一、介绍
OpenKruise 是一个基于 Kubernetes 的扩展套件,主要聚焦于云原生应用的自动化,比如部署、发布、运维以及可用性防护。
OpenKruise 提供的绝大部分能力都是基于 CRD 扩展来定义,它们不存在于任何外部依赖,可以运行在任意纯净的 Kubernetes 集群中。
二、核心能力
-
增强版本的 Workloads
OpenKruise 包含了一系列增强版本的 Workloads(工作负载),比如 CloneSet、Advanced StatefulSet、Advanced DaemonSet、BroadcastJob 等。
它们不仅支持类似于 Kubernetes 原生 Workloads 的基础功能,还提供了如原地升级、可配置的扩缩容/发布策略、并发操作等。
其中,原地升级是一种升级应用容器镜像甚至环境变量的全新方式。它只会用新的镜像重建 Pod 中的特定容器,整个 Pod 以及其中的其他容器都不会被影响。因此它带来了更快的发布速度,以及避免了对其他 Scheduler、CNI、CSI 等组件的负面影响。
-
应用的旁路管理
OpenKruise 提供了多种通过旁路管理应用 sidecar 容器、多区域部署的方式,“旁路” 意味着你可以不需要修改应用的 Workloads 来实现它们。
比如,SidecarSet 能帮助你在所有匹配的 Pod 创建的时候都注入特定的 sidecar 容器,甚至可以原地升级已经注入的 sidecar 容器镜像、并且对 Pod 中其他容器不造成影响。
而 WorkloadSpread 可以约束无状态 Workload 扩容出来 Pod 的区域分布,赋予单一 workload 的多区域和弹性部署的能力。
-
高可用性防护
OpenKruise 在为应用的高可用性防护方面也做出了很多努力。
目前它可以保护你的 Kubernetes 资源不受级联删除机制的干扰,包括 CRD、Namespace、以及几乎全部的 Workloads 类型资源。
相比于 Kubernetes 原生的 PDB 只提供针对 Pod Eviction 的防护,PodUnavailableBudget 能够防护 Pod Deletion、Eviction、Update 等许多种 voluntary disruption 场景。
-
高级的应用运维能力
OpenKruise 也提供了很多高级的运维能力来帮助你更好地管理应用。
你可以通过 ImagePullJob 来在任意范围的节点上预先拉取某些镜像,或者指定某个 Pod 中的一个或多个容器被原地重启。
三、关系对比
OpenKruise vs. Kubernetes
简单来说,OpenKruise 对于 Kubernetes 是一个辅助扩展角色。
Kubernetes 自身已经提供了一些应用部署管理的功能,比如一些基础工作负载。 但对于大规模应用与集群的场景,这些基础功能是远远不够的。
OpenKruise 可以被很容易地安装到任意 Kubernetes 集群中,它弥补了 Kubernetes 在应用部署、升级、防护、运维 等领域的不足。
OpenKruise vs. Platform-as-a-Service (PaaS)
OpenKruise 不是一个 PaaS 平台,并且也不会提供任何 PaaS 层的能力。
它是一个 Kubernetes 的标准扩展套件,目前包括 kruise-manager
和 kruise-daemon
两个组件。 PaaS 平台可以通过使用 OpenKruise 提供的这些扩展功能,来使得应用部署、管理流程更加强大与高效。
四、安装
从 v1.0.0 (alpha/beta) 开始,OpenKruise 要求在 Kubernetes >= 1.16 以上版本的集群中安装和使用。
4.1 通过 helm 安装
建议采用 helm v3.5+ 来安装 Kruise,helm 是一个简单的命令行工具可以从 这里 获取。
# Firstly add openkruise charts repository if you haven't do this.
$ helm repo add openkruise https://openkruise.github.io/charts/
# [Optional]
$ helm repo update
# Install the latest version.
$ helm install kruise openkruise/kruise --version 1.2.0
[root@k8s-master][15:15:38][OK] ~/deploy_pvc
#helm list -n default
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
kruise default 1 2022-09-06 09:43:06.88164278 +0800 CST deployed kruise-1.2.0 1.2.0
[root@k8s-master][15:16:27][OK] ~/deploy_pvc
#kubectl get deploy,po -n kruise-system
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/kruise-controller-manager 2/2 2 2 5h33m
NAME READY STATUS RESTARTS AGE
pod/kruise-controller-manager-766b57c995-gpxd6 1/1 Running 0 5h33m
pod/kruise-controller-manager-766b57c995-ktk4c 1/1 Running 0 5h33m
pod/kruise-daemon-466c5 1/1 Running 0 5h33m
pod/kruise-daemon-k65ml 1/1 Running 0 5h33m
pod/kruise-daemon-pskzb 1/1 Running 0 5h33m
4.2 通过 helm 升级
# Firstly add openkruise charts repository if you haven't do this.
$ helm repo add openkruise https://openkruise.github.io/charts/
# [Optional]
$ helm repo update
# Upgrade to the latest version.
$ helm upgrade kruise openkruise/kruise --version 1.2.0 [--force]
4.3 手工下载 charts 包(可选)
如果你在生产环境无法连接到 https://openkruise.github.io/charts/
,可以先在这里手工下载 chart 包,再用它安装或更新到集群中。
$ helm install/upgrade kruise /PATH/TO/CHART
4.3.1 可选项
注意直接安装 chart 会使用默认的 template values,你也可以根据你的集群情况指定一些特殊配置,比如修改 resources 限制或者配置 feature-gates。
4.3.2 可选: chart 安装参数
下表展示了 chart 所有可配置的参数和它们的默认值:
Parameter | Description | Default |
---|---|---|
featureGates | 可配置的 feature gates 参数,空表示按默认开关处理 | |
installation.namespace | kruise 安装到的 namespace,一般不建议修改 | kruise-system |
installation.createNamespace | 是否需要创建上述 namespace,一般不建议修改,除非指定安装到已有的 ns 中 | true |
manager.log.level | kruise-manager 日志输出级别 | 4 |
manager.replicas | kruise-manager 的期望副本数 | 2 |
manager.image.repository | kruise-manager/kruise-daemon 镜像仓库 | openkruise/kruise-manager |
manager.image.tag | kruise-manager/kruise-daemon 镜像版本 | 1.2.0 |
manager.resources.limits.cpu | kruise-manager 的 limit CPU 资源 | 200m |
manager.resources.limits.memory | kruise-manager 的 limit memory 资源 | 512Mi |
manager.resources.requests.cpu | kruise-manager 的 request CPU 资源 | 100m |
manager.resources.requests.memory | kruise-manager 的 request memory 资源 | 256Mi |
manager.metrics.port | metrics 服务的监听端口 | 8080 |
manager.webhook.port | webhook 服务的监听端口 | 9443 |
manager.nodeAffinity | kruise-manager 部署的 node affinity 亲和性 | {} |
manager.nodeSelector | kruise-manager 部署的 node selector 亲和性 | {} |
manager.tolerations | kruise-manager 部署的 tolerations | [] |
daemon.log.level | kruise-daemon 日志输出级别 | 4 |
daemon.port | kruise-daemon 的 metrics/healthz 服务监听端口 | 10221 |
daemon.resources.limits.cpu | kruise-daemon 的 limit CPU 资源 | 50m |
daemon.resources.limits.memory | kruise-daemon 的 limit memory 资源 | 128Mi |
daemon.resources.requests.cpu | kruise-daemon 的 request CPU 资源 | 0 |
daemon.resources.requests.memory | kruise-daemon 的 request memory 资源 | 0 |
daemon.affinity | kruise-daemon 部署的 affinity 亲和性 (可以排除一些 node 不部署 daemon) | {} |
daemon.socketLocation | Node 节点上 CRI socket 文件所在目录 | /var/run |
daemon.socketFile | 指定 socketLocation 目录下的 socket 文件名 (如果你使用的 CRI 类型不是 containerd/docker/pouch/cri-o) | |
webhookConfiguration.failurePolicy.pods | Pod webhook 的失败策略 | Ignore |
webhookConfiguration.timeoutSeconds | 所有 Kruise webhook 的调用超时时间 | 30 |
crds.managed | 是否安装 Kruise CRD (如何关闭则 chart 不会安装任何 CRD) | true |
manager.resyncPeriod | kruise-manager 中 informer 的 resync 周期,默认不做 resync | 0 |
manager.hostNetwork | kruise-manager pod 是否采用 hostnetwork 网络 | false |
imagePullSecrets | kruise 镜像用的 imagePullSecrets 列表 | false |
这些参数可以通过
--set key=value[,key=value]
参数在helm install
或helm upgrade
命令中生效。
4.3.3 可选: feature-gate
Feature-gate 控制了 Kruise 中一些有影响性的功能:
Name | Description | Default | Side effect (if closed) |
---|---|---|---|
PodWebhook | 启用对于 Pod 创建 的 webhook (不建议关闭) | true | SidecarSet/KruisePodReadinessGate 不可用 |
KruiseDaemon | 启用 kruise-daemon DaemonSet (不建议关闭) | true | 镜像预热/容器重启 不可用 |
DaemonWatchingPod | 每个 kruise-daemon 会 watch 与自己同节点的 pod (不建议关闭) | true | 同 imageID 的原地升级,以及支持 env from labels/annotation 原地升级 不可用 |
CloneSetShortHash | 启用 CloneSet controller 只在 pod label 中设置短 hash 值 | false | CloneSet 名字不能超过 54 个字符(默认行为) |
KruisePodReadinessGate | 启用 Kruise webhook 将 'KruisePodReady' readiness-gate 在所有 Pod 创建时注入 | false | 只会注入到 Kruise workloads 创建的 Pod 中 |
PreDownloadImageForInPlaceUpdate | 启用 CloneSet 自动为原地升级的过程创建 ImagePullJob 来预热镜像 | false | 原地升级无镜像提前预热 |
CloneSetPartitionRollback | 启用如果 partition 被调大, CloneSet controller 会回滚 Pod 到 currentRevision 老版本 | false | CloneSet 只会正向发布 Pod 到 updateRevision |
ResourcesDeletionProtection | 资源删除防护 | false | 资源删除无保护 |
TemplateNoDefaults | 是否取消对 workload 中 pod/pvc template 的默认值注入 | false | Should not close this feature if it has open |
PodUnavailableBudgetDeleteGate | 启用 PodUnavailableBudget 保护 pod 删除、驱逐 | false | 不防护 pod 删除、驱逐 |
PodUnavailableBudgetUpdateGate | 启用 PodUnavailableBudget 保护 pod 原地升级 | false | 不防护 pod 原地升级 |
WorkloadSpread | 启用 WorkloadSpread 管理应用多分区弹性与拓扑部署 | false | 不支持 WorkloadSpread |
InPlaceUpdateEnvFromMetadata | 启用 Kruise 原地升级容器当它存在 env from 的 labels/annotations 发生了变化 | false | 容器中只有 image 能够原地升级 |
StatefulSetAutoDeletePVC | 启用 StatefulSet 自动删除它所创建的 PVC | false | StatefulSet 不会清理 PVC |
如果你要配置 feature-gate,只要在安装或升级时配置参数即可,比如:
$ helm install kruise https://... --set featureGates="ResourcesDeletionProtection=true\,PreDownloadImageForInPlaceUpdate=true"
如果你希望打开所有 feature-gate 功能,配置参数 featureGates=AllAlpha=true
。
4.3.4 可选: 中国本地镜像
如果你在中国、并且很难从官方 DockerHub 上拉镜像,那么你可以使用托管在阿里云上的镜像仓库:
$ helm install kruise https://... --set manager.image.repository=openkruise-registry.cn-hangzhou.cr.aliyuncs.com/openkruise/kruise-manager
五、卸载
注意:卸载会导致所有 Kruise 下的资源都会删除掉,包括 webhook configurations, services, namespace, CRDs, CR instances 以及所有 Kruise workload 下的 Pod。 请务必谨慎操作!
卸载使用 helm chart 安装的 Kruise:
$ helm uninstall kruise
release "kruise" uninstalled
六、系统架构
OpenKruise 的整体架构如下:
6.1 API
所有 OpenKruise 的功能都是通过 Kubernetes API 来提供, 比如:
- 新的 CRD 定义,比如
$ kubectl get crd | grep kruise.io
advancedcronjobs.apps.kruise.io 2021-09-16T06:02:36Z
broadcastjobs.apps.kruise.io 2021-09-16T06:02:36Z
clonesets.apps.kruise.io 2021-09-16T06:02:36Z
containerrecreaterequests.apps.kruise.io 2021-09-16T06:02:36Z
daemonsets.apps.kruise.io 2021-09-16T06:02:36Z
imagepulljobs.apps.kruise.io 2021-09-16T06:02:36Z
nodeimages.apps.kruise.io 2021-09-16T06:02:36Z
podunavailablebudgets.policy.kruise.io 2021-09-16T06:02:36Z
resourcedistributions.apps.kruise.io 2021-09-16T06:02:36Z
sidecarsets.apps.kruise.io 2021-09-16T06:02:36Z
statefulsets.apps.kruise.io 2021-09-16T06:02:36Z
uniteddeployments.apps.kruise.io 2021-09-16T06:02:37Z
workloadspreads.apps.kruise.io 2021-09-16T06:02:37Z
# ...
- 资源对象中的特定标识(labels, annotations, envs 等),比如
apiVersion: v1
kind: Namespace
metadata:
labels:
# 保护这个 namespace 下的 Pod 不被整个 ns 级联删除
policy.kruise.io/delete-protection: Cascading
6.2 Manager
Kruise-manager 是一个运行 controller 和 webhook 中心组件,它通过 Deployment 部署在 kruise-system
命名空间中。
$ kubectl get deploy -n kruise-system
NAME READY UP-TO-DATE AVAILABLE AGE
kruise-controller-manager 2/2 2 2 4h6m
$ kubectl get pod -n kruise-system -l control-plane=controller-manager
NAME READY STATUS RESTARTS AGE
kruise-controller-manager-68dc6d87cc-k9vg8 1/1 Running 0 4h6m
kruise-controller-manager-68dc6d87cc-w7x82 1/1 Running 0 4h6m
逻辑上来说,如 cloneset-controller/sidecarset-controller 这些的 controller 都是独立运行的。不过为了减少复杂度,它们都被打包在一个独立的二进制文件、并运行在 kruise-controller-manager-xxx
这个 Pod 中。
除了 controller 之外,kruise-controller-manager-xxx
中还包含了针对 Kruise CRD 以及 Pod 资源的 admission webhook。Kruise-manager 会创建一些 webhook configurations 来配置哪些资源需要感知处理、以及提供一个 Service 来给 kube-apiserver 调用。
$ kubectl get svc -n kruise-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kruise-webhook-service ClusterIP 172.24.9.234 <none> 443/TCP 4h9m
上述的 kruise-webhook-service
非常重要,是提供给 kube-apiserver 调用的。
6.3 Daemon
这是从 Kruise v0.8.0 版本开始提供的一个新的 daemon 组件。
它通过 DaemonSet 部署到每个 Node 节点上,提供镜像预热、容器重启等功能。
$ kubectl get pod -n kruise-system -l control-plane=daemon
NAME READY STATUS RESTARTS AGE
kruise-daemon-6hw6d 1/1 Running 0 4h7m
kruise-daemon-d7xr4 1/1 Running 0 4h7m
kruise-daemon-dqp8z 1/1 Running 0 4h7m
kruise-daemon-dv96r 1/1 Running 0 4h7m
kruise-daemon-q7594 1/1 Running 0 4h7m
kruise-daemon-vnsbw 1/1 Running 0 4h7m