1、简介
OpenKruise 由 Alibaba 开源,是 Kubernetes 的一个标准扩展,它可以配合原生 Kubernetes 使用,对云原生应用的自动化,比如部署、发布、运维以及可用性防护做了很多贡献。
OpenKruise 是面向自动化场景的 Kubernetes 应用负载扩展控制器。而 Kruise 是 OpenKruise 项目的核心,它是一组控制器,可在应用程序工作负载管理上扩展和补充 Kubernetes 核心控制器。OpenKruise 弥补了 Kubernetes 在应用部署、升级、防护、运维等领域的不足。
2、核心功能
- 原地升级:原地升级是一种可以避免删除、新建 Pod 的升级镜像能力。它比原生 Deployment/StatefulSet 的重建 Pod 升级更快、更高效,并且避免对 Pod 中其他不需要更新的容器造成干扰。
- Sidecar 管理:支持在一个单独的 CR 中定义 sidecar 容器,OpenKruise 能够帮你把这些 Sidecar 容器注入到所有符合条件的 Pod 中。这个过程和 Istio 的注入很相似,但是你可以管理任意你关心的 Sidecar。
- 跨多可用区部署:定义一个跨多个可用区的全局 workload、容器,OpenKruise 会帮你在每个可用区创建一个对应的下属 workload。你可以统一管理 workload 的副本数、版本、甚至针对不同可用区采用不同的发布策略。
- 镜像预热:支持用户指定在任意范围的节点上下载镜像。
3、架构
OpenKruise所有功能都是通过CRD来提供的:

