简介:本文将介绍如何在 Kubernetes 上构建新的应用管理平台,提供一层抽象以封装底层逻辑,只呈现用户关心的接口,使用户可以只关注自己的业务逻辑,管理应用更快更安全。
作者:司徒放
导语:云原生时代,直接使用 Kubernetes 和云基础设施过于复杂,如用户需要学习很多底层细节、应用管理的上手成本高、容易出错、故障频频。随着云计算的普及,不同云又有不同的细节,进一步加剧了上述问题。
本文将介绍如何在 Kubernetes 上构建新的应用管理平台,提供一层抽象以封装底层逻辑,只呈现用户关心的接口,使用户可以只关注自己的业务逻辑,管理应用更快更安全。
云原生时代是一个非常好的时代,我们所面临的是整体技术的颠覆性革新,全面地对应用做端到端重构。目前,云原生在演进过程中产生了三个关键技术:
- 一是容器化,容器作为标准化交互的介质,在运维效率、部署密度和资源隔离性方面相比传统方式有很大改进,据 CNCF 最新调研报告显示,目前已有 92% 的企业生产系统在使用容器;
- 二是 Kubernetes,它对基础设施进行了抽象和管理,现已成为云原生的标配;
- 三是 Operator 自动化运维,通过控制器和定制资源的机制,使 Kubernetes 不仅可以运维无状态应用,还可以执行由用户定义的运维能力,实现更复杂的自动化运维应用进行自动化部署和交互。
这三项关键技术其实是逐渐演进的关系,另外,在应用交付领域,也有与之对应的理论在跟随上述技术不断地演进。云原生的崛起,带来了交付介质、基础设施管理、运维模型和持续交付理论的全面升级和突破,加速了云计算时代的到来。
从 CNCF 发布的云原生技术全景图(见图 1)中,可以看到云原生的蓬勃生态,细数图中这 900 + Logo,其中不乏开源项目、创业公司,未来云原生的技术都会在这些地方诞生。
云原生 “操作系统” Kubernetes带来的应用交付挑战
上文提到,Kubernetes 已成为云原生的标配,其对下封装基础设施的差异,对上支持各种应用的运维部署,如无状态应用、微服务,再如有状态、批处理、大数据、AI、区块链等新技术的应用,在 Kubernetes 上面都有办法部署。Kubernetes 已经成为了现实意义的 “操作系统” 。它在云原生的地位正如移动设备中的 Android。为什么这样讲?Android 不仅仅装在我们的手机上,它还进一步渗透到汽车、电视、天猫精灵等智能终端里,移动应用可以通过 Android 运行在这些设备上。而 Kubernetes 也有这样的潜力或发展趋势,当然它不是出现在智能家电中,而是出现在各家公有云、自建机房,以及边缘集群。可以预想,Kubernetes 未来会像 Android 一样无处不在。
那么,有了 Kubernetes 这层交付以后,容器 + Kubernetes 这层界面是不是就可以解决掉所有的交付问题了?答案肯定不是。试想,如果我们的手机中只有 Android 系统,它能够满足我们工作和生活需求吗?不能,必须有各种各样的软件应用才行。对应到云原生,它除了 Kubernetes 这个 “操作系统” 外,也需要一套应用的交付能力。在手机中,软件应用可以通过类似“豌豆荚”这样的应用以便用户安装,同样在云原生时代,我们也需要将应用部署到不同的 Kubernetes 集群上。但由于 Kubernetes 海量琐碎的设施细节与复杂各异的操作语言,导致部署过程中会遇到各种各样的问题,这时就需要云原生的“豌豆荚”来解决这个问题,也就是应用管理平台,去屏蔽交付的复杂性。
应用管理平台在业界有两种主流模式,第一种是传统平台模式,在 Kubernetes 上 “盖一个大帽子” ,将所有复杂度屏蔽,在此之上,再根据需求自己提供一层简化的应用抽象。通过这种方式,虽然应用平台变得易用了,但新的能力需要由平台开发实现,也就带来了扩展难、迭代缓慢的问题,无法满足日益增长的应用管理诉求。
另一种解法是容器平台模式。这种模式比较云原生,组件是开放的,扩展性强,但是,它缺乏应用层的抽象,导致了很多问题,比如开发者学习路线陡峭。举个例子,当一个业务开发者把自己的代码提交到应用平台时,他需要写 Deployment 部署应用、写 Prometheus 规则配置监控、写 HPA 设置弹性伸缩,写 Istio 规则控制路由等,这些都不是业务开发希望去做的。
所以,不论是哪种解法,都有优缺点,需要取舍。那么,到底怎么做才能封装平台的复杂性,还能拥有良好的扩展性?这是我们一直在探索的。
通过应用管理平台,屏蔽云原生应用交付的复杂性
2012 年,阿里巴巴已经开始做容器化相关的调研,起初主要是为了提高资源利用率,开始了自研容器虚拟化技术之路。随着应对大促的机器资源量不断增多,在 2015 年开始采用容器的混合云弹性架构,并使用阿里云的公有云计算资源,支撑大促流量高峰。这也是阿里巴巴做云原生的早期阶段。
转折发生在 2018 年,阿里巴巴的底层调度采用开源的 Kubernetes 后,我们从面对虚拟机的脚本化安装部署模式,转变为基于标准的容器调度系统部署应用,全面推进阿里巴巴基础设施的 Kubernetes 升级。但很快,新的问题就出现了:应用平台没有标准、不统一,大家“各自为政”。
因此,我们在 2019 年携手微软发布了开放应用模型——OAM(Open Application Model),并开始做 OAM 平台化改造。一切都比较顺利,2020 年 OAM 的实现引擎 KubeVela 正式开源,在内部推进多套应用管理平台基于 OAM 和 KubeVela 演进。并推动了三位一体战略,不仅阿里内部的核心系统全面使用这套技术,而且在面向客户的商业化云产品以及在开源时,都使用同样的技术。通过全面拥抱开源,让整个 OAM 和 KubeVela 社区参与共建。在这段探索历程中,我们走了不少弯路,也累积了许多踩坑经验,接下来将作具体介绍,同时分享 KubeVela 的设计原理和使用方法,帮助开发者了解云原生应用管理平台的完整解决方案,提高应用开发者的使用体验和应用交付效率。
云原生应用管理平台的解决方案
在探索云原生应用管理平台解决方案的过程中,我们主要遇到 4 项重大挑战,并总结了 4 个基本原则,下文将一一介绍。
挑战 1:不同场景的应用平台接口不统一,重复建设。
虽然,云原生有了 Kubernetes 系统,但在不同场景它会构建不一样的应用平台,且接口完全不统一,交付能力存在很大差异,比如 AI、中间件、Serverless 和电商在线业务都有各自不同的服务平台。因此,在构建应用管理平台时,难免重复开发和重复运维。最理想的状况当然是实现复用,但运维平台架构模式各有不同,没办法做到互通。另外,业务开发者在不同场景对接应用交付时,对接的 API 完全不同,交付能力存在很大差异。这是我们遇到的第一个挑战。
挑战 2:“面向终态”无法满足过程式的交付方式。
在云原生时代,面向终态的设计很受欢迎,因为它能减少使用者对实现过程的关心。使用者只需要描述自己想要什么,不需要详细规划执行路径,系统就能自动把事情做好。但在实际使用过程中,交付过程通常需要审批、暂停观察、调整等人为干预。举个例子,我们的 Kubernetes 系统在交付过程中处于强管护的状态,要审批发布。在《阿里集团变更管理规范》中明确 “线上变更,前 x 个线上生产环境批次,每个批次变更后观察时间应大于 y 分钟。” “必须先在安全生产环境(SPE)内进行发布,只有在 SPE 验证无问题后,才能在线上生产环境进行灰度发布。” 因此,应用交付是一个面向过程而非面向终态的执行流程,我们必须考虑,怎样让它更好地适应面向过程的流程。
挑战 3:平台能力扩展复杂度太高。
上文提到,传统模式下的应用平台扩展性差,那么在云原生时代,有哪些常见扩展平台的机制?在 Kubernetes 系统中,可以直接用 Go Template 等模板语言做部署,但缺点是灵活性不够,整个模板写下来结构复杂,难以做大规模的维护。有些高手可能会说 “我可以自定义一套 Kubernetes Controller,扩展性一定很好!” 没错,但是,了解 Kubernetes 及 CRD 扩展机制的人比较少。即使高手把 Controller 写出来了,他还有后续的许多工作要做,比如需要编译并将其安装在 Kubernetes 上运行,另外,Controller 数量也不能一直这样膨胀上去。因此,要想做一个高可扩展的应用平台有很大挑战。
挑战 4:不同环境不同场景,交付差异巨大。
在应用交付过程中,对于不同用途的环境,其运维能力差异特别大。比如开发测试环境,重视开发和联调效率,每次修改采用热加载,不重新打包、走镜像部署的一套流程,同时为开发人员部署按需创建的独立环境。再比如预发联调环境,有攻防演练、故障注入的日常运维诉求。以及在生产环境,需要加入安全生产、服务高可用方面的运维能力。此外,同一个应用,组件依赖也有巨大差异,数据库、负载均衡、存储,在不同云上存在诸多差异。
针对以上四项挑战,我们总结了现代应用管理平台的 4 点核心设计原则:
1. 统一的、基础设施无关的开放应用模型。
2. 围绕工作流的声明式交付。
3. 高度可扩展,易编程。
4. 面向混合环境的设计。
原则1:统一的、基础设施无关的开放应用模型。
怎样提炼统一的、基础设施无关的开放应用模型呢?以开放应用模型,即 OAM 为例,首先,它的设计非常简单,且能够大幅简化我们对管理平台的使用:原来使用者要面对上百个 API,OAM 将其抽象成 4 类交付模型。其次,OAM 从业务开发者视角描述要交付的组件,要用到的运维能力和交付策略,由平台开发者提供运维能力和交付策略的实现,从而对开发者屏蔽基础设施细节与差异性。通过组件模型,OAM 可以用来描述容器、虚拟机、云服务、Terraform 组件、Helm 等制品。
如图 2,这是用 OAM 描述的一个 KubeVela 应用交付示例,里面包含上述 4 类模型。首先,要描述一个应用部署时包含的待交付组件(Component),一般是镜像、制品包、云服务等形式;其次,要描述应用部署后用到的运维能力(Trait),比如路由规则、自动扩缩容规则等,运维能力都作用于组件上;再次,是交付策略(Policy),比如集群分发策略、健康检查策略、防火墙规则等,任何一个部署前需要遵守的规则都可以在这个阶段声明和执行;最后,是工作流(Workflow)的定义,比如蓝绿部署、带流量的渐进式部署、手动审批等任意的管道式持续交付策略。
原则 2:围绕工作流做声明式的交付。
上面 4 类模型中最核心的是工作流,应用交付本质上是一次编排,将组件、运维能力、交付策略、工作流步骤等按顺序定义在一个有向无环图 DAG 里面。
举个例子,应用交付前的第一步,比如安装系统部署依赖、初始化检查等,通过交付策略描述并在交付最开始的时候执行;第二步是依赖的部署,比如应用依赖了数据库,我们可以通过组件创建相关的云资源,也可以引用一个已有的数据库资源,将数据库连接串作为环境参数注入到应用环境中;第三步是用组件部署应用本身,包括镜像版本、开放端口等;第四步是应用的运维能力,比如设置监控方式、弹性伸缩策略、负载均衡等;第五步是在线上环境插入一个人工审核,检查应用启动是否有问题,人工确认没问题之后再继续让工作流往下走;第六步是将剩下的资源并行部署完,然后通过钉钉消息做回调,将部署完的消息告诉开发人员。这就是我们在真实场景中的交付流程。
这个工作流最大的价值在于,它把一个复杂的、面向不同环境的交付过程通过标准化的程序,较为规范地描述了出来。
原则 3:高度可扩展、易编程。
我们一直希望能够像乐高积木一样构建应用模块,平台开发者可以使用平台的业务开发轻松扩展应用平台的能力。但前文提到,用模板语言这种方式,灵活性不够、扩展性不足,而写 Kubernetes Controller 又太复杂、对开发者的专业能力要求极高。那怎么才能既有高度可扩展性,又有编程的灵活性?我们最后借鉴了谷歌 Borg 的 CUElang,这是一个适合做数据模板化、数据传递的配置语言。它天然适合调用 Go 语言,很容易与 Kubernetes 生态融合,具备高灵活性。而且 CUElang 是动态配置语言,不需要编译发布,响应速度快,只要将规则发布到 Kubernetes,就立马生效。
以 KubeVela 的动态扩展机制为例,平台开发者编写完 Web 服务、定时任务等组件模板,以及弹性伸缩、滚动升级等运维能力模板后,将这些能力模板(OAM X-Definition)注册到对应的环境。KubeVela 根据能力模板内容将能力运行时需要的依赖安装到对应环境的集群上。此时,应用开发者就可以使用平台开发者刚才编写的这些模板,他通过选择组件和运维能力构建出一个应用 Application yaml,并将 yaml 发布到 KubeVela 控制面上。KubeVela 通过 Application yaml 编排应用,运行对应选取的能力模板,最终把应用发布到 Kubernetes 集群中。整个从能力定义、应用描述,到最终完成交付的过程就完成了。
原则4:面向混合环境的设计。
在 KubeVela 设计之初,我们就考虑到未来可能是在混合环境(混合云/多云/分布式云/边缘)中做应用的交付,且不同环境、不同场景的交付差异较大。我们做了两件事。第一,将 KubeVela 控制平面完全独立,不入侵业务集群。可以在业务集群中使用任何来自社区的 Kubernetes 插件运维和管理应用,由 KubeVela 负责在控制平面管理和操作这些插件。第二,不使用 KubeFed 等会生成大量联邦对象的技术,而是直接向多集群进行交付,保持和单集群管理一致的体验。通过集成 OCM/Karmada 等多容器集群管理方案支持 Push 和 Pull 模式。在中央管控、异构网络等场景下,KubeVela 可以实现安全集群治理、环境差异化配置、多集群灰度发布等能力。
以阿里云内部边缘计算产品的方案为例,开发人员只需将编写的镜像和 KubeVela 的文件直接发布到 KubeVela 控制平面,控制平面会将应用组件分发到中心托管集群或边缘集群。边缘集群可以采用 OpenYurt 等边缘集群管理方案。因为 KubeVela 是多集群统一的控制平面,所以它可以实现应用组件的统一编排、云-边集群差异配置,以及汇聚所有底层的监控信息,实现统一可观测和绘制跨集群资源拓扑等目的。
总结
总的来说,上述 4 个 KubeVela 核心设计原则可以简单囊括为:
1.基于 OAM 抽象基础设施底层细节,用户只需要关心 4 个交付模型。
2.围绕工作流的声明式交付,工作流无需额外启动进程或容器,交付流程标准化。
3.高度可扩展、易编程:将运维逻辑用 CUE 语言代码化,比模板语言更灵活,比写 Controller 简单一个量级。
4.面向混合环境的设计,提供环境和集群等围绕应用的概念抽象,统一管控所有应用依赖的资源 (包含云服务等)。
目前,KubeVela 已经成为阿里云原生基础设施一部分。从图 5 可见,我们在 Kubernetes 之上做了很多扩展,包括资源池、节点、集群管理能力,对工作负载和自动化运维能力也做了很多支持。KubeVela 在这些能力之上做了一层统一的应用交付和管理层,以便集团业务能够适用不同场景。
未来云原生将如何演进呢?回顾近十年的云原生发展,一个不可逆转的趋势是标准化界面不断上移。为什么?从 2010 年左右云计算崭露头角到如今站稳脚跟,云的算力得到普及;2015 年前后容器大范围铺开,带来了交付介质的标准化;2018 年左右,Kubernetes 通过对集群调度和运维抽象,实现了基础设施管理的标准化;近两年 Prometheus 和 OpenTelemetry 逐渐让监控走向统一,Envoy/Istio 等 Service Mesh 技术在让流量管理更加通用。从这些云原生发展历程中,我们看到了云原生领域技术碎片化和应用交付复杂性的问题,提出开放应用模型 OAM 并开源 KubeVela 试图解决这个问题。我们相信,应用层标准化将是云原生时代的趋势。
作者介绍:
司徒放,花名“姬风”|阿里云资深技术专家,阿里云应用 PaaS 及 Serverless 产品线负责人。2010 年加入阿里巴巴后一直深度参与服务化和云原生架构的多次跨代演进,如链路跟踪、容器虚拟化、全链路压测、异地多活、中间件云产品化、云原生上云等。负责并主导了阿里巴巴在微服务、可观测性、Serverless 等领域的开源技术和商业化产品建设,致力于通过云原生技术,为外部企业提供成熟稳定的互联网架构解决方案和产品。参与或主导设计的开源项目包括 KubeVela、Spring Cloud Alibaba、Apache Dubbo、Nacos 等。
原文链接
本文为阿里云原创内容,未经允许不得转载。