滚动更新
概念:
将一个集群中正在运行的多个 Pod 版本,交替地逐一升级的过程,就是"滚动更新"。
实验:
[root@kub-k8s-master prome]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
dep01 2/2 2 2 4h41m
nginx-deployment 2/2 2 2 5h13m
我们将nginx-deploument的副本数量变成4个,现在2个
[root@kub-k8s-master prome]# vim deployment.yaml #修改如下内容
将replicas: 2
修改为:
replicas: 4
创建上节儿的:nginx-deployment
[root@kub-k8s-master prome]# kubectl apply -f deployment.yaml --record
deployment.apps/nginx-deployment configured
--record 记录下每次操作所执行的命令,以方便后面查看
检查nginx-deployment 创建后的状态信息:
[root@kub-k8s-master prome]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
dep01 2/2 2 2 4h53m
nginx-deployment 4/4 4 4 5h25m
返回结果中四个状态字段含义:
DESIRED:
如果有就表示用户期望的 Pod 副本个数(spec.replicas 的值);
CURRENT:
当前处于 Running 状态的 Pod 的个数;
UP-TO-DATE:
当前处于最新版本的 Pod 的个数,所谓最新版本指的是 Pod 的 Spec 部分与 Deployment 里 Pod 模板里定义的完全一致;
AVAILABLE:
当前已经可用的 Pod 的个数,即:既是 Running 状态,又是最新版本,并且已经处于 Ready(健康检查正确)状态的 Pod 的个数。只有这个字段,描述的才是用户所期望的最终状态。
修改 Deployment:
[root@kub-k8s-master prome]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
dep01 2/2 2 2 4h59m
nginx-deployment 4/4 4 4 5h32m
将dep01的副本将2变为3个
[root@kub-k8s-master prome]# kubectl edit deployment/dep01
# reopened with the relevant failures.
#
apiVersion: apps/v1
...
spec:
progressDeadlineSeconds: 600
replicas: 3 #将这里原来的2改为3
revisionHistoryLimit: 10
selector:
matchLabels:
...
保存退出,vim的方式
[root@kub-k8s-master prome]# kubectl edit deployment/dep01
deployment.apps/dep01 edited
[root@kub-k8s-master prome]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
dep01 3/3 3 3 5h16m
nginx-deployment 4/4 4 4 5h48m
进行版本的升级
创建一个新的deploy
[root@kub-k8s-master prome]# cp nginx-depl.yml nginx-depl02.yml
[root@kub-k8s-master prome]# vim nginx-depl02.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep02 #注意修改
spec:
selector:
matchLabels:
app: web1
replicas: 2
template:
metadata:
name: testnginx9
labels:
app: web1
spec:
containers:
- name: testnginx9
image: daocloud.io/library/nginx:1.14 #注意修改
ports:
- containerPort: 80
[root@kub-k8s-master prome]# kubectl apply -f nginx-depl02.yml
deployment.apps/dep02 created
[root@kub-k8s-master prome]# kubectl get pods
NAME READY STATUS RESTARTS AGE
dep01-58f6d4d4cb-997jw 1/1 Running 0 16m
dep01-58f6d4d4cb-g6vtg 1/1 Running 0 5h32m
dep01-58f6d4d4cb-k6z47 1/1 Running 0 5h32m
dep02-78dbd944fc-47czr 1/1 Running 0 44s
dep02-78dbd944fc-4snsj 1/1 Running 0 25s
将nginx的版本从1.14升级到1.16
[root@kub-k8s-master prome]# kubectl edit deployment/dep02
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
...
spec:
containers:
- image: daocloud.io/library/nginx:1.16 #将这里原来的nginx:1.14修改为nginx:1.16
imagePullPolicy: Always
name: testnginx9
ports:
- containerPort: 80
...
保存退出,vim的方式
[root@kub-k8s-master prome]# kubectl edit deployment/dep01
deployment.apps/dep01 edited
这时可以通过查看 Deployment 的 Events,看到这个"滚动更新"的流程:
[root@kub-k8s-master prome]# kubectl describe deployment dep02
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 50s deployment-controller Scaled up replica set dep02-846bf8775b to 2
Normal ScalingReplicaSet 9s deployment-controller Scaled up replica set dep02-58f8d5678 to 1
Normal ScalingReplicaSet 8s deployment-controller Scaled down replica set dep02-846bf8775b to 1
Normal ScalingReplicaSet 8s deployment-controller Scaled up replica set dep02-58f8d5678 to 2
Normal ScalingReplicaSet 5s deployment-controller Scaled down replica set dep02-846bf8775b to 0
如此交替进行,新 ReplicaSet 管理的 Pod 副本数,从 0 个变成 1 个,再变成 2 个,最后变成 3 个。而旧的 ReplicaSet 管理的 Pod 副本数则从 3 个变成 2 个,再变成 1 个,最后变成 0 个。这样,就完成了这一组 Pod 的版本升级过程。
验证
[root@kub-k8s-master prome]# kubectl get pods
NAME READY STATUS RESTARTS AGE
dep02-78dbd944fc-69t8x 1/1 Running 0 11h
dep02-78dbd944fc-7cn86 1/1 Running 0 11h
[root@kub-k8s-master prome]# kubectl exec -it dep02-78dbd944fc-69t8x /bin/bash
root@dep02-78dbd944fc-69t8x:/# nginx -v
nginx version: nginx/1.16.1
root@dep02-78dbd944fc-69t8x:/# exit
"滚动更新"的好处:
在升级刚开始的时候,集群里只有 1 个新版本的 Pod。如果这时,新版本 Pod 有问题启动不起来,那么"滚动更新"就会停止,从而允许开发和运维人员介入。而在这个过程中,由于应用本身还有两个旧版本的 Pod 在线,所以服务并不会受到太大的影响。
版本回滚
查看版本历史
[root@kub-k8s-master prome]# kubectl rollout history deployment/dep02
deployment.apps/dep02
REVISION CHANGE-CAUSE
1 <none>
2 <none>
回滚到以前的旧版本:
把整个 Deployment 回滚到上一个版本:
[root@kub-k8s-master prome]# kubectl rollout undo deployment/dep02
deployment.apps/dep02 rolled back
查看回滚状态
[root@kub-k8s-master prome]# kubectl rollout status deployment/dep02
deployment "dep02" successfully rolled out
验证:
[root@kub-k8s-master prome]# kubectl get pods
NAME READY STATUS RESTARTS AGE
dep02-8594cd6447-pqtxk 1/1 Running 0 55s
dep02-8594cd6447-tt4h4 1/1 Running 0 51s
[root@kub-k8s-master prome]# kubectl exec -it dep02-8594cd6447-tt4h4 /bin/bash
root@dep02-8594cd6447-tt4h4:/# nginx -v
nginx version: nginx/1.14.2
回滚到更早之前的版本:
- 使用 kubectl rollout history 命令查看每次 Deployment 变更对应的版本。
[root@kub-k8s-master prome]# kubectl rollout history deployment/dep02
deployment.apps/dep02
REVISION CHANGE-CAUSE
2 <none>
3 <none>
由于在创建这个 Deployment 的时候,指定了--record 参数,所以创建这些版本时执行的 kubectl 命令,都会被记录下来。
查看每个版本对应的 Deployment 的 API 对象的细节:
[root@kub-k8s-master prome]# kubectl rollout history deployment/dep02 --revision=3
deployment.apps/dep02 with revision #3
Pod Template:
Labels: app=web1
pod-template-hash=8594cd6447
Containers:
testnginx9:
Image: daocloud.io/library/nginx:1.14
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
2.在 kubectl rollout undo 命令行最后,加上要回滚到的指定版本的版本号,就可以回滚到指定版本了。
[root@kub-k8s-master prome]# kubectl rollout undo deployment/dep02 --to-revision=2
deployment.apps/dep02 rolled back
验证:
[root@kub-k8s-master prome]# kubectl get pods
NAME READY STATUS RESTARTS AGE
dep02-78dbd944fc-8nvxl 1/1 Running 0 86s
dep02-78dbd944fc-sb9sj 1/1 Running 0 88s
[root@kub-k8s-master prome]# kubectl exec -it dep02-78dbd944fc-8nvxl /bin/bash
root@dep02-78dbd944fc-8nvxl:/# nginx -v
nginx version: nginx/1.16.1