原地升级及全链路灰度发布方案OpenKruise
原地升级及全链路灰度发布方案OpenKruise
- OpenKruise部署
本案例使用helm方式安装部署
Helm用于实现kubernetes中相互关联的多个yaml文件的安装部署,相当于linux系统中的yum工具
2.1 安装helm客户端工具
wget https://get.helm.sh/helm-v3.13.2-linux-amd64.tar.gz
托包安装:
tar xf helm-v3.15.2-linux-amd64.tar.gz
mv linux-amd64/helm /usr/bin/

helm version

2.2 通过 helm 安装
[root@master01 ~]# helm repo add openkruise https://openkruise.github.io/charts/
[root@master01 ~]# helm repo update
[root@master01 ~]# helm search repo openkruise
NAME CHART VERSION APP VERSION DESCRIPTION
openkruise/kruise 1.8.0 1.8.0 Helm chart for kruise components
openkruise/kruise-game 0.8.0 0.8.0 Helm chart for kruise-game components
openkruise/kruise-rollout 0.5.0 0.5.0 Helm chart for kruise-rollout components
openkruise/kruise-state-metrics 0.2.0 1.16.0 Install kruise-state-metrics to generate and ex...

注:
Openkruise包括很多功能组件,本课程中主要讲到两个:kruise、kruise-rollout
由于本次部署在K8S 1.28版本集群,并使用cri-dockerd,所以手动指定CRI。
然后托包安装:

# 从本地安装
helm install kruise kruise-1.8.0.tgz \
--set daemon.socketLocation=/var/run \
--set daemon.socketFile=cri-dockerd.sock

然后在安装:
[root@master01 ~]# cd kruise-rollout/
[root@master01 kruise-rollout]# ls
Chart.yaml README.md templates values.yaml
[root@master01 kruise-rollout]#
[root@master01 ~]# helm install kruise-rollout .

[root@master01 ~]# helm list

有vpn通过openkruise/kruise安装一个应用kruise
[root@master01 ~]# helm install kruise openkruise/kruise --version 1.8.0 --set daemon.socketLocation=/var/run --set daemon.socketFile=cri-dockerd.sock
NAME: kruise
LAST DEPLOYED: Wed Jun 12 06:25:50 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
[root@master01 ~]# helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
kruise default 1 2024-06-12 06:25:50.907759992 +0800 CST deployed kruise-1.8.0 1.8.0
[root@master01 ~]# kubectl -n kruise-system get all
NAME READY STATUS RESTARTS AGE
pod/kruise-controller-manager-7c475cb9d6-gjhsd 1/1 Running 0 135m
pod/kruise-controller-manager-7c475cb9d6-lcjkc 1/1 Running 0 135m
pod/kruise-daemon-675mt 1/1 Running 0 135m
pod/kruise-daemon-h7vk2 1/1 Running 0 135m
pod/kruise-daemon-m5bwb 1/1 Running 0 135m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kruise-webhook-service ClusterIP 10.109.153.24 <none> 443/TCP 135m
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/kruise-daemon 3 3 3 3 3 <none> 135m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/kruise-controller-manager 2/2 2 2 135m
NAME DESIRED CURRENT READY AGE
replicaset.apps/kruise-controller-manager-7c475cb9d6 2 2 2 135m

- 原地升级
原地升级是 OpenKruise 提供的核心功能之一
- 什么是原地升级
当我们要升级一个存量 Pod 中的镜像时,分为重建升级和原地升级,区别:
重建升级的特点:
要删除旧 Pod、创建新 Pod
- Pod 名字和 uid 发生变化
因为它们是完全不同的两个 Pod 对象(比如 Deployment 升级)
- Pod 名字可能不变、但 uid 变化
因为它们是不同的 Pod 对象,只是复用了同一个名字(比如 StatefulSet 升级)
- Pod 所在 Node 名字发生变化
因为新 Pod 很大可能性是不会调度到之前所在的 Node 节点的
- Pod IP 发生变化
因为新 Pod 很大可能性是不会被分配到之前的 IP 地址的
原地升级的特点:
仍然复用同一个 Pod 对象,只是修改它里面的字段
- 可以避免如调度、分配IP、分配、挂载盘等额外的操作和代价
- 更快的镜像拉取
因为开源复用已有旧镜像的大部分 layer 层,只需要拉取新镜像变化的一些layer
- 理解 InPlaceIfPossible
类型名为 InPlaceIfPossible ,它意味着 Kruise 会尽量对 Pod 采取原地升级,如果不能则退化到重建升级

