作者 | 王思宇(酒祝) 来源|阿里巴巴云原生公众号
背景
OpenKruise 项目地址:https://github.com/openkruise/kruise
OpenKruise 是什么?它是阿里云开源的云原生应用自动化管理引擎,也是当前托管在 Cloud Native Computing Foundation (CNCF) 下的 Sandbox 项目。它来自阿里巴巴多年来容器化、云原生的技术沉淀,是阿里内部生产环境大规模应用的基于 Kubernetes 之上的标准扩展组件,一套紧贴上游社区标准、适应互联网规模化场景的技术理念与最佳实践。
值得一提的是,阿里内部使用的 OpenKruise 完全来自于社区版本、代码几乎完全一致。此外,OpenKruise 还被提供到了阿里云容器服务(ACK)的应用目录中,任意云上客户都可以一键安装和使用 OpenKruise。目前在 ACK 上使用 OpenKruise 的客户主要包括斗鱼 TV、申通等,而开源社区中携程、Lyft、有赞等公司也都是 OpenKruise 的用户和贡献者(参考:用户列表)。
版本回顾
从 2019 年 6 月开源伊始,OpenKruise 聚焦于云原生应用部署/发布管理相关领域,扩展应用工作负载(workloads)。从最初的 Advanced StatefulSet、BroadcastJob,到“终极”的无状态应用负载 CloneSet、应用 sidecar 容器管理“利器” SidecarSet、多可用区管理负载 UnitedDeployment 等。
CloneSet:提供了更加高效、确定可控的应用管理和部署能力,支持优雅原地升级、指定删除、发布顺序可配置、并行/灰度发布等丰富的策略,可以满足更多样化的应用场景。
Advanced StatefulSet:基于原生 StatefulSet 之上的增强版本,默认行为与原生完全一致,在此之外提供了原地升级、并行发布(最大不可用)、发布暂停等功能。
SidecarSet:对 sidecar 容器做统一管理,在满足 selector 条件的 Pod 中注入指定的 sidecar 容器。
UnitedDeployment:通过多个 subset workload 将应用部署到多个可用区。
BroadcastJob: 配置一个 job,在集群中所有满足条件的 Node 上都跑一个 Pod 任务。
Advanced DaemonSet:基于原生 DaemonSet 之上的增强版本,默认行为与原生一致,在此之外提供了灰度分批、按 Node label 选择、暂停、热升级等发布策略。
AdvancedCronJob:一个扩展的 CronJob 控制器,目前 template 模板支持配置使用 Job 或 BroadcastJob。
当前 OpenKruise 丰富的 workloads 几乎覆盖了绝大多数通用的应用部署场景,这也是目前社区用户对 OpenKruise 的认知。但 OpenKruise 并不仅仅局限于此,以面向云原生场景的应用自动化为目标,必然不止是“部署”那么简单(当然它并不简单)。
规划一览
在 2021 上半年,OpenKruise 新版本会先围绕应用风险防控、Operator 运行时扩展、daemon 旁路扩展等方面展开,而在此之后,还有增强版本的 HPA、无代码控制器尚在排期中。
1. 风险防控
面向终态的自动化是一把 “双刃剑”,它既为应用带来了声明式的部署能力,同时也潜在地会将一些误操作行为被终态化放大。在发生操作故障时副本数维持、版本一致性、级联删除等机制反而很可能导致爆炸半径扩大,例如:
错误地删除一个(多个) CRD,所有对应的 CR 都被清理掉。
错误地删除一个(多个) workload,其下所有 Pod 都被级联删除。
发布时在 workload 中配置错了策略,超过预期数量(甚至全部)的 Pod 被同时升级。
批量给 Node 打了一个错误的 taint,导致上面所有 Pod 被驱逐。
因为各种各样原因引发的 Pod 批量被删除 ......
在实际的生产集群中存在了各种各样的高危操作,OpenKruise 计划通过一系列可选的风险防控机制来为应用最终的可用性做兜底:
定义**“禁止级联删除”**标签:带这个标签的 CRD、Workload 被删除时,Kruise 会校验如果尚存在 CR 或运行中的 Pod 则拒绝删除。
定义 Pod 删除流控策略:用户可以定义一个集群中 Pod 删除的限流值,比如 1 分钟、10 分钟、1 小时、1 天等时间窗口内最多允许删除多少个 Pod,一旦超出阈值则更多的 Pod 删除请求会被拒绝(可以放大限流值解决)。
新增 **PodUnavailableBudget(PUB)**自定义资源:原生 PDB 只能限制 Pod 驱逐,无法限制删除等操作,局限性非常大。而 PUB 将会采取统一机制,对 Pod 删除/驱逐/原地升级 等所有会导致 Pod 变为不可用状态的操作做校验,一旦某个应用的不可用数量超过(或可用数量低于)策略阈值,PUB 会拒绝这个应用下更多的 Pod 操作。
支持为 workload 自动生成 PUB/PDB:一般来说用户只会配置自身应用的 workload,不管使用的是原生 Deployment 还是 OpenKruise 的 CloneSet/Advanced StatefulSet,其实只是针对应用部署/发布的定义。我们希望 PUB/PDB 能逐渐成为与每个 workload 配对的保护策略,通过自动匹配生成,尽量在用户无感(或极小改动)的情况下得到完善的应用运行时保护。
2. kruise-daemon
过去 OpenKruise 只是作为一个中心 kruise-controller-manager 组件运行、提供 controller/webhook 服务,因此其实对于单机侧的操作无法介入。接下来,我们会引入 kruise-daemon 作为单机侧组件,支持在 Kubelet 之外的旁路实现扩展:
新增镜像预热:通过定义 NodeImage 和 ImagePullJob 实现每台 Node 层面需要执行预热的列表和预热状态上报,以及 ImagePullJob 来指定集群中按什么范围来做规模化预热。
通过镜像预热实现发布加速:在 CloneSet、Advanced StatefulSet 等 workload 做原地升级时,Pod 不会发生重建和飘移,仍然在原先节点上做容器重建升级。因此当用户做灰度(partition)原地升级时,OpenKruise 可以提前在未升级 Pod 所在节点做新版本镜像预热,这样在后续 Pod 做升级的过程中就省去了拉镜像所花费的时间,可以有效提升整体应用发布的速度和效率。
支持指定容器重启:目前在对 Pod 中某个容器原地升级时,Kubelet 会执行容器重建操作,我们看到不少用户也依赖于这个能力做重启。但原地升级是必须修改 image 镜像的,是否有办法不修改镜像实现重启呢?后续 kruise-daemon 会支持此类操作,不过对于 Pod 容器启动、停止顺序等需求还是无法代替 Kubelet 实现的。
提供单机调度优化:通过在调整应用 Pod 的 cgroup 系统来实现单机侧的资源最大化利用和应用 SLO 保障。这是一个探索性的方向,目前尚不确定是否会于 2021 在社区提供稳定版实现。
3. ControllerMesh
Kubernetes 能击败 Mesos/Swarm 等对标产品、成为容器集群调度管理引擎的事实标准,其强大而又灵活的扩展能力功不可没。Operator 既是一种特殊的应用,也是不少有状态应用的自动化管理者。而过去社区整体 Operator 趋势还停留在数量野蛮增长、周边运行时机制却无太大进步,这就导致各类 Controller/Operator 的数量和复杂性也逐渐增加,变得越来越难以理解和管理。
单主问题带来的控制器单点运行,无法负载均衡、无法水平扩展;版本升级一次性切换、无法灰度,A/B 测试、金丝雀等模式都无法实现。另外控制器潜在的爆炸半径大,也没有系统性的防护、速率限制、熔断机制。其他可观测性方面的监控、追踪、度量等也都缺乏统一的方式。
我们希望设计一个方案,能提供对整个控制器运行平面的行为洞察和操作控制的能力,以及一个完整的满足 Controller/Operator 应用各种部署管理与运行时需求的解决方案。这套方案将实现 Operator 分片运行,从而带来水平扩展、灰度升级等能力,除此之外还将会提供故障注入、更灵活的租户隔离、安全防护、可观测性等系统性的平台能力。
总结
目前版本的 OpenKruise 已经提供了丰富的 workloads 与部署发布策略,几乎覆盖了绝大多数通用的应用场景。值此 2021 “牛转乾坤”之际,OpenKruise 打出了“More than workloads”口号,在新的一年里 OpenKruise 将走出现有的应用负载领域,覆盖更多云原生场景、挖掘更深层面的应用自动化需求。我们欢迎每一位云原生爱好者共同参与 OpenKruise 的建设,共同打造业界顶尖的云原生应用自动化引擎!
- Github:https://github.com/openkruise/kruise
- Official:https://openkruise.io/
- 钉钉交流群:钉钉搜索群号 23330762