目录
概述
Kubernetes 中,Deployment 控制器是用于管理应用程序生命周期的核心对象。Deployment 通过管理 ReplicaSet 来间接控制 Pod,确保在任何时刻都能维持指定数量的 Pod 副本。这种间接管理使得 Deployment 功能比 ReplicaSet 更加强大,可以支持如滚动更新、回滚等。
Deployment 的主要功能包括:
- 自动部署和滚动更新:支持对应用的无缝更新,保证在更新过程中系统的高可用性。
- 回滚:允许用户回退到之前的版本,确保在部署过程中出现问题时可以迅速恢复。
- 自愈能力:自动检测和修复 Pod 的故障,确保指定数量的 Pod 始终运行。
- 版本控制:Deployment 能够跟踪应用的历史版本,便于管理和查看不同版本的差异。
Deployment 的资源清单:
yaml
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
的设置保留指定数量的版本,以便进行回滚操作。
此机制确保了应用更新时的平滑过渡,不会影响系统的稳定性。
实验
bash
kubectl create deployment nginx --image=nginx --dry-run=client -o yaml>nginx.yaml
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:1.15
name: 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
bash
[root@k8s-master ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-54f8f9f495 3 3 3 22m
nginx-6f68f97d6b 0 0 0 3h19m
bash
[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-jnbv2
Normal SuccessfulCreate 25m replicaset-controller Created pod: nginx-54f8f9f495-g9ttt
Normal 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-t2h4x
Normal SuccessfulDelete 26m replicaset-controller Deleted pod: nginx-6f68f97d6b-6rnc4
Normal SuccessfulDelete 26m replicaset-controller Deleted pod: nginx-6f68f97d6b-52qsq
可以看到旧的rs删除了三个pod,新的rs创建了三个pod。
Describe nginx看看是为什么?
bash
[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 1
Normal ScalingReplicaSet 28m deployment-controller Scaled down replica set nginx-6f68f97d6b to 2 from 3
Normal ScalingReplicaSet 28m deployment-controller Scaled up replica set nginx-54f8f9f495 to 2 from 1
Normal ScalingReplicaSet 28m deployment-controller Scaled down replica set nginx-6f68f97d6b to 1 from 2
Normal ScalingReplicaSet 28m deployment-controller Scaled up replica set nginx-54f8f9f495 to 3 from 2
Normal ScalingReplicaSet 28m deployment-controller Scaled down replica set nginx-6f68f97d6b to 0 from 1
结果发现两个rs交替删除创建,使得deployment滚动更新
回滚:
rs保留了镜像版本
查看历史版本
bash
[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
bash
[root@k8s-master ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-54f8f9f495 0 0 0 57m
nginx-6f68f97d6b 3 3 3 3h55m
bash
[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-t2h4x
Normal SuccessfulDelete 60m replicaset-controller Deleted pod: nginx-6f68f97d6b-6rnc4
Normal SuccessfulDelete 59m replicaset-controller Deleted pod: nginx-6f68f97d6b-52qsq
Normal SuccessfulCreate 4m29s replicaset-controller Created pod: nginx-6f68f97d6b-k95xz
Normal SuccessfulCreate 4m28s replicaset-controller Created pod: nginx-6f68f97d6b-mdgtw
Normal SuccessfulCreate 4m27s replicaset-controller Created pod: nginx-6f68f97d6b-dzfpn
回滚其实用的很少,一般都是直接改镜像,重新apply,一些厂商也是直接调接口"apply"镜像就好