K8S上的分布式系统应用编排

2,780 阅读7分钟

前言

随着容器技术的发展,容器的优势:易打包、可复制、隔离性、低开销,使得不断的有应用开始从传统的物理机、虚拟机,逐渐的搬迁到容器上。而 Kubernetes 的诞生和发展壮大,又降低了应用的标准化部署管理的难度,大大加速了应用搬迁到容器的进程。将一个存在前台、后台、数据库的分布式系统一键式部署到 K8S 上时,可以有哪些方法和途径呢?

K8S上的应用模型

Kubernetes 对容器应用的编排,是将应用的运行时、配置、服务提供、存储、镜像等都定义成了多种资源对象,每种资源对象都可以按照一定的格式进行描述定义。比如环境变量可以定义到 configmap 对象,也可以定义在容器的配置中;而应用的运行时,则是多种工作负载:Deployment、StatefulSet、DaemonSet 等。

资源类型 功能
Deployment 定义应用的容器镜像、资源要求、运行时环境等工作负载相关,无状态记录,可任意扩缩容
StatefulSet 定义应用的容器镜像、资源要求、运行时环境等工作负载相关,存在状态信息记录,按序启动与伸缩
DaemonSet 定义应用的容器镜像、资源要求、运行时环境等工作负载相关,一般是代理类应用,会在每个节点上运行实例
Job 定义应用的容器镜像、资源要求、运行时环境等工作负载相关,短时任务类,执行完成即退出
ConfigMap 定义配置,可用于挂载到容器的环境变量或者文件中
Secret 定义敏感配置信息,可用于挂载到容器的环境变量或者文件中
Service 定义应用的访问入口
Ingress 定义应用的http访问入口
... ...

一个应用就会至少有一个工作负载,以及一些配置,访问入口等资源对象。通过控制这些资源对象,就可以完成一个应用,或者多个应用的统筹管理,这就是k8s上的应用编排。最原始的方式当然是直接操控每一个的资源对象,但是,多个分散的文件,又没有变量替换功能,就意味着这些文件只能在一套环境上执行,一旦环境有变化,还需要手动修改文件的内容;这些对象之间还必须以一定的先后顺序执行,否则会失败。当应用更多时,执行的流程就会更加的复杂。

分布式系统的编排要求

下面是一个典型的分布式系统,包括前端程序、后台程序、后台数据库,负载均衡器等。在应用系统发展到一定程度,自然而然的就会对系统的各部件角色进行拆分,对于每种角色,都可以进行一定的水平或者垂直的扩展,保证应用的扩展性,解除系统的单点问题。

这样的一个系统,对应用编排有这些要求:

  1. 系统中可以定义多种应用

  2. 每个应用的多个资源对象之间,可以定义控制依赖关系

  3. 不同应用之间存在配置上的传递

  4. 不同应用之间存在启动顺序上的先后依赖关系

Helm:社区原生的包管理工具

由于 K8S 的资源对象都具备着一定的格式化规范,社区提供了 Helm 用于处理 k8s 应用的打包,这个包叫做一个 chart。Chart 的包格式如下:一个Chart.yaml文件,用户定义包的名称、版本等信息,一个templates目录,里面定义了这个应用所有相关的资源描述的 go-template 语法的模板,而模板使用到的变量,则在values.yaml文件中进行声明定义。

Helm 的实现原理很简单,在客户端实现变量的渲染替换,再将完整的内容传递到服务端(tiller),由 tiller 将生成的 k8s 对象按照一定的顺序调用 k8s 接口,完成应用的编排创建。

helm 还支持了 dependency 的依赖关系,用于 chart 包之间的引用。而应用之间的参数传递,也可以通过共享相同的变量输入来完成。这样,分布式系统要求的1,2,3,4看起来也都满足了。

但是,在helm的实际应用中,存在着下面的几个问题。

  • 应用中的任务下发,只控制了请求的发送顺序,并不能保证创建完成的先后顺序。这就导致了有时候 secret 之类的对象尚未处理完成,deployment 就去引用而失败的情况。

  • 对于 Deployment 之类的工作负载,helm 没有去真正的判断实例是否启动就绪完成了,即使应用实例因为某些原因失败了,helm也感知不到。

  • Helm 的 dependency 依赖,只控制了 chart 包的引用,实际上的多个应用一起创建时,还是全部展开按照类型顺序统一执行的。

  • Chart 包的模板编写,一方面需要用户对k8s的资源对象结构有一定的理解基础,另一方面go-template的引入使得模板变成了非格式化的结构,无法正常的进行校验处理,导致容易出错。

对于 Helm 在处理分布式系统中遇到的问题,并非难解。核心在于一套完善的DAG框架,能够精确控制所有的步骤流程,以及每个步骤的结果管理和传递。 而这套框架最好是格式化的简单的结构,不需要那么复杂,要精通 K8S、go-templat e等等,最好有图形化的界面,可以辅助编写。

应用编排服务:解决依赖和配置传递

华为云上的应用编排服务(以下简称 AOS),就是这样一个能够满足复杂分布式应用在 K8S 上的各种要求的系统。AOS 服务对接了华为云的云容器引擎(CCE服务),提供了一套规范化的模型结构,可定义 K8S 上的各种资源对象。通过模型设计的模板,可以实现复杂分布式系统的一键式编排创建在 K8S 集群上。

  • 优秀的图形化设计器,通过图形化拖拽即可设计应用结构,将应用所需的各种资源,精确控制所有对象的执行顺序关系,实现最大化的并行。

  • 通过编排语法可以将应用之间的共享参数、应用的输出访问地址等信息进行传递输出。

  • 良好的变量输入输出机制,将应用在不同环境中的部署所需配置提炼,实现一套模板,多处复用。

前面的分布式系统,在 AOS 编排设计后,就可以成为下面的这个图。这样的一个分布式系统,将依次创建 DB 数据库,执行创建数据库表结构的job,而数据库的访问信息将记录到secret中,由两个后端程序app1-back2,app-backend1 挂载使用。两个后端程序还同时引用了共同的配置 appconfig。前台应用通过 ingress 和 service 去访问后端程序,并提供了 ingress 用于外部访问。这个图中没有体现负载均衡器,因为这里的 ingress 配置了连接华为云的 ELB 服务。

应用编排系统还支持编排管理云上的各种服务,比如 RDS 数据库,ELB 负载均衡器等,利用这些服务,将简化分布式系统的云上架构,帮助用户聚焦在自身的业务,不再需要花大力气在业务的交付和部署运维上。