在这个领域,Kubernetes 用 Helm 的来管理和打包应用,可是 Helm 并非十全十美的,在使用过程当中咱们发现它并不能彻底知足咱们的需求,因此在 Helm 的基础上,咱们本身研发了一套编排组件……node
什么是编排?git
不知道你们有没仔细思考过编排究竟是什么意思? 我查阅了 Wiki 百科,了解到咱们常说的编排的英文单词为 “Orchestration”,它常被解释为:github
有趣的是 “Orchestration” 的标准翻译应该为“编配”,而“编排”则是另一个单词 “Choreography”,为了方便你们理解, 符合平时的习惯,咱们仍是使用编排 (Orchestration) 来描述下面的问题。至于“编配 (Orchestration)” 和 “编排(Choreography)” 之争,这里有一篇文章,有兴趣能够看一下 。数据库
编配和编排的定义之争当咱们在说容器编排的时候,咱们在说什么?设计模式
在传统的单体式架构的应用中,咱们开发、测试、交付、部署等都是针对单个组件,咱们不多听到编排这个概念。而在云的时代,微服务和容器大行其道,除了为咱们显示出了它们在敏捷性,可移植性等方面的巨大优点之外,也为咱们的交付和运维带来了新的挑战:咱们将单体式的架构拆分红愈来愈多细小的服务,运行在各自的容器中,那么该如何解决它们之间的依赖管理,服务发现,资源管理,高可用等问题呢?安全
在容器环境中,编排一般涉及到三个方面:网络
在 Kubernetes 中有 5 种咱们常常会用到的控制器来帮助咱们进行容器编排,它们分别是 Deployment, StatefulSet, DaemonSet, CronJob, Job。架构
在这 5 种常见资源中,Deployment 常常被做为无状态实例控制器使用; StatefulSet 是一个有状态实例控制器; DaemonSet 能够指定在选定的 Node 上跑,每一个 Node 上会跑一个副本,它有一个特色是它的 Pod 的调度不通过调度器,在 Pod 建立的时候就直接绑定 NodeName;最后一个是定时任务,它是一个上级控制器,和 Deployment 有些相似,当一个定时任务触发的时候,它会去建立一个 Job ,具体的任务其实是由 Job 来负责执行的。他们之间的关系以下图:运维
一个简单的例子微服务
咱们来考虑这么一个简单的例子,一个须要使用到数据库的 API 服务在 Kubernetes 中应该如何表示:
客户端程序经过 Ingress 来访问到内部的 API Service, API Service 将流量导流到 API Server Deployment 管理的其中一个 Pod 中,这个 Server 还须要访问数据库服务,它经过 DB Service 来访问 DataBase StatefulSet 的有状态副本。由定时任务 CronJob 来按期备份数据库,经过 DaemonSet 的 Logging 来采集日志,Monitoring 来负责收集监控指标。
Kubernetes 为咱们带来了什么?
经过上面的例子,咱们发现 Kubernetes 已经为咱们对大量经常使用的基础资源进行了抽象和封装,咱们能够很是灵活地组合、使用这些资源来解决问题,同时它还提供了一系列自动化运维的机制:如 HPA, VPA, Rollback, Rolling Update 等帮助咱们进行弹性伸缩和滚动更新,并且上述全部的功能均可以用 YAML 声明式进行部署。
困境
可是这些抽象仍是在容器层面的,对于一个大型的应用而言,须要组合大量的 Kubernetes 原生资源,须要很是多的 Services, Deployments, StatefulSets 等,这里面用起来就会比较繁琐,并且其中服务之间的依赖关系须要用户本身解决,缺少统一的依赖管理机制。
什么是应用?
一个对外提供服务的应用,首先它须要一个可以与外部通信的网络,其次还须要能运行这个服务的载体 (Pods),若是这个应用须要存储数据,这还须要配套的存储,因此咱们能够认为:
应用单元 = 网络 + 服务载体 +存储
那么咱们很容易地能够将 Kubernetes 的资源联系起来,而后将他们划分为 4 种类型的应用:
咱们来从新审视一下以前的例子:
应用层面的四个问题
经过前面的探索,咱们能够引出应用层面的四个问题:
在社区中,这四个方面的问题分别由三个组件或者项目来解决:
Helm Charts
Charts 在本质上是一个 tar 包,包含了一些 yaml 的 template 以及解析 template 须要的 values, 以下图:templates 是 Golang 的 template 模板,values.yaml 里面包含了这个 Charts 须要的值。
Helm Registry
用来负责存储和管理用户的 Charts, 并提供简单的版本管理,与容器领域的镜像仓库相似这个项目是开源的。( https://github.com/caicloud/helm-registry)
Tiller
Tiller 的缺陷
Release Controller
为了解决上述的问题,咱们基于 Kubernetes 的 Custom Resource Definition 设计并实现了咱们本身的运行时管理系统 – Release Controller, 为此咱们设计了两个新的 CRD – Release 和 Release History。
Release 建立
当 Release CRD 被建立出来,controller 为它建立一个新的 Release History, 而后将 Release 中的 Chart 和 Configuration 解析成 Kubernetes 的资源,而后将这些资源在集群中建立出来,同时会监听这些资源的变化,将它们的状态反映在 Release CRD 的 status 中。
Release 更新
当用户更新 Release 的时候,controller 计算出更新后的资源与集群中现有资源的 diff, 而后删除一部分,更新一部分,建立一部分,来使得集群中的资源与 Release 描述的一致,同时为旧的 Release 建立一份 Release History。
Release 回滚和删除
用户但愿回滚到某一个版本的 Release, controller 从 Release History 中找到对应的版本,而后将 Release 的 Spec 覆盖,同时去更新集群中对应的资源。当 Release 被删除后,controller 将它关联的 Release History 删除,同时将集群中的其余资源一并删除。
架构图
这样的设计有什么好处?
总而言之,编排不只仅是一门技术也是一门艺术!谢谢!