1.修改 deployment 模板。
这里将原本镜像是: nginx:latest
的版本,修改为:nginx:alpine
。
kubectl edit deploy/nginx-deployment
2.通过查看 Deployment 的 Events,看到这个“滚动更新”的流程:
- 第二条 Events:Deployment 首先创建了一个新的 ReplicaSet (nginx-deployment-86d5bf894b),初始 Pod 副本数为:0。
- 第三条 Events:缩放 ReplicaSet 控制器 nginx-deployment-54fdb8fb59 从 3 缩小到 2。
- 第四条 Events:缩放 ReplicaSet 控制器 nginx-deployment-86d5bf894b 从1 放大到 2。
- 第五条 Events:缩放 ReplicaSet 控制器 nginx-deployment-54fdb8fb59 从 2 缩小到 1。
- 第六条 Events:缩放 ReplicaSet 控制器 nginx-deployment-86d5bf894b 从 2 放大到 3。
- 第七条 Events:缩放 ReplicaSet 控制器 nginx-deployment-54fdb8fb59 从1 缩小到 0。
像这样,交替逐一升级的过程,就是 “滚动更新”。这个过程保证了用户的体验,因为在升级的过程中,只有当新版本的运行成功之后旧版本才会删除,所以这个过程始终都会有服务提供给用户。
[root@master01 ~]# kubectl describe deploy/nginx-deployment ... ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 55m deployment-controller Scaled up replica set nginx-deployment-54fdb8fb59 to 3 Normal ScalingReplicaSet 32m deployment-controller Scaled up replica set nginx-deployment-86d5bf894b to 1 Normal ScalingReplicaSet 31m deployment-controller Scaled down replica set nginx-deployment-54fdb8fb59 to 2 from 3 Normal ScalingReplicaSet 31m deployment-controller Scaled up replica set nginx-deployment-86d5bf894b to 2 from 1 Normal ScalingReplicaSet 31m deployment-controller Scaled down replica set nginx-deployment-54fdb8fb59 to 1 from 2 Normal ScalingReplicaSet 31m deployment-controller Scaled up replica set nginx-deployment-86d5bf894b to 3 from 2 Normal ScalingReplicaSet 31m deployment-controller Scaled down replica set nginx-deployment-54fdb8fb59 to 0 from 1
3.再次查看 ReplicaSet:
- 这里,可以看到有两个 ReplicaSet,一个新创建的,一个旧的。旧的 ReplicaSet 还存在的意义就是为了保证,切换为之前的版本,“回滚” 的操作。
[root@master01 yaml]# kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-54fdb8fb59 0 0 0 25m nginx-deployment-86d5bf894b 3 3 3 2m13s
综上所述,再来看看此时 Deployment、ReplicaSet 和 Pod 的关系图(黄色代表旧 Pod,绿色代表新 Pod,目前状态是 新 Pod 只更新了一个):
- 通过图我们了解到,Deployment 可以控制 ReplicaSet 的数量,以及每个 ReplicaSet 的属性;
- 而一个应用的版本,对应的是一个 ReplicaSet。
四、回滚
首先,我们使用 kubectl set image
的指令,直接修改 nginx-deployment 所使用的镜像。这个命令的好处就是,你可以不用像 kubectl edit 那样需要打开编辑器。
这次,我们把镜像改为一个不存在的镜像,如改为 nginx:1.111,这个 Deployment 就会出现一个升级失败的版本(nginx-deployment-746bd689d9)。
1.修改 Deployment 的 image 版本:
[root@master01 ~]# kubectl get deploy -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR nginx-deployment 3/3 3 3 126m nginx-web nginx:alpine app=nginx [root@master01 ~]# [root@master01 ~]# kubectl set image deploy/nginx-deployment nginx-web=nginx:1.111 deployment.apps/nginx-deployment image updated
2.查看 RplicaSet 情况:
- nginx-deployment-746bd689d9 控制器,可以看到 READY 状态的个数为:0
[root@master01 ~]# kubectl get deploy NAME READY UP-TO-DATE AVAILABLE AGE nginx-deployment 3/3 1 3 127m [root@master01 ~]# [root@master01 ~]# kubectl get rs #746bd689d9 NAME DESIRED CURRENT READY AGE nginx-deployment-54fdb8fb59 0 0 0 127m nginx-deployment-746bd689d9 1 1 0 20s nginx-deployment-86d5bf894b 3 3 3 104m
查看 Pod,可以看到不正常状态的 Pod。这是因为 “滚动更新” 被触发后,报错会立刻停止。
[root@master01 ~]# kubectl get pod NAME READY STATUS RESTARTS AGE nginx-deployment-746bd689d9-qcsxf 0/1 ImagePullBackOff 0 34m nginx-deployment-86d5bf894b-fzcd7 1/1 Running 0 138m nginx-deployment-86d5bf894b-hc28d 1/1 Running 0 138m nginx-deployment-86d5bf894b-vfkxg 1/1 Running 0 138m
回滚到上一个版本
执行一条 kubectl rollout undo 命令,就能把整个 Deployment 回滚到上一个版本:
kubectl rollout undo deployment/nginx-deployment
查看 RplicaSet
[root@master01 ~]# kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-54fdb8fb59 0 0 0 170m nginx-deployment-746bd689d9 0 0 0 43m nginx-deployment-86d5bf894b 3 3 3 147m
回滚到更早之前版本
如果我想回滚到更早之前的版本,要怎么办呢?
1.首先,使用 kubectl rollout history
命令,查看每次 Deployment 变更对应的版本。
- 我们的的操作从最开始依次顺序的记录在了这里,那次失败的更新操作,则对应的是版本 3,因为在这之前执行了回滚的命令。
[root@master01 ~]# kubectl rollout history deployment/nginx-deployment deployment.apps/nginx-deployment REVISION CHANGE-CAUSE 1 kubectl create --filename=deploy-web.yaml --record=true 3 kubectl create --filename=deploy-web.yaml --record=true 4 kubectl create --filename=deploy-web.yaml --record=true
2.查看对应版本细节。
通过 --revision=3
参数加上对应的步骤版本,就可以查看细节,如:
[root@master01 ~]# kubectl rollout history deployment/nginx-deployment --revision=3 deployment.apps/nginx-deployment with revision #3 Pod Template: Labels: app=nginx pod-template-hash=746bd689d9 Annotations: kubernetes.io/change-cause: kubectl create --filename=deploy-web.yaml --record=true Containers: nginx-web: Image: nginx:1.111 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none>
3.回滚到指定版本。
通过 kubectl rollout undo
命令,加上 --to-revision=2
要回滚到的指定版本的版本号,就可以回到指定版本了。
[root@master01 ~]# kubectl rollout undo deployment/nginx-deployment --to-revision=1 deployment.apps/nginx-deployment rolled back [root@master01 ~]#
回到指定版本后,可以看到 RplicaSet 控制器也就发生了变化,一个 RplicaSet 对应一个版本。
[root@master01 ~]# kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-54fdb8fb59 3 3 3 3h5m nginx-deployment-746bd689d9 0 0 0 57m nginx-deployment-86d5bf894b 0 0 0 162m
删除多余的 RplicaSet
不过,Deployment 进行的每一次更新操作,都会生成一个新的 ReplicaSet 对象,是不是有些多余,甚至浪费资源呢?
- 我们在确定了,不需要某个版本之后就可以将其删除。
[root@master01 ~]# kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-54fdb8fb59 3 3 3 3h12m nginx-deployment-746bd689d9 0 0 0 65m nginx-deployment-86d5bf894b 0 0 0 169m [root@master01 ~]# kubectl delete rs/nginx-deployment-746bd689d9 replicaset.apps "nginx-deployment-746bd689d9" deleted [root@master01 ~]# kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-54fdb8fb59 3 3 3 3h12m nginx-deployment-86d5bf894b 0 0 0 169m
除了删除之外
- Kubernetes 项目还提供了一个指令,使得我们对 Deployment 的多次更新操作,最后 只生成一个 ReplicaSet。
- 具体的做法是,在更新 Deployment 前,你要先执行一条
kubectl rollout pause
指令。
步骤如下:
- 1.让 Deployment 进入了 “暂停” 状态。
[root@master01 ~]# kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-54fdb8fb59 3 3 3 3h12m nginx-deployment-86d5bf894b 0 0 0 169m [root@master01 ~]# kubectl rollout pause deployment/nginx-deployment deployment.apps/nginx-deployment paused
- 2.修改 Image 镜像版本。
[root@master01 ~]# kubectl set image deploy/nginx-deployment nginx-web=nginx:alpine deployment.apps/nginx-deployment image updated [root@master01 ~]# [root@master01 ~]# kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-54fdb8fb59 3 3 3 3h46m nginx-deployment-86d5bf894b 0 0 0 3h22m
- 3.“恢复” Deployment
[root@master01 ~]# kubectl rollout resume deployment/nginx-deployment deployment.apps/nginx-deployment resumed [root@master01 ~]# kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-54fdb8fb59 0 0 0 3h46m nginx-deployment-86d5bf894b 3 3 3 3h23m
如果,你将 spec.revisionHistoryLimit
字段设置为:0;那么,你就不能做回滚操作了。
总结
今天讲解了,Deploymen 最基本的编排控制器的实现原理和使用方法。
分别说明了,水平扩展/收缩、滚动更新、回滚的机制实现。
最后:技术交流、博客互助,点击下方或主页推广加入哦!!