作者 | 孙健波(天元)
导读:当前云原生 DevOps 体系现状如何?面临哪些挑战?如何通过 OAM 解决云原生 DevOps 场景下的诸多问题?云原生开发应用模型 OAM(Open Application Model) 社区核心成员孙健波将为大家一一解答,并分享如何基于 OAM 和 Kubernetes 打造无限能力的下一代 DevOps 平台。
什么是 DevOps?为什么基于 Kubernetes 构建?
2009 年举办了第一届 DevOpsDays 大会,DevOps 名字被首次提出。到 2010 年,DevOps 的概念越来越火,出了 What is DevOps 的文章,讲解了 DevOps 的概念,方法论及配套的工具。简单来说,研发工程师需要和运维工程师深度的合作,同时通过一系列工具保证研发更加顺畅,从而更容易的接触生产环境。
到 2013 年,Docker 出现了,工程师可以第一次到软件生产环境中定义,通过 Docker image 完成单机软件的交付和分发。此时 DevOps 开始慢慢落地。2015 年开始,DevOps 相关的工具越来越多,资源利用率出现了一些问题,CNCF 的成立使得 DevOps 的实践往 Kubernetes 上走。
(DevOps 的三个阶段)
阿里在 Kubernetes 上的实践也取得了非常好的成果。在规模方面,阿里内部集成了数十个节点可以达到上万的集群,同时具备高性能和安全特性,秒级扩容,神龙+安全容器。具备极致的弹性,分钟级拆解公有云计算资源,无限资源池。另一方面,Kubernetes 社区已经具备非常丰富的 DevOps 生态基础功能,包括镜像托管、CI\CD 流水线、任务编排、发布策略、镜像打包、分发、丰富的应用运行时的负载支撑、丰富弹性和应用扩容能力。
为什么阿里基于 Kubernetes 构建 DevOps平台?
1)阿里基于 Kubernetes 的无限资源池与基础设施能力
- 大规模 – 单集群最高可达 10000 节点、百万 Pod
- 高性能 – 秒级扩容,智能伸缩,神龙 + 安全容器
- 极致弹性 – 分钟级拆解公有云计算资源,无限资源池
2)社区围绕 Kubernetes 已经具备丰富的 DevOps 生态基础功能
- 源码到容器镜像仓库,Kubernetes 是容器平台事实标准:Github / DockerHub;
- CI/CD 流水线、任务编排、发布策略:Argo / Teckton / Spinnaker / Jenkins-X / Flagger;
- 镜像打包、分发:Helm / CNAB;
- 丰富的应用运行负载支撑:Deployment(无状态) / StatefulSet(有状态) / OpenKruise(原生有状态增强);
- 丰富的弹性和应用扩缩容能力:HPA / KEDA。
基于 Kubernetes 的 DevOps 平台新挑战
下图展示了一个云原生下的 DevOps 流水线的典型流程。首先是代码的开发,代码托管到 Github,再接入单元测试的工具 Jenkins,此时基本研发已完成。再接着到镜像的构建,涉及到配置、编排等。云原生中可以用 HELM 打包应用。打包好的应用部署到各个环境中。但整个过程中会面临很多挑战。首先,在不同的环境需要不同的运维能力。
(一个云原生 DevOps 流水线的典型流程)
其次,配置的过程中要创建云上数据库,需要另外打开一个控制台来创建数据库。还需要配置负载均衡。在应用启动以后还需要配置额外的功能,包括日志、策略、安全防护等等。可以发现,云资源和 DevOps 平台体验是割裂的,里面充斥着借助外部平台创建的过程。这对新手来说是非常痛苦的。
挑战一:云资源与 DevOps 平台体验割裂
DevOps 流程中充斥着大量需要外部平台创建的过程:
挑战二:研发、运维、基础设施关注点耦合
下图是常用的 K8s 的 YAML 配置文件,大家经常吐槽这个配置文件很复杂。
简单来说 YAML 配置文件可以分为三大块,一块是运维比较关心的配置,包括实例数,策略和发布。第二块是研发关心的,涉及到镜像、端口号等。第三块是基础设施工程师看得懂的,如调度策略等。K8s 的配置文件中将方方面面的信息都耦合在一起,这对 K8s 工程师来说是非常适合的,但是对应用侧的终端工程师而言,有很多不需要关心的配置指标。
- DevOps 流程中缺乏对“应用”这个概念的描述
- K8s 的 YAML 文件的定位并不是终端用户
挑战三:平台的自定义封装,简单却能力不足
DevOps 平台对 K8s 能力封装抽象,只剩下 5 个 Deployment 的字段需要研发填写。从用户角度而言,这种设置非常好用简单。但是针对稍微复杂的应用,涉及到应用状态管理,健康检查等等一系列的操作,此时这 5 个字段是不够的。
挑战四:CRD 扩展能力强大,DevOps 平台无法直接复用
CRD(Customize Resource Definition) 扩展能力强大,几乎所有软件都可以通过 CRD 的方式进行扩展,包括数据库、存储、安全、编排、依赖管理、发布等。但是对 DevOps 平台来说,上面接口并没有向用户暴露,导致无法直接复用。
挑战五:DevOps 平台开发的新能力使用门槛高
如果平台想要扩展一些能力,而原生的自动扩缩容能力不太合适,希望开发定时的扩缩容YAML文件,随着业务情况而设置。但此时用户使用YAML的门槛非常高,不清楚如何使用YAML。随着新能力开发越来越多,能力之间会出现冲突,这也非常难以管理。
- 运维同学怎么知道这个扩展能力怎么用?看 CRD?看配置文件?看 …… 文档?
- 扩展能力间出现冲突,导致线上故障,比如:CronHPA 和 默认 HPA 被同时安装给了同一个应用;K8s 扩展能力之间的冲突关系,如何有效管理?如何有效的对运维透出?
挑战六:不同 DevOps 平台需要完全重新对接
很多云原生实践中会遇到的问题,即需要定义非常复杂的 YAML,这种方式可以解决企业内部所有问题,但是挑战在于很难与生态进行对接。如 RDS,SLB 的能力都嵌到 YAML 文件中,无法复用,几乎不具备原子化能力。同时无法协作,无法提供给兄弟部门或生态使用,只能给内部封闭生态使用。上层系统不同应用对接 DevOps 平台时,需要写不同格式的 YAML,这也是非常痛苦的。
- 难以理解,必须通过界面可视化透出
- 无法复用,几乎不具备原子化能力
- 无法协作,只能内部封闭生态使用
OAM 应用模型的技术原理
OAM 应用模型的出现,解决了上述应用管理的难题,下面我们来介绍一下 OAM 模型的技术原理。
1. Component 组件
OAM 中常见的概念是 Component 组件,完全从研发角度定义的待部署单元。下图右侧是 YAML 中 Component 的例子,其中黄色部分可以灵活自定义。OAM 中会定义标准的架构 ContaineriseWorkload,表示工作负载部分,里面是待部署单元的具体描述。这时就可以解决关注点分离的问题,帮助应用侧工程师去掉很多细节,只需要关心开发需要关注的端口号,镜像等等。
应对挑战一,在 OAM 中可以定义数据库表达资源需要使用云资源,Workload 中可以根据自己的需要定义不同的组件,包括基于虚拟机的应用、或者老的 Function 应用。组件是应用开发者关心的。
2. Trait
如果只是组件,组合起来就可以构建简单的应用。如果关心应用运维的问题,OAM 中有 Trait 的概念,指的是在原来组件的基础上附加一些特征。特征指的是运维的能力,如手动扩缩容能力、外部访问能力、发布、负载均衡。弹性扩缩容、基于流量的管理等等。通过 OAM 的 Trait 可以很灵活的得到插件化扩充能力。不同的 component 绑定不同的特征。
3. Scope
Component,Trait 以及所有组装起来的 Application Configuration 就是 OAM 中的三种主要的概念。但当多个组件共同协作时应该如何处理?OAM 中有个边界 Scope 的概念,是一种特殊的 Trait,将多个 Component 组合在一起,共享一组资源组,CPU 等特征用 Scope 表示,拓展多个组件的共同特征。
OAM 加持下的下一代 DevOps 技术
1. OAM:以应用为中心的分层模型
OAM 是以应用为中心的分层模型,首先需要运行在服务端的 OAM 解释器,对于 YAML 的读取需要通过 OAM 解释器。OAM 提供 Trait,Component 让用户填写,编成 APP Config。APP Config 通过 OAM 解释器具备 Deployment,Ingress,HPA 或者云资源等能力。这种方法可以将研发、运维基于基础设施进行分层,研发关心 Component,运维关心 Trait,基础设施通过 OAM 解释器提供各种能力,与 K8s 紧密结合,对其应用概念做了补充。
- 分层
- 模块化
- 可复用
2. 快速的纳入 K8s 生态已有 Operater 能力
OAM 可以快速的纳入 K8s 生态已有的 Operater 能力,下图左边的 Component 中是一个 CRD 的实例,右边是 Trait 中的 CRD 的实例,中间表示 Component 底下的 Workload 和 Trait 分别对应了 K8s 自定义资源的能力。如果想要使用 K8s 中的某些能力,只需要在 Trait 中写入相应的字段即可。
3. OAM 框架解决组件依赖关系和启动顺序
OAM 框架解决组件依赖关系和启动顺序。OAM Runtime,OAM 解释器会将组件依赖关系和启动顺序处理好,下图中 Component 之间有 dependency 关系,Trait 与 Component 之间有 preComponent 或者 postComponent 等关系。
4. OAM Trait 灵活解决资源绑定难题
启动顺序厘清之后涉及到资源绑定问题,一边是使用的数据库,另一边是 Web 的程序,Web 的程序绑定数据库连接串资源。在 OAM 中只需要写一个 Trait 就可以解决资源绑定问题,下图右边,K8s 通过 Secret 承载连接串信息,Service Binding Trait 对应一个运行的 Operator,Web Hook 拿到 Secret 后注入进数据库中。
5. Workload 与 Trait 交互机制
大家会考虑接入 OAM 会不会比较麻烦,需不需要改代码。OAM 设计了 Workload 与 Trait 交互机制,OAM 内部零改造,只需要扩展 Workload 和 Trait。首先,Component 中创建 Workload 实例,再创建 Trait 实例,只需要在 Trait 中查看 Workload 的 Definition,从而配置 Trait 中需要的能力。
(OAM 内核零改造,插件式快速接入新能力)
如果开发了新的能力,碰到冲突问题也是非常头痛的。在 OAM 框架中定义 Trait 时,可以检查哪些字段是冲突的,拒绝掉新的应用的创建,从而保障 Trait 之间的兼容性,使得运维问题可发现、可管理。
(可发现、可管理的 Traits 系统)
6. OAM:无限能力的 DevOps 平台体系
下图是 DevOps 平台体系,最下层是 OAM Runtime,一部分是 Workload,对应运行时的承载的 Runtime,如 Function、Container、虚拟机、Serverless Service 等。另一部分是 Trait,对应运维能力,如发布、弹性扩缩容、日志、安全等等。再上一层可以根据场景化组合(Application Profile)组装成不同的业务形态平台,不同平台可以使用不同组合的 Workload 和 Trait,具备不同的能力。通过 OAM 标准化的模型构建无限能力的 DevOps 平台,满足各种场景的需要。
在用户侧,OAM 加持下的研发 DevOps 流程在镜像构建完成之后使用达到统一,OAM 提供了 APP Config,包含不同的 Component,每个 Component 包含不同的运维能力 Trait,支持不同的环境,如测试环境、生成环境。OAM 配置统一,适合不同的云,可以拿到不同的集群中直接运行。在 K8s 侧,用户只需要装上插件,就可以很方便的嵌入很多丰富的能力。
如果有其他问题,建议大家加入我们的钉钉群进行讨论。(钉钉搜索群号:23310022,即可进群)
课程推荐
去年,CNCF 与 阿里云联合发布了《云原生技术公开课》已经成为了 Kubernetes 开发者的一门“必修课”。今天,阿里云再次集结多位具有丰富云原生实践经验的技术专家,正式推出《云原生技术实践公开课》。课程内容由浅入深,专注讲解“ 落地实践”。还为学习者打造了真实、可操作的实验场景,方便验证学习成果,也为之后的实践应用打下坚实基础。
点击链接即可免费观看:https://developer.aliyun.com/learning/roadmap/cloudnative2020
“阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的公众号。”