关于大数据:QCon演讲实录下多云管理关键能力实现与解析AppManager

1次阅读

共计 5824 个字符,预计需要花费 15 分钟才能阅读完成。

在上篇中,咱们曾经根本理解了多云治理。当初,咱们将深入探讨多云治理要害能力实现:AppManager

什么是 AppManager?

下面咱们讲了实践、咱们本人应用的交付流程和整体架构,上面咱们进入要害能力实现与解析的环节,看看咱们是如何实现上述这些能力的。

回到 AppManager 这个服务自身,它就是一个基于 OAM 的几种拆散的角色,可能实现利用治理及交付的一个服务。

它因大数据侧业务诉求而成长,重视扩大能力、网络隔离环境交付、资源管理和版本治理。

扩大能力

首先来看最重要的扩大能力。不论在一开始的平台设计的时候有如许欠缺,都很难满足后续继续演进的业务需要。所以扩展性是一个 PaaS 平台的重中之重。

依靠于 OAM 的设计,咱们将所有的 Component / Addon / Trait / Policy / Workflow 等均做成了可插拔动静加载的 Groovy 脚本,并在此之上提供了插件治理及市场散发的能力。

图中的所有绿色的中央都是可依据业务须要自行扩大的,所有能力都能够在整个流程中动静引入、插拔和替换。

最下面基础设施研发的同学负责编写反对的组件类型、工作流类型、资源类型的 Groovy 脚本,并注册到 AppManager 外部。

两头的 SRE 同学负责编写 Trait、Policy 的 Groovy 脚本注册到 AppManager 外部,并负责配置环境及部署约束条件等信息。

上面的用户只须要把本人的利用代码写好,而后依照事后定义的 CI、CD、Watch 流程运行即可。

三类角色各司其职,独特高效的实现多云环境下整体利用的治理与交付过程。

图中所有绿色的中央扩大的 Groovy 脚本都是去实现事后定义的 Interface 形象接口的,任何实现了这些 Interface 的 Groovy 脚本,都能够像搭积木一样被组装和替换到各个利用的生命周期中施展本人的能力。包含构建、部署、销毁、状态监测。

在服务外部,咱们为每个脚本定义了本人的 kind (类型) / name (名称) / revision (版本) 三元组,全局惟一。对于雷同的 kind + name 组合,仅加载指定的单个版本的代码版本。通过这样的设计,实现不同用处,不同名称的脚本动静加载,且能够自在切换脚本代码版本。

扩大能力 – 插件包

尽管单个 Groovy 扩大不便且灵便,但不易散发,而开源版本 SREWorks 中社区用户的需要又千差万别,所以在此之上,咱们减少了插件包的机制,插件包通过对一系列 Groovy 脚本的组合,实现对应性能的封装。用户只须要一键下载及装置即可实现对应的能力加载。

对于插件包自身,咱们也定义了一套标准,用于社区用户进行二次开发编写本人须要的插件并上传到插件市场。

构建打包

如果咱们回顾过去这些年来的交付介质演进,能够看到抽象层次是越来越高的。从最开始的 RPM 等零碎层面的软件包,到 Docker 呈现后的镜像,再到前面以镜像为根底,进行各种包装而产生的交付物,如 Helm Chart/Kustomize 等。

那么咱们也不例外,在物理机时代,咱们作为 SRE 去保护各种物理机的软件一致性以及在此之上交付各类服务,甚至还研发了配套的流程平台、作业平台、配置平台等等。在 Docker 遍及之后,这项工作就简略了很多,只须要解决镜像即可,但镜像自身的治理及交付依然是头疼的问题。

好在当初是云原生的时代,咱们有各类 CRD+Operator,有欠缺及牢靠的 Kubernetes 原语,更有事实上的打包交付的规范 Helm/Kustomize 来帮忙咱们更好的实现交付物的封装。接下来咱们就看一下,咱们在整个利用交付的流程中,如何解决好构建打包、制品治理及内部 CI 对接的。

通过图上咱们能够看到,首先用户自定义的构建配置被提交,之后会被 AppManager 解析为利用包工作以及一个个的组件包工作,每个组件包工作会依据本人的组件类型抉择对应的构建逻辑进行构建,这里能够有不同的数据源,也能够通过不同的形式产出镜像,不论是 Docker Daemon 还是 Kaniko 的形式都反对,也会推送到指定的镜像仓库中。最终实现后生成一个个组件包,以及拼装为一个利用包,赋予版本及标签后,最初上传到 OSS 或 MinIO 上进行制品存储。一个常见的用户场景是,通过标签申明以后制品的用处,在理论应用的时候通过标签进行过滤,并进而抉择本人须要的版本号以确认惟一的制品。

当存在内部 CI 零碎须要对接的时候,只须要将内部 CI 零碎产出的镜像及其他 commit 信息通过 Trigger API 触发即可,前面的流程和上述人工被动触发统一。

利用部署

