Deployment概述
Kubernetes 中的一个控制器模式,最常用于部署无状态服务的方式。Deployment 控制器实际操纵的是 ReplicaSet对象,而不是 Pod 对象。 保证系统中的Pod数量永远在期望状态
ReplicaSet 确保在任何给定时间运行指定数量的 pod 副本。然而,Deployment 是一个更高级别的概念,它管理 ReplicaSet 并为 Pod 提供声明性更新以及许多其他有用的功能。学习这篇文章首先需要了解Pod
使用场景
- 创建Deployment
- 滚动升级和回滚操作
- 检测状态
- 扩缩容
- 清理策略
创建Deployment
下面的 yaml 文件定义了一个 Deployment,该 Deployment 将创建一个有 3 个 nginx Pod 副本的 ReplicaSet(副本集)
这个Deployment是由控制器的定义以及被控制对象的模板定义而组成的
我们回过头在了解一下ReplicaSet对象,它的结构非常简单,和Deployment相似。
我们可以看到,一个 ReplicaSet 对象,其实就是由副本数目的定义和一个 Pod 模板组成的。更重要的是,Deployment 控制器实际操纵的,正是这样的 ReplicaSet 对象,而不是 Pod 对象。
让我们创建 Deployment 对象并查看。
[root@ycloud ~]# kubectl apply -f deployment.yaml
deployment.apps/nginx-deployment created
[root@ycloud ~]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 54s
- READY:第一个3是当前状态的Running的Pod个数,第二个3是用户期望的Pod副本个数(.spec.replicas)
- UP-TO-DATE: 当前处于最新版本的 Pod 的个数
- AVVILABLE: 当前已经可用的 Pod 的个数
下面这张图就能很好体现,Deployment、Pod、ReplicaSet三者的关系
滚动升级和回滚操作
1.滚动升级
当 Deployment Pod 模板(即 .spec.template
)发生改变时,例如模板的标签或容器镜像被更新, 才会触发 Deployment 上线。其他更新(如对 Deployment 执行扩缩容的操作)不会触发上线动作。
1>使用 set image 命令更新Pod,使用 nginx:1.7.9 镜像,--record 可以记录每次控制器变化
[root@ycloud ~]# kubectl set image deployment/nginx-deployment nginx=nginx:1.7.9 --record
deployment.apps/nginx-deployment image updated
–record 参数。它的作用,是记录下你每次操作所执行的命令,以方便后面查看。
2>或者直接通过 edit 编辑资源清单
[root@ycloud ycloud]# kubectl edit deployment/nginx-deployment
·····
spec:
containers:
- image: nginx:latest -----> 修改成nginx:1.7.9
imagePullPolicy: Always
name: nginx
······
Kubernetes 为我们提供了一条指令,让我们可以实时查看 Deployment 对象的状态
变化。
[root@ycloud ~]# kubectl rollout status deployment/nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "nginx-deployment" successfully rolled out
“0 out of 3 new replicas have been updated”意味着还没有 Pod 进入了 UP-TO-DATE 状态。 返回”successfully rolled out“表示都创建成功。
也可以通过Deployment 的 Event,看到 “滚动更新” 的流程:
[root@ycloud ~]# kubectl describe deployment nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Sun, 02 Oct 2022 23:28:23 +0800
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 2
Selector: app=nginx
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
·········
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 3m2s deployment-controller Scaled up replica set nginx-deployment-585449566 to 3
Normal ScalingReplicaSet 111s deployment-controller Scaled up replica set nginx-deployment-56db85c5db to 1
Normal ScalingReplicaSet 86s deployment-controller Scaled down replica set nginx-deployment-585449566 to 2
Normal ScalingReplicaSet 86s deployment-controller Scaled up replica set nginx-deployment-56db85c5db to 2
Normal ScalingReplicaSet 61s deployment-controller Scaled down replica set nginx-deployment-585449566 to 1
Normal ScalingReplicaSet 61s deployment-controller Scaled up replica set nginx-deployment-56db85c5db to 3
Normal ScalingReplicaSet 37s deployment-controller Scaled down replica set nginx-deployment-585449566 to 0
"Scaled up replica set nginx-deployment-56db85c5db to 3",可以看到,当我们修改Pod模板中的镜像时,Deployment-controller 控制器会根据修改的 Pod模板,创建一个新的ReplicaSet(nginx-deployment-56db85c5db )
像Events中记录的这中,当一个新Pod运行成功,就会down掉一个旧的Pod,来保证系统中的Pod数量永远在期望状态
,这种交替更新的过程就叫滚动更新
有人问了为什么要一个一个,不能多个同时更新呢,这里Deployment控制器有一个“滚动更新策略”,叫 RollingUpdateStrategy ,在Deployment描述信息我们就可以看到这个字段, 默认情况下,它确保至少所需 Pod 的 75% 处于运行状态(最大不可用比例为 25%)。 当副本数为4时,Pod的个数就会介于3~5之间。
通过滚动更新实践,可以扩展出Deployment、Pod、ReplicaSet三者的关系
2.回滚操作
查看 ReplicaSet 对象,查看其更新之后的状态
[root@sztcyl-177-9-244 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-56db85c5db 3 3 3 29m
nginx-deployment-585449566 0 0 0 30m
这次我们把镜像名字修改成为了一个错误的名字,比如:nginx:1.79。这样,这个 Deployment 就会出现一个升级失败的版本。这种情况Deployment会进入反复崩溃状态。
[root@ycloud ~]# kubectl set image deploy/nginx-deployment nginx=nginx:1.79 --record
deployment.apps/nginx-deployment image updated
这时,我们再次查看 ReplicaSet 状态
[root@ycloud ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-56db85c5db 3 3 3 36m
nginx-deployment-585449566 0 0 0 37m
nginx-deployment-5c4bcd6994 1 1 0 84s
发现新版本已经停止,这是我们只需要执行一个 kubectl rollout undo 命令,就可以使整个Deployment回滚到上个版本
[root@ycloud ~]# kubectl rollout undo deployment/nginx-deployment
deployment.apps/nginx-deployment rolled back
[root@ycloud ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-56db85c5db 3 3 3 40m
nginx-deployment-585449566 0 0 0 42m
nginx-deployment-5c4bcd6994 0 0 0 5m42s
我们也可以回滚到历史版本,只需在添加 --to-revision=2 这个参数,
[root@sztcyl-177-9-244 ~]# kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
2 kubectl set image deploy/nginx-deployment nginx=nginx:1.7.9 --record=true
3 <none>
4 kubectl set image deploy/nginx-deployment nginx=nginx:1.79 --record=true
[root@sztcyl-177-9-244 ~]# kubectl rollout undo deployment/nginx-deployment --to-revision=2
扩缩容
“水平扩展 / 收缩”非常容易实现,Deployment Controller 只需要修改它所控制的 ReplicaSet 的 Pod 副本个数就可以了。
1.可以通过如下命令实现
[root@sztcyl-177-9-244 ~]# kubectl scale deployment nginx-deployment --replicas=4
deployment.apps/nginx-deployment scaled
2.或者直接通过 edit 编辑资源清单
[root@ycloud ycloud]# kubectl edit deployment/nginx-deployment
·····
spec:
progressDeadlineSeconds: 600
replicas: 4
······
清理策略
可以在 Deployment 中设置 .spec.revisionHistoryLimit
字段以指定保留此 Deployment 的多少个旧有 ReplicaSet。其余的 ReplicaSet 将在后台被垃圾回收。 默认情况下,此值为 10。
如果把它设置为 0,将导致 Deployment 的所有历史记录被清空,你就再也不能做回滚操作了。
结论
Deployment 实际上是一个两层控制器。 Deployment 控制 ReplicaSet(版本),ReplicaSet 控制 Pod(副本数)
参考文献
https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/#canary-deployment