- 使用要求
如果要使用原地升级能力,需要在安装或升级 Kruise chart 的时候打开kruise- daemon (默认打开)和 InPlaceUpdateEnvFromMetadata 两个 feature-gate。
- OpenKruise使用案例
实验过程可连续实现,也可以通过删除当前配置,通过01-ok.yaml文件重新部署后再应用新策略(注意副本数和镜像版本)
4.1 部署应用
cat > 01-ok.yaml <<EOF
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
name: nginxweb1
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: nginxweb1
template:
metadata:
labels:
app: nginxweb1
spec:
containers:
- name: nginx
image: nginx:1.20
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
EOF
[root@master01 ~]# kubectl apply -f 01-ok.yaml

[root@master01 ~]# kubectl get clonesets
NAME DESIRED UPDATED UPDATED_READY READY TOTAL AGE
nginxweb1 3 3 3 3 3 6m45s
[root@master01 ~]# kubectl get all
NAME READY STATUS RESTARTS AGE
pod/nginxweb1-4f7kc 1/1 Running 0 8m39s
pod/nginxweb1-7grxd 1/1 Running 0 8m39s
pod/nginxweb1-pnbgd 1/1 Running 0 8m39s

创建成功之后通过 kubectl get all命令查看对应的信息,可以发现cloneset- controller 是直接创建的 Pod,而原生的Deployment 是通过 ReplicaSet 去创建的 Pod
4.2 应用扩容
[root@master01 ~]# cat > 02-ok.yaml <<EOF
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
name: nginxweb1
namespace: default
spec:
minReadySeconds: 30
scaleStrategy:
maxUnavailable: 1
replicas: 5
selector:
matchLabels:
app: nginxweb1
template:
metadata:
labels:
app: nginxweb1
spec:
containers:
- name: nginx
image: nginx:1.20
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
EOF
注:
minReadySeconds: 30 创建了一个pod之后30s才会创建第二个
maxUnavailable:1 在滚动更新过程中最多不可用的pod数量
[root@master01 ~]# kubectl apply -f 02-ok.yaml

[root@master01 ~]# watch kubectl get pods
NAME READY STATUS RESTARTS AGE
nginxweb1-7qh8s 1/1 Running 0 2m8s
nginxweb1-c2n2c 1/1 Running 0 3m12s
nginxweb1-vqfwn 1/1 Running 0 96s
nginxweb1-w8w2v 1/1 Running 0 64s
nginxweb1-zlklg 1/1 Running 0 2m40s

[root@master01 ~]# kubectl get cloneset
NAME DESIRED UPDATED UPDATED_READY READY TOTAL AGE
nginxweb1 5 5 5 5 5 4m1s

kubectl get pods
NAME READY STATUS RESTARTS AGE
nginxweb1-7qh8s 1/1 Running 0 5m35s
nginxweb1-c2n2c 1/1 Running 0 6m39s
nginxweb1-vqfwn 1/1 Running 0 5m3s
nginxweb1-w8w2v 1/1 Running 0 4m31s
nginxweb1-zlklg 1/1 Running 0 6m7s

4.3 应用缩容
cat > 03-ok.yaml <<EOF
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
name: nginxweb1
namespace: default
spec:
minReadySeconds: 30
scaleStrategy:
maxUnavailable: 1
podsToDelete:
- nginxweb1-57j78 #可指定pod(多个pod写多行“- pod名字”)
replicas: 4
selector:
matchLabels:
app: nginxweb1
template:
metadata:
labels:
app: nginxweb1
spec:
containers:
- name: nginx
image: nginx:1.20
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
EOF
缩容时, CloneSet可以指定一些pod删除,而 StatefulSet 或者 Deployment 做不到:
StatefulSet 是根据序号来删除 Pod,而 Deployment/ReplicaSet 目前只能根据控制器里定义的排序来删除。
而 CloneSet 允许用户在缩小 replicas 数量的同时,指定想要删除的 Pod 名字。
如果只是把name加入podsToDelete,而没有修改replicas的话,删完之后会再扩一个pod
kubectl apply -f 03-ok.yaml