当获取到制品之后,就来到了整个零碎中最外围也是最简单的局部:利用部署。此处临时先疏忽多环境下的制品下发及相干细节,前面会独自讲到。当初先假如咱们曾经将制品传输到了指定环境中,并且镜像也曾经在对应环境中可用,只是单纯的执行一次部署流程,会有哪些事件产生。

首先看一下整个 Application 的 Yaml,它残缺定义了一个利用部署的模型,形容了一个利用应如何牢靠而又灵便的交付到指标环境中。如后面所说,Component/Addon/Trait 为面向终态设计,Policy/Workflow 为面向过程设计。

之后来看一下整体的部署层级关系,从大到小别离是 Workflow 部署、Application 部署、Component 部署 (含 Trait 部署)。当然并不局限于这三层,Workflow 是能够按业务需要进行各种嵌套的,前面会独自讲到。接下来咱们用相同的程序来介绍实现细节,自底向上,逐渐拼出来咱们最初的实现计划。

利用部署 – Trait

Trait 咱们会归类为三种性能:

  • 依据配置批改绑定的 Component Workload Yaml。
  • 新增 / 批改资源 / 做你想做的事,并在实现后产出数据给本身对应的组件或后续其余组件应用。
  • 继续监听指标集群中以后组件的事件(不只是部署过程中),并实时依据事件做出反馈(Groovy 实现),罕用于依据组件的以后状态做出一些内部反馈,比方 Pod 漂移 IP 变动后须要从新做一些信息注册或保护类的工作。

所有的 Trait 也都是 Groovy 脚本实现,并封装为插件包注册到零碎中。每个 Trait Groovy 的 class 阐明如上图,其中会包含两个 interface:

  • 一个是 execute,所有类型的 Trait 在部署过程中均会执行该办法,并产出数据供上游应用,当然产出数据是可选的
  • 另外一个是 reconcile,只有第三类须要继续监听指标集群事件的 Trait 才会应用,实质上是指标集群运行着咱们开发的一个 Trait Operator,在 execute 执行的时候下发一个监听 CR 到该集群,Trait Operator 检测到该 CR 后会启动一个新的 Controller 来监听指定组件事件,并在事件到来后间接调用 AppManager 的 Trait Reconcile API,该 API 会间接同步调用对应 Trait Groovy 脚本中的 reconcile 办法,实现业务自定义的事件触发动作。这里其实等价于咱们把常见的 K8S Operator 的 Reconcile 链路缩短到了 AppManager 本身,并通过 Groovy 来实现业务逻辑,简化了惯例 Operator 的开发流程,并且中心化也更好保护一些,尤其是面对茫茫多的指标集群的时候。

利用部署 – 组件

对于组件而言,咱们定义了几个固定类型,别离是构建、部署和状态感知。其中构建后面介绍过了,状态感知是可选的,会在最初进行介绍。这里次要介绍下部署逻辑。

组件部署的时候,一样会执行对应的 Groovy 脚本,并且零碎会在进入脚本执行前主动将选定的制品解压到本地目录供脚本应用,以执行业务自定义的部署逻辑。目前咱们曾经依据各个业务状况编写了 6 类外部应用的组件,这些因为和阿里云业务相干无奈开源。在开源场景下,咱们默认提供了微服务、Job、Helm 几种类型,并凋谢了扩大机制,供有须要的用户自行编写新的组件类型来管制本人的组件如何部署。这里的组件类型是形象的,也能够齐全和 K8S 无关,比方是本人公司外部零碎的某些特定配置导入导出。

由下面的图能够看到,在部署过程中,Groovy 脚本中的 launch 办法会首先被调用,并实现对应的部署流程,这里可通过 fabric8 进行 K8S 近程调用 apply 上来对应的 Yaml,当实现后立刻返回即可。之后,AppManager 服务会不停轮询以后 Groovy 脚本中的 get 办法,冀望查问到胜利的返回值,否则就会始终等上来,直到超时或失败。

这里在查看业务组件终态的时候其实还能够和组件本身的状态感知的能力产生互动,比方始终没有终态,然而没有终态的起因是什么呢?是能够通过前面说的状态感知来剖析失败起因并返回给用户的。前面咱们再细讲。

利用部署 – 利用 & 组件 & Trait 间依赖关系

说完了组件和 Trait 的部署,咱们回升到利用层面,来看下在利用的视角下,本身的组件、Trait 在整个部署流程中的数据关系。

因为理论的业务场景中,每个组件和 Trait 都有可能产生数据输入,并且会被别的组件和 Trait 援用到,在这种依赖关系下,产出数据的组件不跑完,援用数据的组件是不能跑的。但如果两个组件间没有任何依赖关系,那么他们是须要并行跑来提速的。

所以依照 OAM spec 的形容,咱们在 Application Yaml 中为每个组件和 Trait 都提供了 dataInputs 和 dataOutputs 能力,如图上的 Yaml 所示。

