【导语】
云原生时代,直接使用Kubernetes和云基础设施过于复杂,如用户需要学习很多底层细节、应用管理的上手成本高、容易出错、故障频频。随着云计算的普及,不同云又有不同的细节,进一步加剧了上述问题。
本文将介绍如何在Kubernetes上构建新的应用管理平台,提供一层抽象以封装底层逻辑,只呈现用户关心的接口,使用户可以只关注自己的业务逻辑,管理应用更快更安全。
作者 | 司徒放 责编 | 田玮靖
出品 | CSDN(ID:CSDNnews)
云原生时代是一个非常好的时代,我们所面临的是整体技术的颠覆性革新,全面地对应用做端到端重构。目前,云原生在演进过程中产生了三个关键技术:
-
一是容器化,容器作为标准化交互的介质,在运维效率、部署密度和资源隔离性方面相比传统方式有很大改进,据CNCF最新调研报告显示,目前已有92%的企业生产系统在使用容器;
-
二是Kubernetes,它对基础设施进行了抽象和管理,现已成为云原生的标配;
-
三是Operator自动化运维,通过控制器和定制资源的机制,使Kubernetes不仅可以运维无状态应用,还可以执行由用户定义的运维能力,实现更复杂的自动化运维应用进行自动化部署和交互。
这三项关键技术其实是逐渐演进的关系,另外,在应用交付领域,也有与之对应的理论在跟随上述技术不断地演进。云原生的崛起,带来了交付介质、基础设施管理、运维模型和持续交付理论的全面升级和突破,加速了云计算时代的到来。
图1 云原生技术全景图(来源:CNCF Landscape 2021-10,https://landscape.cncf.io/)
从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 用开放应用模型描述的一个应用交付示例
如图2,这是用OAM描述的一个KubeVela应用交付示例,里面包含上述4类模型。首先,要描述一个应用部署时包含的待交付组件(Component),一般是镜像、制品包、云服务等形式;其次,要描述应用部署后用到的运维能力(Trait),比如路由规则、自动扩缩容规则等,运维能力都作用于组件上;再次,是交付策略(Policy),比如集群分发策略、健康检查策略、防火墙规则等,任何一个部署前需要遵守的规则都可以在这个阶段声明和执行;最后,是工作流(Workflow)的定义,比如蓝绿部署、带流量的渐进式部署、手动审批等任意的管道式持续交付策略。
原则2:围绕工作流做声明式的交付。
上面4类模型中最核心的是工作流,应用交付本质上是一次编排,将组件、运维能力、交付策略、工作流步骤等按顺序定义在一个有向无环图DAG里面。
图3 KubeVela 通过工作流编排应用交付的示例
举个例子,应用交付前的第一步,比如安装系统部署依赖、初始化检查等,通过交付策略描述并在交付最开始的时候执行;第二步是依赖的部署,比如应用依赖了数据库,我们可以通过组件创建相关的云资源,也可以引用一个已有的数据库资源,将数据库连接串作为环境参数注入到应用环境中;第三步是用组件部署应用本身,包括镜像版本、开放端口等;第四步是应用的运维能力,比如设置监控方式、弹性伸缩策略、负载均衡等;第五步是在线上环境插入一个人工审核,检查应用启动是否有问题,人工确认没问题之后再继续让工作流往下走;第六步是将剩下的资源并行部署完,然后通过钉钉消息做回调,将部署完的消息告诉开发人员。这就是我们在真实场景中的交付流程。
这个工作流最大的价值在于,它把一个复杂的、面向不同环境的交付过程通过标准化的程序,较为规范地描述了出来。
原则3:高度可扩展、易编程。
我们一直希望能够像乐高积木一样构建应用模块,平台开发者可以使用平台的业务开发轻松扩展应用平台的能力。但前文提到,用模板语言这种方式,灵活性不够、扩展性不足,而写 Kubernetes Controller又太复杂、对开发者的专业能力要求极高。那怎么才能既有高度可扩展性,又有编程的灵活性?我们最后借鉴了谷歌Borg的CUElang,这是一个适合做数据模板化、数据传递的配置语言。它天然适合调用Go语言,很容易与Kubernetes生态融合,具备高灵活性。而且CUElang是动态配置语言,不需要编译发布,响应速度快,只要将规则发布到Kubernete,就立马生效。
图4 KubeVela动态扩展机制
以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.面向混合环境的设计,提供环境和集群等围绕应用的概念抽象,统一管控所有应用依赖的资源 (包含云服务等)。
图5 KubeVela在阿里云原生基础设施的位置
目前,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等。
,