[root@mast01 OpenKruise]# kubectl get crd | grep kruise.io
advancedcronjobs.apps.kruise.io 2024-09-24T07:20:47Z
broadcastjobs.apps.kruise.io 2024-09-24T07:20:47Z
clonesets.apps.kruise.io 2024-09-24T07:20:47Z
containerrecreaterequests.apps.kruise.io 2024-09-24T07:20:47Z
daemonsets.apps.kruise.io 2024-09-24T07:20:47Z
imagepulljobs.apps.kruise.io 2024-09-24T07:20:47Z
nodeimages.apps.kruise.io 2024-09-24T07:20:47Z
nodepodprobes.apps.kruise.io 2024-09-24T07:20:47Z
persistentpodstates.apps.kruise.io 2024-09-24T07:20:47Z
podprobemarkers.apps.kruise.io 2024-09-24T07:20:47Z
podunavailablebudgets.policy.kruise.io 2024-09-24T07:20:47Z
resourcedistributions.apps.kruise.io 2024-09-24T07:20:47Z
sidecarsets.apps.kruise.io 2024-09-24T07:20:47Z
statefulsets.apps.kruise.io 2024-09-24T07:20:47Z
uniteddeployments.apps.kruise.io 2024-09-24T07:20:47Z
workloadspreads.apps.kruise.io 2024-09-24T07:20:47Z
CRD列表
- CloneSet: 提供更加高效、确定可控的应用管理和部署能力,支持优雅原地升级、指定删除、发布顺序可配置、并行/灰度发布等丰富的策略,可以满足更多样化的应用场景。
- StatefulSet: 基于原生 StatefulSet 之上的增强版本,默认行为与原生完全一致,在此之外提供了原地升级、并行发布(最大不可用)、发布暂停等功能。
- SidecarSet: 对 sidecar 容器做统一管理,在满足 selector 条件的 Pod 中注入指定的 sidecar 容器。
- UnitedDeployment: 通过多个 subset workload 将应用部署到多个可用区。
- BroadcastJob: 配置一个 job,在集群中所有满足条件的 Node 上都跑一个 Pod 任务。
- DaemonSet: 基于原生 DaemonSet 之上的增强版本,默认行为与原生一致,在此之外提供了灰度分批、按 Node label 选择、暂停、热升级等发布策略。
- AdvancedCronJob: 一个扩展的 CronJob 控制器,目前 template 模板支持配置使用 Job 或 BroadcastJob。
- ImagePullJob: 支持用户指定在任意范围的节点上下载镜像 。
4、原地升级特性
- 避免重建 Pod:传统 Kubernetes 滚动更新会通过删除旧 Pod、创建新 Pod 的方式进行容器镜像升级。而 OpenKruise 的原地升级不删除 Pod,仅更新其容器镜像。
- 状态保留:对于有状态服务,保持 Pod 不重启,原地升级可以保留服务的网络、状态和其他相关信息,避免因 Pod 重新调度引起的中断。
- 自定义更新控制:通过设置策略和条件,可以灵活控制哪些条件下允许进行原地更新,比如镜像版本的更新、资源的调整等。
5、使用场景
- 有状态服务:如数据库、缓存服务等,这类服务往往需要长时间运行,无法接受频繁的 Pod 重建,原地升级可以保证这些服务的平稳运行。
- 大规模微服务集群:对微服务集群中的某些容器进行更新,而不影响其他部分的服务,减少了服务中断的可能性。
- 资源紧张环境:在资源受限的环境中,避免重建 Pod 可以节省调度和资源开销,提升系统的稳定性。
6、安装
#添加镜像仓库
$ helm repo add openkruise https://openkruise.github.io/charts/
#更新本地的 Helm chart 仓库
$ helm repo update
#安装(k8s集群用的docker,别用太高版本,太高版本用的Containerd,会有问题)
helm install kruise openkruise/kruise --version 1.3.0
#卸载
$ helm uninstall kruise
7、部署
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
name: demo
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: cs
template:
metadata:
labels:
app: cs
spec:
containers:
- name: nginx
image: nginx:alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
创建成功之后通过 kubectl describe命令查看对应的 Events 信息,可以发现 cloneset-controller 是直接创建的 Pod,而原生的Deployment 是通过 ReplicaSet 去创建的 Pod
[root@mast01 CloneSet]# kubectl apply -f 1.yaml
cloneset.apps.kruise.io/demo created
[root@mast01 CloneSet]# kubectl get cloneset demo
NAME DESIRED UPDATED UPDATED_READY READY TOTAL AGE
demo 3 3 3 3 3 13m
[root@mast01 CloneSet]# kubectl describe cloneset demo
Status:
Available Replicas: 3
Collision Count: 0
Current Revision: demo-5c5f449787
Expected Updated Replicas: 3
Label Selector: app=cs
Observed Generation: 1
Ready Replicas: 3
Replicas: 3
Update Revision: demo-5c5f449787
Updated Ready Replicas: 3
Updated Replicas: 3
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 13m cloneset-controller succeed to create pod demo-slfrq
Normal SuccessfulCreate 13m cloneset-controller succeed to create pod demo-s2rhp
Normal SuccessfulCreate 12m cloneset-controller succeed to create pod demo-tsgqn
8、扩容
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
name: demo
namespace: default
spec:
minReadySeconds: 30 # 创建了一个pod之后30s后才会创建第二个
scaleStrategy:
maxUnavailable: 1
replicas: 5
selector:
matchLabels:
app: cs
template:
metadata:
labels:
app: cs
spec:
containers:
- name: nginx
image: nginx:alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
滚动更新时 Pod 的可用性和更新速度的两个重要参数
maxUnavailable:指在滚动更新过程中,最多可以有多少个不可用的 Pod。例如,设置为1表示在更新期间,最多只能有 1 个 Pod 处于不可用状态。这个参数确保在更新期间,总是有一定数量的 Pod 保持可用,防止服务中断。maxSurge:指在滚动更新过程中,最多可以有多少个额外的 Pod 超过期望的副本数量。例如,设置为1表示在更新期间,可以临时创建多 1 个 Pod,从而加快更新过程。
[root@mast01 CloneSet]# kubectl apply -f 2.yaml
cloneset.apps.kruise.io/demo configured
[root@mast01 CloneSet]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo-2hz68 1/1 Running 0 6m18s
demo-c2gsl 1/1 Running 0 5m46s
demo-s2rhp 1/1 Running 0 39m
demo-slfrq 1/1 Running 0 39m
demo-tsgqn 1/1 Running 0 38m
9、缩容
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
name: demo
namespace: default
spec:
minReadySeconds: 30
scaleStrategy:
maxUnavailable: 1
podsToDelete:
- demo-2hz68 # 优先删除这些
replicas: 4
selector:
matchLabels:
app: cs
template:
metadata:
labels:
app: cs
spec:
containers:
- name: nginx
image: nginx:alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
缩容时,CloneSet可以指定一些pod删除,而 StatefulSet 或者 Deployment 做不到
- StatefulSet 是根据序号来删除 Pod,而 Deployment/ReplicaSet 目前只能根据控制器里定义的排序来删除。而 CloneSet 允许用户在缩小 replicas 数量的同时,指定想要删除的 Pod 名字。
- 如果只是把name加入podsToDelete,而没有修改replicas的话,删完之后会再扩一个pod 。
[root@mast01 CloneSet]# kubectl apply -f 3.yaml
cloneset.apps.kruise.io/demo configured
[root@mast01 CloneSet]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo-c2gsl 1/1 Running 0 7m21s
demo-s2rhp 1/1 Running 0 40m
demo-slfrq 1/1 Running 0 40m
demo-tsgqn 1/1 Running 0 39m
10、原地升级
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
name: demo
namespace: default
spec:
minReadySeconds: 30
updateStrategy:
type: InPlaceIfPossible #修改1:指定为最大限度的原地升级的方式
scaleStrategy:
maxUnavailable: 1
replicas: 4
selector:
matchLabels:
app: cs
template:
metadata:
labels:
app: cs
spec:
containers:
- name: nginx
image: nginx:1.7.9 #修改2:把镜像版本替换了
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
原地升级最常见的几种策略
- ReCreate : 更新时 Pod 将被删除,然后重新创建新的 Pod 实例。这个过程会导致 Pod 的 IP 地址和其他相关属性发生变化。使用场景:常见的无状态服务或不需要原地更新的场景。
- InPlaceIfPossible : 系统会尽量在不重启 Pod 的前提下进行升级。如果无法原地更新(如某些字段更新需要重建 Pod),则会删除并重新创建 Pod。使用场景:大多数场景下的推荐策略,尤其是有状态服务,减少重建 Pod 的开销。
- InPlaceOnly : 强制要求所有更新都必须通过原地升级进行,不能删除和重建 Pod。如果某些字段不支持原地更新,则更新会失败。使用场景:要求严格控制 Pod 不被重新创建的场景,例如需要保持 Pod 的 IP 地址或其他属性不变的情况。
[root@mast01 CloneSet]# kubectl apply -f 4.yaml
cloneset.apps.kruise.io/demo configured
[root@mast01 CloneSet]# kubectl get po
NAME READY STATUS RESTARTS AGE
demo-c2gsl 1/1 Running 1 (8m25s ago) 30m
demo-s2rhp 1/1 Running 1 (6m30s ago) 63m
demo-slfrq 1/1 Running 1 (5m57s ago) 63m
demo-tsgqn 1/1 Running 1 (7m32s ago) 62m
[root@mast01 CloneSet]# kubectl get po demo-c2gsl -oyaml|grep image
apps.kruise.io/inplace-update-state: '{"revision":"demo-7cb9c88699","updateTimestamp":"2024-09-26T08:04:18Z","lastContainerStatuses":{"nginx":{"imageID":"docker-pullable://nginx@sha256:a5127daff3d6f4606be3100a252419bfa84fd6ee5cd74d0feaca1a5068f97dcf"}},"containerBatchesRecord":[{"timestamp":"2024-09-26T08:04:18Z","containers":["nginx"]}]}'
- image: nginx:1.7.9
imagePullPolicy: IfNotPresent
image: nginx:1.7.9
imageID: docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451
11、灰度
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
name: demo
namespace: default
spec:
minReadySeconds: 30
updateStrategy:
type: InPlaceIfPossible
partition: 2
scaleStrategy:
maxUnavailable: 1
replicas: 4
selector:
matchLabels:
app: cs
template:
metadata:
labels:
app: cs
spec:
containers:
- name: nginx
image: nginx:latest #修改2:把镜像版本替换了
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
灰度发布常用的两个参数
- partition: 表示最开始会保留 几 个旧版本 Pod,另外 几 个 Pod 会被更新为新版本。
- **maxUnavailable:**限制更新时最多只有 1几个 Pod 会处于不可用状态,保证更新过程中服务的稳定性。
[root@mast01 CloneSet]# kubectl apply -f 5.yaml
cloneset.apps.kruise.io/demo configured
[root@mast01 CloneSet]# kubectl get po
NAME READY STATUS RESTARTS AGE
demo-c2gsl 1/1 Running 1 (9m27s ago) 31m
demo-s2rhp 1/1 Running 2 (10s ago) 64m
demo-slfrq 1/1 Running 2 (88s ago) 64m
demo-tsgqn 1/1 Running 1 (8m34s ago) 63m
[root@mast01 CloneSet]# kubectl get po demo-slfrq -oyaml|grep image
apps.kruise.io/inplace-update-state: '{"revision":"demo-7c4d79f5bc","updateTimestamp":"2024-09-26T08:12:17Z","lastContainerStatuses":{"nginx":{"imageID":"docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451"}},"containerBatchesRecord":[{"timestamp":"2024-09-26T08:12:17Z","containers":["nginx"]}]}'
- image: nginx:latest
imagePullPolicy: IfNotPresent
image: nginx:latest
imageID: docker-pullable://nginx@sha256:04ba374043ccd2fc5c593885c0eacddebabd5ca375f9323666f28dfd5a9710e3
微信打赏:

支付宝打赏:
