目录
• 云原生时代的运维挑战
• “目前没有一个 IDP 可以满足所有使用场景”
• 可靠性的配置管理方式
• 决定成败的,不只有技术
3 月 15 日,KCD Beijing 2025 成功举办。Karpor 团队出席并发表演讲《Karpor——开启 AI 时代下可靠、安全、智能的多集群洞察之旅》,分享 AI 时代下 Karpor 对于多集群管理与洞察问题的思考与总结。
Karpor 是 KusionStack 的核心组件之一,是 Kubernetes 多集群管理工具,支持通过自然语言与 Kubernetes 集群交互,降低运维复杂度,可提供多集群资源的可视化、搜索、洞察和 AI 加持的数据智能。
KusionStack 最初于 2020 年在蚂蚁集团孵化,经过多年的发展,逐渐演变为一个松耦合的平台工程技术栈。2023 年,KusionStack 通过了 全球顶级开源基金会云原生计算基金会(CNCF)的技术监督委员会(TOC)评定,正式成为 CNCF 沙箱(Sandbox)项目,标志着其在云原生领域的重要地位。KusionStack 旨在帮助平台团队构建现代化的内部开发者平台(IDP)。它通过模块化的组件和工具,简化云原生资源管理,降低开发者的认知负担,提升研发和运维效率。
云原生时代的运维挑战
在正式进入话题前,请屏幕前的你思考一个问题:公司的一次迭代从线下环境发布到生产环境总共需要使用到几个系统?占用多少人力?多久能上线?根据 Accelerate State of DevOps 2023 的报告,超过 80% 的企业进行一次变更需要超过一天,甚至几周到一个月的时间。
研发运维效率一直是行业存在的难题。云原生技术的大规模使用不但没有带来研发运维效率的提升,反而使其下降。造成这种现象的根本原因是研发的认知负担过高,既要写业务逻辑,也要做应用运维。在云原生时代,应用运维是一件很复杂的事情,CNCF Landscape 的爆炸性增长也从侧面说明了这一点。研发除了要学习各种云原生工具,还要学习各种内部系统,一次运维在四、五个系统中反复切换是常态,组织规模越大,这问题越严重。
复杂性的提高必然会带来效率与安全的下降。在传统的平台建设思路中,解决上述问题的方法一般是构建一个 PaaS 平台,例如蚂蚁早期的 PaaS 平台是一个 Web 控制台,用户(通常是 App Dev 或 SRE)可以通过 UI 交互完成诸如发布、重启、扩缩容等操作。在技术实现上大体可以分为三部分,前端系统作为系统入口,提供用户交互的能力;后端系统作为中间层,通过胶水代码对接各个基础设施;各个基础设施的 API 作为底层。然而尽管这种架构良好运行了近十年,它已不再适用。
主要有以下三个方面的问题:
- 平台成为了企业效能的瓶颈。 紧耦合的架构要求所有基础设施都由平台团队统一收口,当下基础设施的种类太多,平台团队的人力难以承受如此的增长。
- 研发认知负担过高,迭代周期变长。 由于平台团队无法统一收束所有基础设施,进而导致各个基础设施成为独立的“烟囱”,应用研发需要直接使用这些“烟囱”。底层的复杂性直接暴露给了研发,研发的学习成本变高,效率自然下降。
- 多个独立的基础设施平台,风险敞口变大。各个分散的平台直接面向用户,风险更加分散,安全管控更加困难。Kubernetes 声明式的运维方式导致稳定性问题会快速蔓延到整个集群,进一步提升了安全管控难度。
“目前没有一个 IDP 可以满足所有使用场景”
为解决上述的行业痛点,平台工程的概念应运而生。根据蚂蚁内部大规模的实践经验与业内公司的广泛交流,我们总结了实践平台工程的三个原则:
- 降低用户认知负担,实现研发自服务
- 提高平台的扩展性,可快速接入基础设施,释放平台生产力
- 平台即产品,以用户为中心,产品化的方式构建平台
基于这三个原则,在内部孵化两年多后,我们开源了 KusionStack 平台工程技术栈。每个组织对于平台类的产品的需求差别非常大,因此我们不认为存在一个 IDP(Internal Developer Platform)可以满足所有的使用场景,而是希望通过提供一套技术栈帮助大家更方便地构建自己的开发者平台。
KusionStack 提供了一套模块化的工具和产品,平台团队可以根据需求灵活组合,构建适合自身的 IDP。
核心组件包括:
- Kusion(平台编排器):通过代码化的配置和抽象模块,屏蔽基础设施的复杂性;连接异构基础设施,提升跨团队协作效率,优化应用交付体验。
- Karpor(Kubernetes 多集群管理工具):提供多集群资源的可视化、搜索、洞察和 AI 加持的数据智能;支持通过自然语言与 Kubernetes 集群交互,降低运维复杂度。
- Kuperator(Kubernetes Controller 扩展套件):增强 Kubernetes 工作负载的生命周期管理、流量管理、渐进式发布和可观测性;提供分片、限流、熔断等高可靠性能力,保障大规模集群的稳定性。
下面介绍 KusionStack 体系中的两个重要概念,以及我们是如何解决上述行业痛点。
Kusion Module
Kusion Module 是由平台团队构建的可复用能力模块,数据库、监控配置、中间件等基础能力都可以被视为 Kusion Module。基于 Kusion 的能力,应用研发可以使用这些 Kusion Module 按需选择需要的基础设施能力,实现自服务。Kusion Module 由两部分组成:面向应用研发的 Schema 和生成基础设施可识别配置的 Generator。
- Schema:经过抽象屏蔽基础设施细节,应用研发可理解的模型,只暴露应用研发必须关注的字段,复杂性留给平台工程师。以阿里云 MySQL 为例,应用研发只需要配置一下 MySQL 的版本号这一个字段,Kusion 就能在阿里云上提供一个 MySQL 实例,并把数据库地址、账号、密码等链接信息以环境变量的形式注入到业务容器里,应用研发完全不需要关心阿里云中的 VPC、VSwitch、DatabaseConnection 等资源的配置。
- Generator:研发编写的 AppConfiguration 与平台配置的工作空间配置 workspace.yaml 是 Generator 的输入,Generator 根据输入会生成 Intent,也就是 KusionStack 体系的 single source of truth。Intent 中包含了资源描述、依赖关系、安全策略等本次运维的所有运维意图。Kusion 引擎会解析 Intent 并完成最终的生效。
下面是一个工作空间 workspace.yaml 的示例。平台通过这份配置文件描述工作空间各个 Module 的默认值,并提供了 override 机制,可以为某些应用提供特殊的配置。除了 Module 默认值以外,其他工作空间级别的配置也可以在 workspace.yaml 里配置,比如 Kusion 使用的后端存储介质:本地文件、数据库、OSS/S3、KubeConfig 路径、使用的 Terraform 版本信息等。
借助 Kusion Module,平台工程师可以把基础能力、环境相关的配置封装成独立的 Module,以实现运维能力标准化。结合 workspace 工作空间配置的机制,不同环境配置不同的 workspace,可以灵活实现不同环境的差异化管理,进而实现应用配置“一次编写,多处发布”的多云、混合云的复杂场景。差异化、复杂性留给了平台团队,降低研发的认知负担。
AppConfiguration
AppConfiguration 是应用研发需要编写的配置,里面包含了此应用所需的 Kusion Module,借助平台工程师提供的这些 Kusion Module,应用研发可以按需选择需要的能力,自由组合,满足自己的需求,以实现自服务。
上图是一个 AppConfiguration 的示例,配置编写的过程就是实例化 Kusion Module Schema 的过程。从示例中可以看出,AppConfiguration 中的所有字段都是应用研发必须感知,并可以理解的。我们希望通过这份配置涵盖 SDLC(Software Development Lifecycle),其中包含了:
- Components:完整交付应用所需的组件,包括工作负载 (workload) 、网络端口、数据库、监控配置等。
- Dependency:描述了多个 AppConfiguration 之间的依赖。
- Pipleline:描述应用交付的流程,包括前置检查、审批、部署、后置校验等步骤。
Operating
AppConfiguration 的 workload 部分通常由 Kubernetes 进行交付。Kubernetes 原生提供了 Deployment、StatefulSet 等 workload 来负责这部分工作。不过在实践中发现应用和平台开发者在日常运维应用服务时,还期望有更高阶的能力,因此 KusionStack 在 Kubernetes 多集群和单集群场景都做了能力的扩展,并以 CRD 加 Operator 的形式暴露出来。KusionStack Operating 项目即承载了对 Kubernetes 单集群能力的扩展。其核心能力之一则是引入了 Pod 运维生命周期(PodOpsLifecycle)。
在实际运维时,Pod 的变更前后往往还需要伴随其他的操作,最常见的是开关 Pod 的流量,另外也会有例如对监控告警、Pod 实例状态处理等操作。Kubernetes 原生提供了 Pod Lifecycle 的能力,但是不能满足精细化控制、可回滚、可扩展等诉求,因此 Operating 提出了 Pod 运维生命周期。在一次 Pod 运维生命周期中,存在两类角色:
- Operation Controller:负责发起 Pod 的运维动作,比如 Kubernetes 的 Deployment 和 StatefulSet,或者 Operating 的 CollaSet;
- Resource Controller:负责维护 Pod 周边的资源,并参与到 Pod 的每次运维流程中,比如 Service Controller 需要在 Pod 运维前后做摘挂流操作。
这两类角色不必感知对方的存在,仅需要在 PodOpsLifecycle 的组织下完成各自的工作。而 PodOpsLifecycle 将原生 Pod Lifecycle 进行扩展,添加了 ServiceAvailable、Preparing、Completing 等阶段。在 Preparing 阶段负责完成运维前的准备工作;Completing 阶段负责完成运维后的收尾工作;当运维完成且所有工作结束后则进入 ServiceAvailable 阶段,表示 Pod 已经完成运维并可以提供服务。
图中以流量为例,通过引入 PodOpsLifecycle,可以保证负责流量管控的 Traffic Controller 提前在 Preparing 阶段就介入,开始摘流。当流量摘除成功后才进入 Kubernetes 原生的 Pod Lifecycle,以此保障 Pod 的流量无损变更。最后在 Pod 变更结束后的 Completing 阶段,PodOpsLifecycle 也会关注 Traffic Controller,在其恢复流量后再将 Pod 设置成 ServiceAvailable 状态,以示变更完成。
同时,PodOpsLifecycle 在 Preparing 和 Completing 前还分别加入了 Pre-Check 和 Post-Check 阶段。在这个阶段,Operating 提供了 workload PodTransitionRule,用于在 Pod 变更前后插入一些管控规则,比如常见的 Pre-Check 规则 MaxUnavailable 用于保障应用服务的整体水位。另外也提供如 label 和 webhook 机制帮助扩展更多的规则。此外,KusionStack 也提供了 ResourceConsist 调和框架,帮助更多的 Kubernetes 集群外资源方便的以 Resource Controller 的身份集成到 PodOpsLifecycle 中。目前已经通过该框架集成了阿里云 SLB Controller。
ControllerMesh
随着 Kubernetes 集群规模的增加,Kubernetes Controller 原生机制带入的单点问题越发凸显出来。首先带来高负荷问题,Controller 无法水平扩展要求每个 Controller 实例能独立调和整个集群,有更大的 memory 缓存集群整体的资源,这导致 Controller 冷启动和日常调和效率下降;其次带来高风险问题,正因为 Controller 面对的是整个集群,因此无法提供隔离和灰度的能力,使得故障的爆炸半径至少是集群级别。
因此 KusionStack 引入了 ControllerMesh 项目。每个 Controller 实例创建时,会以 Sidecar 的方式注入 ControllerMesh。它会拦截 Controller 发出的所有网络请求,特别是发往 Kube-APIServer 的请求,并以 labelSelector 的形式向其中注入分片规则,以无侵入的方式实现服务端的分片能力。ControllerMesh 的引入为 Controller 实现了集群分片能力。这让 Controller 具备水平扩展、分片隔离、灰度发布等能力,有效解决了 Controller 单点特性带来的高负荷、高风险问题。
KusionStack Workflow
KusionStack 的工作流分为三个主要步骤:
- 编码(Write):平台工程师提供 Kusion Module,研发人员编写 AppConfiguration。
- 构建(Build):生成运维意图(Intent),作为单一可信源(SoT)。
- 生效(Preview/Apply):Kusion 解析 Intent,通过三路 Diff 算法预览变更,并将配置生效到基础设施。
Kusion 用户可以直接用 kusion apply 自动执行以上所有步骤。
可靠性的配置管理方式
随着云原生技术的发展,基础设施代码化(IaC)已成为自动化和管理云资源的关键,IaC 也成为了开发者体验的核心部分,Kubernetes 和 Terraform 等基础设施即代码 (IaC) 工具已成为越来越流行的管理和部署基于云 API 的应用程序的工具,带来了便利和效率的同时也带来了一系列问题与挑战。
首先,随着应用需求的不断增长和云计算的不断演进,越来越多的新功能被不断引入,如服务发现,负载均衡,权限管理等。这些新功能的引入增加了系统的复杂性,也同时增加了不同资源类型的数量、以及这些资源类型之间的复杂关系也呈指数级增长。普通的应用开发者也需要面对复杂的基础设施和平台概念,这造成了较高的认知负担,影响了更上层应用开发者的软件交付体验。
对于云 API, 我们借助 Terraform 等 IaC 工具可以获得大量的已经编写好的 Module 配置和 Provider 等,但是对于 Kubernetes 仍然缺乏一套成熟标准的管理办法,现有的方案或者规范难以在抽象能力和扩展性获得平衡。在部分情况下,还需要依赖于一线人员的专业素养,采用非标准化的方法比如脚本和胶水代码的方式进行配置管理,导致项目变得越来越复杂、难于维护,开发效率降低并且引入了配置漂移的风险。
因此,我们迫切需要一种能够减轻开发者认知负担、提供高效动态配置管理,并且通过标准的配置测试与验证手段来保证可靠性的配置管理方式,来确保基础设施的高效与安全。
KCL
我们尝试设计了一种新的配置语言 KCL,通过在语言语法的设计和周边工具的增强来解决前文中提到诸多问题。KCL 语言针对前面提到的动态配置管理、配置可靠性的验证与测试和降低开发者认知负担的三个方面出发,提出三个主要的设计理念,Mutation、Validation 和 Abstraction。围绕这三个设计理念,KCL 在语言语法上做了一些设计:
- 使用 KCL 做动态配置管理: 语言侧需要提供诸如流程控制,lambda 表达式等能够描述程序行为的语法。
- 要做配置可靠性相关的验证与测试: 通过强类型系统,assert、check 等语法,赋予该语言能够检查配置内容的能力,来支持测试和验证过程。
- 降低开发者认知负担和开发成本: KCL 提供了 Schema 模型对数据结构进行抽象,对于开发者来说屏蔽非必要字段,并且通过包管理机制提供丰富的三方库资源,降低开发者直接编写模型的编写成本。
KCL 一些核心的语言特性如上图所示。 - Mutation:与通用编程语言相近的流程控制,lambda 表达式 和 python 风格的循环表达式。
- Validation:针对验证和测试过程提供的 assert 语句,schema 的 check 块,通过 check 中的编写的策略可以对 Schema 中的字段进行检查。
Abstraction:使用 Schema 定义数据结构,并且实例化配置。
上述例子已经展示出 KCL 的强类型系统对于配置类型的校验功能。如果在使用 Schema 实例化配置的过程中写错了某个字段类型,就会在编译阶段排查出错误。解决 IaC 领域的问题
为了解决前面提到的三个问题,KCL 提供了提到的一些动态行为,check、assert语句,类型系统,Schema 抽象等等特性。我们在尝试利用上述特性进行配置管理的时候发现,KCL 的语言特性仅仅作用于语言本身是不够的,其目标是解决 IaC 领域的问题。使用 KCL 是一种方式,不是目的,想解决 IaC 领域内的问题,就必须要考虑目前非 KCL 编写的存量配置。将存量配置全部推倒用 KCL 重写无法实现,很明显不是合适的方式。
因此,对于存量的一些配置,除了在语言机制上下功夫之外,还需要具备与社区生态集成的能力,能够将 KCL 语言特性的作用也发挥在其他的配置语言上,使得 KCL 能够真正解决 IaC 领域的问题。在尽可能减少对存量配置的改动下,充分发挥 KCL 语言特性的作用,解决前文提到的动态配置,可靠性校验和降低开发者心智负担的问题。
于是,我们提出了KCL & KRM 规范。基于该个规范,我们可以借助 KCL 语言的能力,对 KRM 中的资源进行动态配置,模型校验和抽象。
更多关于 KCL & KRM 的内容请参考:https://kcl-lang.io/zh-CN/blog/2023-09-06-dcm-using-kcl
麻雀虽小,五脏俱全
虽然 KCL 是一个领域语言,但是 KCL 也提供了与通用编程语言语言能力基本等同的的工具链,如格式化,测试、文档、包管理等工具帮助更好地编写、理解和检查编写的配置或策略;通过 VS Code/Idea/Vim 等 IDE 插件和 Playground 降低配置编写、分享的成本;通过 Rust、Go 和 Python 多语言 SDK 自动化管理和执行配置。对于 IDE 插件,KCL 目前主要提供了 VS Code、IntelliJ 和 NeoVim三种 IDE 插件基于同样的 KCL Language Server 实现了同样的补全、跳转、悬停、代码重构和格式化等能力。
基于 KCL & KRM 规范我们开发了一些工具使 KCL 能够与周边工具生态进行集成。
- 数据结构的导入导出:KCL 提供了如 import/export 工具,支持使用 KCL 从 JsonSchema、Terraform 等导入/导出数据结构,以减少在开发过程中对于数据重复建模的过程,使 KCL 的特性能够直接作用于存量配置。
- 插件:提供如 kubectl、kustomize、helm/helmfile 等工具的 KCL 插件,用户可以针对不同的场景选择合适场景的引擎比如 Kubectl、KusionStack、KubeVela 或 Helmfile 等来和 KCL 结合将配置生效到集群。
- Kubernetes 集成:开发了 KCL Operator,在运行时实现配置自动修改,无需重复开发 Kubernetes Webhook 编写大量的配置处理逻辑。
一门新的语言是否好用,一方面取决于语言语法的设计,另一方面取决于周边工具和 IDE 的使用体验,更重要的是这门语言是否有丰富多彩的三方库。因此,我们与 ArtifactHub (https://artifacthub.io/docs/topics/repositories/kcl-modules/) 进行了集成,将 Artifacthub 作为 KCL 的三方库模型市场,提供了 300 + 的 KCL 模型,涵盖配置编辑、校验和模型抽象等多个方面。欢迎大家参与共建。
更多关于 KCL 生态集成的内容请参考:https://kcl-lang.io/zh-CN/blog/2023-10-23-cloud-native-supply...
云原生策略配置语言 KCL 旨在降低现代云原生配置的复杂性, 降低开发者在 IaC 实践过程中的认知负担,并提供验证和测试等工程手段提升配置的可靠性。同时通过 KCL & KRM 规范以及一些周边生态集成工具来支持对存量配置的配置管理。
决定成败的,不只有技术
上文围绕技术层面介绍了如何建设一个好的平台,或者说实践好平台工程。技术是基础,但只有技术是不够的,还需要产品和组织方面的配合。
平台即产品并不是一句口号,平台的负责人能否真正把内部平台当成商业产品来建设、提升平台用户(应用研发与平台工程师)的体验是平台工程能否成功的一个关键因素。用户使用平台遇到 80% 的问题能否通过文档自助解决,还是一定要找到对应的研发人员来排查问题?产品自身的稳定性是否足够,一次性成功率能到达多少?做好产品并不容易,尤其是做好一个内部产品,内部产品的用户体验往往会因为资源投入、工期等问题妥协。但是积累的债不还,它只会越滚越大,平台效率永远无法提高。
人员组织的上的配合也是非常重要的。举一个具体的例子,开源生态里有一些开箱即用的 Kusion Module,但如果企业内部有自建的基础设施,却没有配套的平台工程师根据业内部的业务去构建内部的 Kusion Module,也无法真正提高平台的效率。
此外,根据我们的经验,不存在一个普适的 IDP 可以满足所有的场景,基于开源产品构建企业内部的 IDP 是一个 ROI 更高的选择。
总结
KusionStack 开源的初衷并不是再去造一个 IDP,而是开源一套可以帮助平台更高效、更安全的构建 IDP 的技术栈。它通过模块化设计、抽象能力和强大的工具链,降低开发者的认知负担,提升研发和运维效率。
KusionStack 和 KCL 开源至今,目前已经在蚂蚁集团、华为、有赞、SafetyCulture 等国内外企业落地,帮助他们构建了自己的 IDP。如果你正在寻找一种高效、灵活的平台工程解决方案,KusionStack 将是一个值得尝试的选择。欢迎加入 KusionStack 社区,与我们一起推动平台工程的未来!
项目地址:https://github.com/KusionStack
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。