kubectl get pods
NAME READY STATUS RESTARTS AGE
nginxweb1-c2n2c 1/1 Running 0 8m7s
nginxweb1-p22fw 1/1 Running 0 46s
nginxweb1-vqfwn 1/1 Running 0 6m31s
nginxweb1-zlklg 1/1 Running 0 7m35s

如果升级kruise,需先删除旧实例,重新安装
先查看一下,先删除:
[root@master01 ~]# kubectl get cloneset
NAME DESIRED UPDATED UPDATED_READY UPDATED_AVAILABLE READY TOTAL AGE
nginxweb1 4 4 4 4 4 4 7m55s
然后删除:
[root@master01 ~]# kubectl delete cloneset nginxweb1
cloneset.apps.kruise.io "nginxweb1" deleted
[root@master01 ~]#

然后在删除kruise
helm uninstall kruise

重新安装
这是有vpn的语句重新生成
helm install kruise openkruise/kruise --version 1.8.0 --set daemon.socketLocation=/var/run --set daemon.socketFile=cri-dockerd.sock --set featureGates="InPlaceUpdateEnvFromMetadata=true\,PreDownloadImageForInPlaceUpdate=true"
如果是本地安装托包的话直接使用:
helm install kruise kruise-1.8.0.tgz --set daemon.socketLocation=/var/run --set daemon.socketFile=cri-dockerd.sock --set featureGates="InPlaceUpdateEnvFromMetadata=true\,PreDownloadImageForInPlaceUpdate=true"

4.4 原地升级
kubectl exec -it nginxweb1-c2n2c -- nginx -v
nginx version: nginx/1.20.2
cat > 04-ok.yaml <<EOF
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
name: nginxweb1
namespace: default
spec:
minReadySeconds: 30
updateStrategy: # 添加更新策略
type: InPlaceIfPossible
scaleStrategy:
maxUnavailable: 1
replicas: 5
selector:
matchLabels:
app: nginxweb1
template:
metadata:
labels:
app: nginxweb1
spec:
containers:
- name: nginx
image: nginx:latest # 更换镜像版本
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
EOF
[root@master01 ~]# kubectl apply -f 04-ok.yaml

更新过程
[root@master01 ~]# watch kubectl get pods

[root@master01 ~]# kubectl exec -it nginxweb1-4ghsr -- nginx -v
nginx version: nginx/1.27.4

4.5 灰度更新
通过灰度更新可以更新部分pod
cat > 05-ok.yaml <<EOF
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
name: nginxweb1
namespace: default
spec:
minReadySeconds: 30
updateStrategy: # 添加更新策略
type: InPlaceIfPossible
partition: 2 # 保留旧版本pod数量
scaleStrategy:
maxUnavailable: 1
replicas: 4
selector:
matchLabels:
app: nginxweb1
template:
metadata:
labels:
app: nginxweb1
spec:
containers:
- name: nginx
image: nginx:1.20 # 更换镜像版本
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
EOF
[root@master01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginxweb1-92mtx 1/1 Running 0 110s
nginxweb1-kltdh 1/1 Running 0 78s
nginxweb1-pz4ff 1/1 Running 0 2m22s
nginxweb1-whd9h 1/1 Running 0 2m54s

kubectl apply -f 05-ok.yaml

watch kubectl get pods
NAME READY STATUS RESTARTS AGE
nginxweb1-92mtx 1/1 Running 1 (3m34s ago) 15m
nginxweb1-kltdh 1/1 Running 1 (4m6s ago) 15m
nginxweb1-pz4ff 1/1 Running 0 16m
nginxweb1-whd9h 1/1 Running 0 16m

[root@master01 ~]# kubectl exec -it nginxweb1-2fkvg -- nginx -v

[root@master01 ~]# kubectl exec -it nginxweb1-4ghsr -- nginx -v
nginx version: nginx/1.21.5

[root@master01 ~]# kubectl exec -it nginxweb1-cnr25f -- nginx -v
nginx version: nginx/1.20.2

[root@master01 ~]# kubectl exec -it nginxweb1-w6k58 -- nginx -v
nginx version: nginx/1.20.2

我们会发现只更新了2个pod,还有2个pod没有更新。
更多推荐

所有评论(0)