做者 | 孙健波(阿里巴巴技术专家)、赵钰莹数据库
导读:云原生时代,Kubernetes 的重要性日益凸显。然而,大多数互联网公司在 Kubernetes 上的探索并不是想象中顺利,Kubernetes 自带的复杂性足以让一批开发者望而却步。本文中,阿里巴巴技术专家孙健波在接受采访时基于阿里巴巴 Kubernetes 应用管理实践过程提供了一些经验与建议,以期对开发者有所帮助。设计模式
在互联网时代,开发者更可能是经过顶层架构设计,好比多集群部署和分布式架构的方式来实现出现资源相关问题时的快速切换,作了不少事情来让弹性变得更加简单,并经过混部计算任务来提升资源利用率,云计算的出现则解决了从 CAPEX 到 OPEX 的转变问题。微信
云计算时代让开发能够聚焦在应用价值自己,相较于之前开发者除了业务模块还要投入大量精力在存储、网络等基础设施,现在这些基础设施都已经像水电煤同样便捷易用。云计算的基础设施具备稳定、高可用、弹性伸缩等一系列能力,除此以外还配套解决了一系列应用开发“最佳实践”的问题,好比监控、审计、日志分析、灰度发布等。原来,一个工程师须要很是全面才能作好一个高可靠的应用,如今只要了解足够多的基础设施产品,这些最佳实践就能够信手拈来了。可是,在面对自然复杂的 Kubernetes 时,不少开发者都无能为力。网络
做为 Jira 和代码库 Bitbucket 背后的公司,Atlassian 的 Kubernetes 团队首席工程师 Nick Young 在采访中表示:架构
虽然当初选择 Kubernetes 的战略是正确的(至少到如今也没有发现其余可能的选择),解决了现阶段遇到的许多问题,但部署过程异常艰辛。框架
那么,有好的解决办法吗?less
“若是让我说 Kubernetes 存在的问题,固然是‘太复杂了’”,孙健波在采访中说道,“不过,这实际上是因为 Kubernetes 自己的定位致使的。”运维
孙健波补充道,Kubernetes 的定位是“platform for platform”。它的直接用户,既不是应用开发者,也不是应用运维,而是“platform builder”,也就是基础设施或者平台级工程师。可是,长期以来,咱们对 Kubernetes 项目不少时候都在错位使用,大量的应用运维人员、甚至应用研发都在直接围绕 Kubernetes 很底层的 API 进行协做,这是致使不少人抱怨 “Kubernetes 实在是太复杂了”的根本缘由之一。分布式
这就比如一名 Java Web 工程师必须直接使用 Linux Kernel 系统调用来部署和管理业务代码,天然会以为 Linux “太反人类了”。因此,目前 Kubernetes 项目实际上欠缺一层更高层次的封装,来使得这个项目可以对上层的软件研发和运维人员更加友好。微服务
若是能够理解上述的定位,那么 Kubernetes 将 API 对象设计成 all-in-one 是合理的,这就比如 Linux Kernel 的 API,也不须要区分使用者是谁。可是,当开发者真正要基于 K8s 管理应用、并对接研发、运维工程师时,就必然要考虑这个问题,也必然要考虑如何作到像另外一层 Linux Kernel API 那样以标准、统一的方式解决这个问题,这也是阿里云和微软联合开放云原生应用模型 Open Application Model (OAM)的缘由。
除了自然的复杂性问题,Kubernetes 对于有状态应用的支持也一直是众多开发者花费大量时间研究和解决的问题,并非不能够支持,只是没有相对较优的解决方案。目前,业内主流的针对有状态应用的解法是 Operator,可是编写 Operator 实际上是很困难的。
在采访中,孙健波表示,这是由于 Operator 本质上是一个“高级版”的 K8s 客户端,可是 K8s API Server 的设计,是“重客户端”的模型,这固然是为了简化 API Server 自己的复杂度,但也致使了不管是 K8s client 库,仍是以此为基础的 Operator,都变的异常复杂和难以理解:它们都夹杂了大量 K8s 自己的实现细节,好比 reflector、cache store、informer 等。这些,并不该该是 Operator 编写者须要关心的,Operator 编写者应该是有状态应用自己的领域专家(好比 TiDB 的工程师),而不该该是 K8s 专家。这是如今 K8s 有状态应用管理最大的痛点,而这可能须要一个新的 Operator 框架来解决这个问题。
另外一方面,复杂应用的支持不止编写 Operator 这么简单,这里还须要有状态应用交付的技术支撑,这是目前社区上各类持续交付项目都有意或者无心间忽略掉的事情。事实上,持续交付一个基于 Operator 的有状态应用,跟交付一个无状态的 K8s Deployment 的技术挑战彻底不是一个量级的。这也是孙健波所在团队在 CNCF 应用交付领域小组(CNCF SIG App Deliver)倡导“应用交付分层模型”的重要缘由:以下图所示,四层模型分别为“应用定义”、“应用交付”、“应用运维与自动化”、“平台层”,只有经过这四个层不一样能力的协力协做,才能真正作到高质量和高效率的交付有状态应用。
举个例子,Kubernetes API 对象的设计是“all-in-one”的, 即:应用管理过程当中的全部参与者,都必须在同一个 API 对象上进行协做。这就致使开发者会看到,像 K8s Deployment 这样的 API 对象描述里, 既有应用开发关注的字段,也能够看到运维关注的字段,还有一些字段可能仍是被多方关注的。
实际上,不管是应用开发、应用运维,仍是 HPA 这样的 K8s 自动化能力,它们都有可能须要控制一个 API 对象里的同一个字段。最典型的状况就是副本数(replica)这种参数。可是,到底谁 own 这个字段,是一个很是棘手的问题。
综上,既然 K8s 的定位是云时代的 Linux Kernel,那么 Kubernetes 就必须在 Operator 支持、API 层以及各种接口定义的完善上不断进行突破,使得更多生态参与者能够更好的基于 K8s 构建本身的能力和价值。
现在,Kubernetes 在阿里经济体的应用场景涵盖了阿里方方面面的业务,包括电商、物流、离在线计算等,这也是目前支撑阿里 61八、双 11 等互联网级大促的主力军之一。阿里集团和蚂蚁金服内部运行了数十个超大规模的 K8s 集群,其中最大的集群约 1 万个机器节点,并且这其实还不是能力上限。每一个集群都会服务上万个应用。在阿里云 Kubernetes 服务(ACK)上,咱们还维护了上万个用户的 K8s 集群,这个规模和其中的技术挑战在全世界也是数一数二的。
孙健波透露,阿里内部早在 2011 年便开始了应用容器化,当时最开始是基于 LXC 技术构建容器,随后开始用自研的容器技术和编排调度系统。整套系统自己没有什么问题,可是做为基础设施技术团队,目标必定是但愿阿里的基础技术栈可以支撑更普遍的上层生态,可以不断演进和升级,所以,整个团队又花了一年多时间逐渐补齐了 K8s 的规模和性能短板。整体来看,升级为 K8s 是一个很是天然的过程,整个实践过程其实也很简单:
如上的三步完成,就具有了对接研发、运维、上层 PaaS 的能力,可以讲清楚本身的平台价值。接下来就能够试点开始,在不影响现有应用管理体系的前提下,一步步换掉下面的基础设施。
Kubernetes 自己并不提供完整的应用管理体系,这个体系是整个云原生的生态基于 K8s 构建出来的,能够用下图表示:
Helm 就是其中最成功的一个例子,它位于整个应用管理体系的最上面,也就是第 1 层,还有 Kustomize 等各类 YAML 管理工具,CNAB 等打包工具,它们都对应在第 1.5 层。而后有 Tekton、Flagger 、Kepton 等应用交付项目,对应在第 2 层。Operator ,以及 K8s 的各类工做负载组件,好比 Deployment、StatefulSet,对应在第 3 层。最后才是 K8s 的核心功能,负责对工做负载的容器进行管理,封装基础设施能力,对各类不一样的工做负载对接底层基础设施提供 API 等。
初期,整个团队最大的挑战来自于规模和性能瓶颈,但这个解法也是最直接的。孙健波表示,随着规模逐渐增大,咱们看到规模化铺开 K8s 最大的挑战其实是如何基于 K8s 进行应用管理和对接上层生态。好比,咱们须要统一的管控来自数十个团队、数百个不一样目的的 Controller;咱们须要以天天近万次的频率交付来自不一样团队的生产级应用,这些应用的发布、扩容策略可能彻底不一样;咱们还须要对接数十个更加复杂的上层平台,混合调度和部署不一样形态的做业以追求最高的资源利用率,这些诉求才是阿里巴巴 Kubernetes 实践要解决的问题,规模和性能只是其中一个组成部分。
除了 Kubernetes 的原生功能外,在阿里巴巴内部会开发大量的基础设施以 K8s 插件的形式对接到这些功能上,随着规模的扩大,用统一的方式发现和管理这些能力成为了一个关键问题。
此外,阿里巴巴内部也有众多存量 PaaS,这些是为了知足用户不一样业务场景上云所构建的,好比有的用户但愿上传一个 Java 的 War 包就能够运行,有的用户但愿上传一个镜像就能够运行。在这些需求背后,阿里各团队帮用户作了许多应用管理的工做,这也是存量 PaaS 出现的缘由,而这些存量 PaaS 与 Kubernetes 对接过程可能会产生各类问题。目前,阿里正在经过 OAM 这个统一标准的应用管理模型,帮助这些 PaaS 向 K8s 底盘进行对接和靠拢,实现标准化和云原生化。
经过解耦,Kubernetes 项目以及对应的云服务商就能够为不一样的角色暴露不一样维度、更符合对应用户诉求的声明式 API。好比,应用开发者只须要在 YAML 文件中声明”应用 A 要使用 5G 可读写空间“,应用运维人员则只须要在对应的 YAML 文件里声明”Pod A 要挂载 5G 的可读写数据卷“。这种”让用户只关心本身所关心的事情“所带来的专一力,是下降 Kubernetes 使用者学习门槛和上手难度的关键所在。
孙健波表示,如今大多数的解法其实是“悲观处理”。好比,阿里内部的 PaaS 平台,为了减轻研发使用的负担,长期以来只开放给研发设置 5 个 Deployment 的字段。这固然是由于 K8s YAML "all-in-one"的设计,使得完整的 YAML 对研发来讲太复杂,但这也致使 K8s 自己的能力,绝大多数状况下对研发来讲是彻底没有体感的。而对 PaaS 平台运维来讲,他反而以为 K8s YAML 太简单,不够描述平台的运维能力,因此要给 YAML 文件添加大量 annotation。
此外,这里的核心问题在于,对运维人员而言,这种“悲观处理”的结果就是他本身太“独裁”,包揽了大量细节工做,还费力不讨好。好比扩容策略,目前就是彻底由运维一方说了算。但是,研发做为编写代码的实际人员,才是对应用怎么扩容最有发言权的,并且研发人员也很是但愿把本身的意见告诉运维,好让 K8s 更加 灵活,真正知足扩容需求。但这个诉求在目前的系统里是没法实现的。
因此,“研发和运维解耦”并非要把二者割裂,而是要给研发提供一个标准、高效的,同运维进行沟通的方式,这也是 OAM 应用管理模型要解决的问题。孙健波表示,OAM 的主要做用之一就是提供一套研发从本身的角度表达诉求的标准和规范,而后这套标准“你知,我知,系统知”,那么上面这些问题也就迎刃而解了。
具体来讲,OAM 是一个专一于描述应用的标准规范。有了这个规范,应用描述就能够完全与基础设施部署和管理应用的细节分开。这种关注点分离(Seperation of Conerns)的设计好处是很是明显的。举个例子,在实际生产环境中,不管是 Ingress、CNI 仍是 Service Mesh,这些表面看起来一致的运维概念,在不一样的 Kubernetes 集群中可谓千差万别。经过将应用定义与集群的运维能力分离,咱们就可让应用开发者更专一应用自己的价值点,而不是”应用部署在哪“这样的运维细节。
此外,关注点分离让平台架构师能够轻松地把平台运维能力封装成可被复用的组件,从而让应用开发者专一于将这些运维组件与代码进行集成,从而快速、轻松地构建可信赖的应用。OAM 的目标是让简单的应用管理变得更加轻松,让复杂的应用交付变得更加可控。孙健波表示,将来,团队将专一于将这套体系逐步向云端 ISV 和软件分发商侧推动,让基于 K8s 的应用管理体系真正成为云时代的主流。
嘉宾介绍:孙健波,阿里巴巴技术专家。Kubernetes 项目社区成员。目前在阿里巴巴参与大规模云原生应用交付与管理相关工做,2015 年参与编写《Docker 容器与容器云》技术书籍。曾任职七牛,参与过期序数据库、流式计算、日志平台等项目相关应用上云过程。
今年 12 月 6-7 日北京 ArchSummit 全球架构师峰会上,孙健波老师会继续分享《阿里巴巴 Kubernetes 应用管理实践中的经验与教训》,会介绍阿里对解耦研发和运维过程当中的现有实践,以及实践自己存在的问题;以及实施的标准化、统一化解决的思路,以及对社区的进一步思考。
“ 阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,作最懂云原生开发者的技术公众号。”
更多详细信息可关注“阿里巴巴云原生”。