在 AppManager 零碎收到下面的 Yaml 后,在整个利用部署的过程中就须要对针对所有的组件和 Trait 之间的关系建图连边了。

在构图的时候,Component 和 Trait 是厚此薄彼的,这种对等关系会升高复杂度,同时保障数据流依赖关系在两种类型上保持一致。

对于每个 Component,会独自再结构一个镜像节点,用于确保前置组件的后置 Trait 节点的运行在以后组件之前。这样整体构图之后,只须要依照这个 DAG 无脑执行即可满足束缚程序。

利用部署 -Workflow

在晚期的业务撑持中,其实是没有 Workflow & Policy 这一层的,然而下面讲到的利用部署只是针对单指标的,如果是批量指标环境的部署,就须要在更高的纬度发动多个利用部署单子来解决。

OAM 针对这一状况也在 0.3.1 的草案中提出了解决方案,也就是 Workflow & Policy。这里简要阐明一下:

  • 一个 Workflow 蕴含多个步骤,执行程序能够依次,也能够并发,如果并发的话就是依照下面说的 dataInputs/dataOutputs 的 DAG 结构形式。
  • 每个 Workflow Step 也都是 Groovy 脚本来实现,所以每个步骤执行什么,怎么执行全副交给平台方来定义。
  • 每个 Workflow Step 的 Groovy 脚本中,能够调用 Policy 对全局 Application 进行自定义批改,并且将批改后的 Application 提交利用部署单,也就是后面说的逻辑,这样就能够实现不同指标环境有不同的覆写配置。
  • Workflow 在执行的过程中能够有更多的管制及人工染指,如暂停、复原、设置上下文等等,在灰度公布场景、波及回滚动作的时候尤其有用。
  • Workflow Step 能够持续产出一个 Workflow,实现简单场景实现套娃成果。

资源管理(Addon)

秉承着所有可扩大的货色都通过 Groovy 脚本来插拔,资源 Addon 也不例外,其实也能够把它看做是 Component 组件。

对于 Addon,会有和 Component 不同的语义。资源须要申请和开释,也就是 apply 和 release,所以这两个办法是 Addon 层面的 interface。同时 Addon 也会存在本人的规格 Schema 定义,前端会在资源申请的时候辨认这个定义,让用户在页面抉择须要申请的资源规格(比方 8c16g 的数据库)。

在咱们的实际过程中,间接写了一个对接 Terraform 的 Groovy 脚本就实现了大部分的外部业务诉求。对于所有的 tfstate 文件也会透出以 Addon Schema 的模式存储到数据库中供后续其余组件应用或共享。

留神资源的个性是利用下依据 Namespace 隔离的,但 Namespace 下的同名资源会进行共享。一个典型的场景是生产的 Namespace 下申请的数据库会共享到预发和生产两个环境的服务中。这里在下一页的多环境反对中进行介绍。

如果你对于其余第三方的各类异构资源有需要,比方有的资源须要通过特定的 API 申请的,齐全能够再扩大一个插件注册进去即可实现。

多环境反对

咱们在 AppManager 中定义了四种环境层级,如上图。从上到下别离是:

  • Unit(单元):单元间网络隔离。每个单元须要一个 AppManager 实例进行管控。一个单元可包含多个 Cluster。
  • Cluster(集群): 一个独立 K8S 集群,集群间网络可达。集群间接注册 kubeconfig 到以后单元下的 AppManager 即可应用。
  • Namespace(命名空间): 对应 K8S 的 Namespace 概念,用于一个 Cluster 下的资源及利用的隔离,一个 Namespace 对应了一个信息孤岛。
  • Stage(阶段 / 环境): 一个 Namespace 可蕴含多个 Stage,每个 Stage 共享了以后 Namespace 下的所有资源。

利用状态感知

一个利用被交付到指标环境之后,运行的状态怎么样?这块其实有很多种内部开源计划或监控伎俩能够来搞的,不开展。这里只介绍下 AppManager 内置的一个简略的状态感知计划。

由上图能够看到,一个利用被部署到了一个指标环境中,就变成了一个利用实例 Application Instance。一个组件被部署后也一样会变成组件实例 Component Instance。利用实例的状态是由组件实例的状态汇聚而来的,那么组件实例的状态须要怎么来呢?

首先来看 Watch 的计划,时效性高,但撑持的集群数量只有几百个,小规模下应用。实质上是在组件注册的时候通过 Informer 机制 List/Watch 集群事件,而后将 Event Handler 的实现交由组件开发者本人自行判断,并依据内容返回业务自定义的状态后果。

接下来是 Pull 计划,能够撑持最高 10 万量级的利用及集群,但时效性在利用状态失常时会逐渐升高到 5min。只有在产生异样时会疾速晋升检测频率,直到再次恢复正常。当然具体的状态断定的脚本也是交给组件开发者来写的,能够依据业务须要自行扩大,灵活性十分高。

以上为本次分享全部内容,谢谢大家的凝听。

正文完
 0