目录
- 概述
- Deployment 的更新原理
- 实验
概述
Kubernetes 中,Deployment 控制器是用于管理应用程序生命周期的核心对象。Deployment 通过管理 ReplicaSet 来间接控制 Pod,确保在任何时刻都能维持指定数量的 Pod 副本。这种间接管理使得 Deployment 功能比 ReplicaSet 更加强大,可以支持如滚动更新、回滚等。
Deployment 的主要功能包括:
- 自动部署和滚动更新:支持对应用的无缝更新,保证在更新过程中系统的高可用性。
- 回滚:允许用户回退到之前的版本,确保在部署过程中出现问题时可以迅速恢复。
- 自愈能力:自动检测和修复 Pod 的故障,确保指定数量的 Pod 始终运行。
- 版本控制:Deployment 能够跟踪应用的历史版本,便于管理和查看不同版本的差异。
Deployment 的资源清单:
apiVersion: apps/v1 # 版本号
kind: Deployment # 类型
metadata: # 元数据 name: nginx-deployment # Deployment名称 namespace: default # 所属命名空间 labels: # 标签 controller: deploy
spec: # 详情描述 replicas: 3 # 副本数量 revisionHistoryLimit: 3 # 保留历史版本,默认为10 paused: false # 暂停部署,默认是false progressDeadlineSeconds: 600 # 部署超时时间(秒),默认是600 strategy: # 策略 type: RollingUpdate # 滚动更新策略 rollingUpdate: # 滚动更新设置 maxSurge: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数 maxUnavailable: 30% # 最大不可用状态的 Pod 的最大值,可以为百分比,也可以为整数 selector: # 选择器,通过它指定该控制器管理哪些 Pod matchLabels: # Labels匹配规则 app: nginx-pod matchExpressions: # Expressions匹配规则 - {key: app, operator: In, values: [nginx-pod]} template: # 模板,当副本数量不足时,会根据下面的模板创建 Pod 副本 metadata: labels: app: nginx-pod spec: containers: - name: nginx image: nginx:1.15 # 镜像版本可以根据需要调整,确保是有效的版本ports: - containerPort: 80 # 对外暴露的端口号
Deployment 的更新原理
-
触发更新的条件:仅当 Deployment 的 Pod 模板(
spec.template
)发生变化时(例如容器镜像更新、标签变更等),才会触发更新操作。其他变动,如扩缩容操作,并不会导致更新触发(创建新的 ReplicaSet)。 -
更新过程:
- 创建新的 ReplicaSet:当 Deployment 的模板发生变化时,Kubernetes 会创建一个新的 ReplicaSet。
- 准备就绪后替换旧 ReplicaSet:新的 ReplicaSet 准备就绪后,Kubernetes 会逐步替换旧的 ReplicaSet,但不会立即删除它。旧的 ReplicaSet 会根据
revisionHistoryLimit
的设置保留指定数量的版本,以便进行回滚操作。
此机制确保了应用更新时的平滑过渡,不会影响系统的稳定性。
实验
kubectl create deployment nginx --image=nginx --dry-run=client -o yaml>nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginxname: nginx
spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- image: nginx:1.15name: nginx
kubectl expose deployment nginx --target-port=80 --port=80 --type=NodePort
浏览器访问地址加端口
nginx版本1.15.12
滚动升级:
Kubectl edit deployment nginx
kubectl set image deployment/web web=nginx:1.18 --record 可以保留记录,回滚时方便识别
更新后,有两个rs
[root@k8s-master ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-54f8f9f495 3 3 3 22m
nginx-6f68f97d6b 0 0 0 3h19m
[root@k8s-master ~]# kubectl describe rs nginx-54f8f9f495 |grep -A 5 Event
Events:Type Reason Age From Message---- ------ ---- ---- -------Normal SuccessfulCreate 25m replicaset-controller Created pod: nginx-54f8f9f495-jnbv2Normal SuccessfulCreate 25m replicaset-controller Created pod: nginx-54f8f9f495-g9tttNormal SuccessfulCreate 25m replicaset-controller Created pod: nginx-54f8f9f495-cc4vf
[root@k8s-master ~]# kubectl describe rs nginx-6f68f97d6b |grep -A 5 Event
Events:Type Reason Age From Message---- ------ ---- ---- -------Normal SuccessfulDelete 26m replicaset-controller Deleted pod: nginx-6f68f97d6b-t2h4xNormal SuccessfulDelete 26m replicaset-controller Deleted pod: nginx-6f68f97d6b-6rnc4Normal SuccessfulDelete 26m replicaset-controller Deleted pod: nginx-6f68f97d6b-52qsq
可以看到旧的rs删除了三个pod,新的rs创建了三个pod。
Describe nginx看看是为什么?
[root@k8s-master ~]# kubectl describe deploy nginx |grep -A 10 Event
Events:Type Reason Age From Message---- ------ ---- ---- -------Normal ScalingReplicaSet 29m deployment-controller Scaled up replica set nginx-54f8f9f495 to 1Normal ScalingReplicaSet 28m deployment-controller Scaled down replica set nginx-6f68f97d6b to 2 from 3Normal ScalingReplicaSet 28m deployment-controller Scaled up replica set nginx-54f8f9f495 to 2 from 1Normal ScalingReplicaSet 28m deployment-controller Scaled down replica set nginx-6f68f97d6b to 1 from 2Normal ScalingReplicaSet 28m deployment-controller Scaled up replica set nginx-54f8f9f495 to 3 from 2Normal ScalingReplicaSet 28m deployment-controller Scaled down replica set nginx-6f68f97d6b to 0 from 1
结果发现两个rs交替删除创建,使得deployment滚动更新
回滚:
rs保留了镜像版本
查看历史版本
[root@k8s-master ~]# kubectl rollout history deployment nginx
deployment.apps/nginx
REVISION CHANGE-CAUSE
1 <none>。 #1.15
2 <none>。#当前版本1.16
回滚到上个版本:
kubectl rollout undo deployment nginx
回滚后可以看到1.15版本的rs创建了3个pod
[root@k8s-master ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-54f8f9f495 0 0 0 57m
nginx-6f68f97d6b 3 3 3 3h55m
[root@k8s-master ~]# kubectl describe rs nginx-6f68f97d6b |grep -A 10 Event
Events:Type Reason Age From Message---- ------ ---- ---- -------Normal SuccessfulDelete 60m replicaset-controller Deleted pod: nginx-6f68f97d6b-t2h4xNormal SuccessfulDelete 60m replicaset-controller Deleted pod: nginx-6f68f97d6b-6rnc4Normal SuccessfulDelete 59m replicaset-controller Deleted pod: nginx-6f68f97d6b-52qsqNormal SuccessfulCreate 4m29s replicaset-controller Created pod: nginx-6f68f97d6b-k95xzNormal SuccessfulCreate 4m28s replicaset-controller Created pod: nginx-6f68f97d6b-mdgtwNormal SuccessfulCreate 4m27s replicaset-controller Created pod: nginx-6f68f97d6b-dzfpn
回滚其实用的很少,一般都是直接改镜像,重新apply,一些厂商也是直接调接口“apply”镜像就好