OpenKruise|OpenKruise v1.0(云原生应用自动化达到新的高峰)
云原生应用自动化管理套件、CNCF Sandbox 项目 -- OpenKruise,近期发布了 v1.0 大版本。
OpenKruise [1]是针对 Kubernetes 的增强能力套件,聚焦于云原生应用的部署、升级、运维、稳定性防护等领域。所有的功能都通过 CRD 等标准方式扩展,可以适用于 1.16 以上版本的任意 Kubernetes 集群。单条 helm 命令即可完成 Kruise 的一键部署,无需更多配置。
文章图片
总得来看,目前 OpenKruise 提供的能力分为几个领域:
- 应用工作负载: 面向无状态、有状态、daemon 等多种类型应用的高级部署发布策略,例如原地升级、灰度流式发布等。
- Sidecar 容器管理: 支持独立定义 sidecar 容器,完成动态注入、独立原地升级、热升级等功能。
- 增强运维能力: 包括容器原地重启、镜像预拉取、容器启动顺序保障等。
- 应用分区管理: 管理应用在多个分区(可用区、不同机型等)上的部署比例、顺序、优先级等。
- 应用安全防护: 帮助应用在 Kubernetes 之上获得更高的安全性保障与可用性防护。
【OpenKruise|OpenKruise v1.0(云原生应用自动化达到新的高峰)】首先要说的是,从 v1.0 开始 OpenKruise 将 CRD/WehhookConfiguration 等资源配置的版本从 v1beta1 升级到 v1 ,因此可以支持 Kubernetes v1.22 及以上版本的集群,但同时也要求 Kubernetes 的版本不能低于 v1.16。
以下对 v1.0 的部分功能做简要介绍,详细的 ChangeLog 列表请查看 OpenKruise Github 上的 release 说明以及官网文档。
支持环境变量原地升级
Author: @FillZpp [2]
OpenKruise 从早期版本开始就支持了 “原地升级” 功能,主要应用于 CloneSet 与 Advanced StatefulSet 两种工作负载上。简单来说,原地升级使得应用在升级的过程中,不需要删除、新建 Pod 对象,而是通过对 Pod 中容器配置的修改来达到升级的目的。
文章图片
文章图片
如上图所示,原地升级过程中只修改了 Pod 中的字段,因此:
- 可以避免如调度、分配 IP、分配、挂载盘等额外的操作和代价。
- 更快的镜像拉取,因为开源复用已有旧镜像的大部分 layer 层,只需要拉取新镜像变化的一些 layer。
- 当一个容器在原地升级时,Pod 的网络、挂载盘、以及 Pod 中的其他容器不会受到影响,仍然维持运行。
经过我们的不懈努力,OpenKruise 终于在 v1.0 版本中,支持了通过 Downward API 的方式支持了 env 环境变量的原地升级。例如对以下 CloneSet YAML,用户将配置定义在 annotation 中并关联到对应 env 中。后续在修改配置时,只需要更新 annotation value 中的值,Kruise 就会对 Pod 中所有 env 里引用了这个 annotation 的容器触发原地重建,从而生效这个新的 value 配置。
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
...
spec:
replicas: 1
template:
metadata:
annotations:
app-config: "... the real env value ..."
spec:
containers:
- name: app
env:
- name: APP_CONFIG
valueFrom:
fieldRef:
fieldPath: metadata.annotations['app-config']
updateStrategy:
type: InPlaceIfPossible
与此同时,我们在这个版本中也去除了过去对镜像原地升级的 imageID 限制,即支持相同 imageID 的两个镜像替换升级。
具体使用方式请参考文档 [3] 。
配置跨命名空间分发
?Author: ? @veophi [4]
在对 Secret、ConfigMap 等 namespace-scoped 资源进行跨 namespace 分发及同步的场景中,原生 kubernetes 目前只支持用户 one-by-one 地进行手动分发与同步,十分地不方便。
典型的案例有:
- 当用户需要使用 SidecarSet 的 imagePullSecrets 能力时,要先重复地在相关 namespaces 中创建对应的 Secret,并且需要确保这些 Secret 配置的正确性和一致性。
- 当用户想要采用 ConfigMap 来配置一些通用的环境变量时,往往需要在多个 namespaces 做 ConfigMap 的下发,并且后续的修改往往也要求多 namespaces 之间保持同步。
ResourceDistribution 目前支持 Secret 和 ConfigMap 两类资源的分发和同步。
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
metadata:
name: sample
spec:
resource:
apiVersion: v1
kind: ConfigMap
metadata:
name: game-demo
data:
...
targets:
namespaceLabelSelector:
...
# or includedNamespaces, excludedNamespaces
如上述 YAML 所示,ResourceDistribution 是一类 cluster-scoped 的 CRD,其主要由 resource 和 targets 两个字段构成,其中 resource 字段用于描述用户所要分发的资源,targets 字段用于描述用户所要分发的目标命名空间。
具体使用方式请参考文档 [5] 。
容器启动顺序控制
Author: @Concurrensee [6]
对于 Kubernetes 的一个 Pod,其中的多个容器可能存在依赖关系,比如 容器 B 中应用进程的运行依赖于 容器 A 中的应用。因此,多个容器之间存在顺序关系的需求:
- 容器 A 先启动,启动成功后才可以启动 容器 B
- 容器 B 先退出,退出完成后才可以停止 容器 A
因此,OpenKruise 在 v1.0 中提供了名为 Container Launch Priority 的功能,用于控制一个 Pod 中多个容器的强制启动顺序:
- 对于任意一个 Pod 对象,只需要在 annotations 中定义 apps.kruise.io/container-launch-priority: Ordered,则 Kruise 会按照 Pod 中 containers 容器列表的顺序来保证其中容器的串行启动。
- 如果要自定义 containers 中多个容器的启动顺序,则在容器 env 中添加 KRUISE_CONTAINER_PRIORITY 环境变量,value 值是范围在 [-2147483647, 2147483647] 的整数。一个容器的 priority 值越大,会保证越先启动。
kubectl-kruise 命令行工具
Author: @hantmac [8]
过去 OpenKruise 是通过 kruise-api、client-java 等仓库提供了 Go、Java 等语言的 Kruise API 定义以及客户端封装,可供用户在自己的应用程序中引入使用。但仍然有不少用户在测试环境下需要灵活地用命令行操作 workload 资源。
然而原生 kubectl 工具提供的 rollout、set image 等命令只能适用于原生的 workload 类型,如 Deployment、StatefulSet,并不能识别 OpenKruise 中扩展的 workload 类型。
因此,OpenKruise 最新提供了 kubectl-kruise 命令行工具,它是 kubectl 的标准插件,提供了许多适用于 OpenKruise workload 的功能。
# rollout undo cloneset
$ kubectl kruise rollout undo cloneset/nginx
#rollout status advanced statefulset
$ kubectl kruise rollout status statefulsets.apps.kruise.io/sts-demo
# set image of a cloneset
$ kubectl kruise set image cloneset/nginx busybox=busybox nginx=nginx:1.9.1
具体使用方式请参考文档 [9] 。
其余部分功能改进与优化
CloneSet:
- 通过 scaleStrategy.maxUnavailable 策略支持流式扩容
- Stable revision 判断逻辑变化,当所有 Pod 版本与 updateRevision 一致时则标记为 currentRevision
- 支持接管存量 Pod 到匹配的 subset 分组中
- 优化 webhook 在 Pod 注入时的更新与重试逻辑
- 支持对 Daemon Pod 做原地升级
- 引入 progressive annotation 来选择是否按 partition 限制 Pod 创建
- 解决 SidecarSet 过滤屏蔽 inactive Pod
- 在 transferenv 中新增 SourceContainerNameFrom 和 EnvNames 字段,来解决 container name 不一致与大量 env 情况下的冗余问题
- 新增 “跳过保护” 标识
- PodUnavailableBudget controller 关注 workload 工作负载的 replicas 变化
- 加入 --nodeimage-creation-delay 参数,并默认等待新增 Node ready 一段时间后同步创建 NodeImage
- 解决 NodeSelectorTerms 为 nil 情况下 Pod NodeSelectorTerms 长度为 0 的问题
- kruise-daemon 采用 protobuf 协议操作 Pod 资源
- 暴露 cache resync 为命令行参数,并在 chart 中设置默认值为 0
- 解决 certs 更新时的 http checker 刷新问题
- 去除对 forked controller-tools 的依赖,改为使用原生 controller-tools 配合 markers 注解
- 加入社区 Slack channel [11] (English)
- 加入社区钉钉群:搜索群号 23330762 (Chinese)
- 加入社区微信群:添加用户 openkruise 并让机器人拉你入群 (Chinese)
??https://openkruise.io??
[2]@FillZpp:
??https://github.com/FillZpp??
[3]文档:
/docs/core-concepts/inplace-update
[4]@veophi:
??https://github.com/veophi??
[5]文档:
/docs/user-manuals/resourcedistribution
[6]@Concurrensee:
??https://github.com/Concurrensee??
[7]文档:
/docs/user-manuals/containerlaunchpriority
[8]@hantmac:
??https://github.com/hantmac??
[9]文档:
/docs/cli-tool/kubectl-plugin
[10]社区双周会:
??https://shimo.im/docs/gXqmeQOYBehZ4vqo??
[11]Slack channel:
??https://kubernetes.slack.com/channels/openkruise??
戳??原文??,查看 OpenKruise 项目官方主页与文档!
推荐阅读
- 赠己诗
- 八、「料理风云」
- 西湖游
- 两短篇
- 9531
- NeuVector 会是下一个爆款云原生安全神器吗()
- S8大连侠盗勇士
- 走向天空,走向云(小说)3
- 2018年7月11日|2018年7月11日 星期三 多云转晴(18)
- (全员向连载)云间当铺(一)