云原生应用自动化管理套件、CNCF Sandbox 项目 -- OpenKruise,近期发布了 v1.0 大版本。
OpenKruise[1] 是针对 Kubernetes 的增强能力套件,聚焦于云原生应用的部署、升级、运维、稳定性防护等领域。所有的功能都通过 CRD 等标准方式扩展,可以适用于 1.16 以上版本的任意 Kubernetes 集群。单条 helm 命令即可完成 Kruise 的一键部署,无需更多配置。
总得来看,目前 OpenKruise 提供的能力分为几个领域:
在 v1.0 大版本中,OpenKruise 带来了多种新的特性,同时也对不少已有功能做了增强与优化。
首先要说的是,从 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 中的字段,因此:
然而,OpenKruise 过去只能对 Pod 中 image 字段的更新做原地升级,对于其他字段仍然只能采用与 Deployment 相似的重建升级。一直以来,我们收到很多用户反馈,希望支持对 env 等更多字段的原地升级 -- 由于受到 kube-apiserver 的限制,这是很难做到的。
经过我们的不懈努力,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 地进行手动分发与同步,十分地不方便。
典型的案例有:
因此,面对这些需要跨 namespaces 进行资源分发和多次同步的场景,我们期望一种更便捷的分发和同步工具来自动化地去做这件事,为此我们设计并实现了一个新的 CRD --- ResourceDistribution。
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 中的应用。因此,多个容器之间存在顺序关系的需求:
通常来说 Pod 容器的启动和退出顺序是由 Kubelet 管理的。Kubernetes 曾经有一个 KEP 计划在 container 中增加一个 type 字段来标识不同类型容器的启停优先级。但是由于 sig-node 考虑到对现有代码架构的改动太大,目前这个 KEP 已经被拒绝了。
因此,OpenKruise 在 v1.0 中提供了名为 Container Launch Priority 的功能,用于控制一个 Pod 中多个容器的强制启动顺序:
apps.kruise.io/container-launch-priority: Ordered
,则 Kruise 会按照 Pod 中 containers
容器列表的顺序来保证其中容器的串行启动。containers
中多个容器的启动顺序,则在容器 env 中添加 KRUISE_CONTAINER_PRIORITY
环境变量,value 值是范围在 [-2147483647, 2147483647]
的整数。一个容器的 priority 值越大,会保证越先启动。具体使用方式请参考文档[7]。
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
策略支持流式扩容WorkloadSpread:
Advanced DaemonSet:
SidecarSet:
transferenv
中新增 SourceContainerNameFrom
和 EnvNames
字段,来解决 container name 不一致与大量 env 情况下的冗余问题PodUnavailableBudget:
NodeImage:
--nodeimage-creation-delay
参数,并默认等待新增 Node ready 一段时间后同步创建 NodeImageUnitedDeployment:
NodeSelectorTerms
为 nil 情况下 Pod NodeSelectorTerms
长度为 0 的问题Other optimization:
[1]OpenKruise: 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