一、认识Deployment控制器
Deployment控制器为Pod和Replica Set控制器提供声明式的更新;你只需要在Deployment中描述你想要的目标状态是什么,Deployment Controller就会帮你将Pod和Relica Set控制器的实际状态改变到你的目标状态。你也可以定义一个新的Deployment,也可以创建一个新的替换旧的Deployment控制器。
当我们在使用Deployment控制器做滚动更新时,Deployment控制器首先会创建出一个新的ReplicaSet控制器,在新的ReplicaSet控制器上创建出新的Pod;并且通过一定的频率,将老的ReplicaSet控制器上的Pod发送退出信号;但是无论如何更新,老的ReplicaSet控制器上的Pod副本数和新的ReplicaSet副本数必须要满足Deployment控制器所规定的数量;当老的ReplicaSet控制器中的Pod被用户访问完毕时,便会退出;新的用户访问会被调度到新的ReplicaSet控制器下的Pod上。
二、Deployment典型的应用场景如下
- 使用Deployment控制器来创建ReplicaSet,ReplicationSet在后台创建Pod;检查启动状态,看它是成功还是失败。
- 通过更新Deployment控制器中的PodTemplateSpec字段来声明Pod的新状态。这会创建一个新的ReplicationSet,Deployment控制器会按照自己所控制的速率将Pod从旧的ReplicaSet中移动到新的ReplicaSet中。
- 如果当前状态不稳定,回滚到之前的Deployment revision,每次回滚都会更新Deployment的revision。
- 支持动态扩缩容,扩容Deployment控制器以满足更高的负载。
- 暂停Deployment控制器来应用PodTemplateSpec的多个修复,然后恢复上线。
- 根据Deployment控制器的状态来判断上线是否失败了。
- 定时清理不必要的ReplicaSet
三、Deployment使用操作
1)创建Deployment资源
]# cat deploy-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: myapp
release: canary
template:
metadata:
labels:
app: myapp
release: canary
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
]# kubectl apply -f deploy-demo.yaml
deployment.apps/myapp-deploy created
2)查看Deployment资源
]# kubectl get deploy -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
myapp-deploy 3/3 3 3 2m35s myapp ikubernetes/myapp:v1 app=myapp,release=canary
]# kubectl get rs -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
myapp-deploy-65fb6c8459 3 3 3 2m43s myapp ikubernetes/myapp:v1 app=myapp,pod-template-hash=65fb6c8459,release=canary
]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-deploy-65fb6c8459-bkcbj 1/1 Running 0 3m49s 10.244.1.28 node1 <none> <none>
myapp-deploy-65fb6c8459-c44fs 1/1 Running 0 3m49s 10.244.1.27 node1 <none> <none>
myapp-deploy-65fb6c8459-fbbl7 1/1 Running 0 3m49s 10.244.2.10 node2 <none> <none>
3)访问pod资源
]# curl 10.244.1.28
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
]# curl 10.244.1.27
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
]# curl 10.244.2.10
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
4)查看Deoloyment和ReplicaSet的详细信息
]# kubectl describe deployment myapp-deploy
Name: myapp-deploy
Namespace: default
CreationTimestamp: Sun, 26 Jul 2020 13:50:09 +0800
Labels: <none>
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=myapp,release=canary
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=myapp
release=canary
Containers:
myapp:
Image: ikubernetes/myapp:v1
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Progressing True NewReplicaSetAvailable
Available True MinimumReplicasAvailable
OldReplicaSets: <none>
NewReplicaSet: myapp-deploy-65fb6c8459 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 6m21s deployment-controller Scaled up replica set myapp-deploy-65fb6c8459 to 3
]# kubectl describe rs myapp-deploy-65fb6c8459
Name: myapp-deploy-65fb6c8459
Namespace: default
Selector: app=myapp,pod-template-hash=65fb6c8459,release=canary
Labels: app=myapp
pod-template-hash=65fb6c8459
release=canary
Annotations: deployment.kubernetes.io/desired-replicas: 3
deployment.kubernetes.io/max-replicas: 4
deployment.kubernetes.io/revision: 1
Controlled By: Deployment/myapp-deploy
Replicas: 3 current / 3 desired
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: app=myapp
pod-template-hash=65fb6c8459
release=canary
Containers:
myapp:
Image: ikubernetes/myapp:v1
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 8m8s replicaset-controller Created pod: myapp-deploy-65fb6c8459-c44fs
Normal SuccessfulCreate 8m8s replicaset-controller Created pod: myapp-deploy-65fb6c8459-bkcbj
Normal SuccessfulCreate 8m8s replicaset-controller Created pod: myapp-deploy-65fb6c8459-fbbl7
5)动态扩容Pod副本集
]# kubectl patch deployment myapp-deploy -p '{"spec":{"replicas":5}}'
deployment.apps/myapp-deploy patched
]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
myapp-deploy-65fb6c8459-bkcbj 1/1 Running 0 9m21s
myapp-deploy-65fb6c8459-c44fs 1/1 Running 0 9m21s
myapp-deploy-65fb6c8459-fbbl7 1/1 Running 0 9m21s
myapp-deploy-65fb6c8459-2wkfq 0/1 Pending 0 0s
myapp-deploy-65fb6c8459-vtrzk 0/1 Pending 0 0s
myapp-deploy-65fb6c8459-2wkfq 0/1 Pending 0 0s
myapp-deploy-65fb6c8459-vtrzk 0/1 Pending 0 0s
myapp-deploy-65fb6c8459-2wkfq 0/1 ContainerCreating 0 0s
myapp-deploy-65fb6c8459-vtrzk 0/1 ContainerCreating 0 0s
myapp-deploy-65fb6c8459-vtrzk 1/1 Running 0 2s
myapp-deploy-65fb6c8459-2wkfq 1/1 Running 0 2s
Deployment控制器中的Pod资源副本集已经被动态的创建出来,并且不影响原有的Pod资源
6)动态缩容Pod副本集
]# kubectl patch deployment myapp-deploy -p '{"spec":{"replicas":2}}'
deployment.apps/myapp-deploy patched
[root@master label]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
myapp-deploy-65fb6c8459-2wkfq 1/1 Running 0 112s
myapp-deploy-65fb6c8459-bkcbj 1/1 Running 0 12m
myapp-deploy-65fb6c8459-c44fs 1/1 Running 0 12m
myapp-deploy-65fb6c8459-fbbl7 1/1 Running 0 12m
myapp-deploy-65fb6c8459-vtrzk 1/1 Running 0 112s
myapp-deploy-65fb6c8459-c44fs 1/1 Terminating 0 13m
myapp-deploy-65fb6c8459-2wkfq 1/1 Terminating 0 3m16s
myapp-deploy-65fb6c8459-vtrzk 1/1 Terminating 0 3m16s
myapp-deploy-65fb6c8459-vtrzk 0/1 Terminating 0 3m19s
myapp-deploy-65fb6c8459-2wkfq 0/1 Terminating 0 3m19s
myapp-deploy-65fb6c8459-c44fs 0/1 Terminating 0 13m
myapp-deploy-65fb6c8459-2wkfq 0/1 Terminating 0 3m20s
myapp-deploy-65fb6c8459-2wkfq 0/1 Terminating 0 3m20s
myapp-deploy-65fb6c8459-c44fs 0/1 Terminating 0 13m
myapp-deploy-65fb6c8459-c44fs 0/1 Terminating 0 13m
myapp-deploy-65fb6c8459-vtrzk 0/1 Terminating 0 3m20s
myapp-deploy-65fb6c8459-vtrzk 0/1 Terminating 0 3m20s
Deployment控制器已经平滑退出了三个副本集,来满足用户所定义的Pod副本数量
7)滚动更新Pod镜像
]# kubectl set image deployment myapp-deploy myapp=ikubernetes/myapp:v2
deployment.apps/myapp-deploy image updated
]# kubectl get rs -w
NAME DESIRED CURRENT READY AGE
myapp-deploy-65fb6c8459 2 2 2 18m
myapp-deploy-559ff5c66 1 0 0 0s
myapp-deploy-559ff5c66 1 0 0 0s
myapp-deploy-559ff5c66 1 1 0 0s
myapp-deploy-559ff5c66 1 1 1 3s
myapp-deploy-65fb6c8459 1 2 2 18m
myapp-deploy-559ff5c66 2 1 1 3s
myapp-deploy-65fb6c8459 1 2 2 18m
myapp-deploy-559ff5c66 2 1 1 3s
myapp-deploy-559ff5c66 2 2 1 3s
myapp-deploy-65fb6c8459 1 1 1 18m
myapp-deploy-559ff5c66 2 2 2 4s
myapp-deploy-65fb6c8459 0 1 1 18m
myapp-deploy-65fb6c8459 0 1 1 18m
myapp-deploy-65fb6c8459 0 0 0 18m
]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
myapp-deploy-65fb6c8459-bkcbj 1/1 Running 0 15m
myapp-deploy-65fb6c8459-fbbl7 1/1 Running 0 15m
myapp-deploy-559ff5c66-gmgfn 0/1 Pending 0 0s
myapp-deploy-559ff5c66-gmgfn 0/1 Pending 0 0s
myapp-deploy-559ff5c66-gmgfn 0/1 ContainerCreating 0 0s
myapp-deploy-559ff5c66-gmgfn 1/1 Running 0 3s
myapp-deploy-65fb6c8459-bkcbj 1/1 Terminating 0 18m
myapp-deploy-559ff5c66-2sqtc 0/1 Pending 0 0s
myapp-deploy-559ff5c66-2sqtc 0/1 Pending 0 0s
myapp-deploy-559ff5c66-2sqtc 0/1 ContainerCreating 0 0s
myapp-deploy-65fb6c8459-bkcbj 0/1 Terminating 0 18m
myapp-deploy-559ff5c66-2sqtc 1/1 Running 0 1s
myapp-deploy-65fb6c8459-fbbl7 1/1 Terminating 0 18m
myapp-deploy-65fb6c8459-fbbl7 0/1 Terminating 0 18m
myapp-deploy-65fb6c8459-bkcbj 0/1 Terminating 0 18m
myapp-deploy-65fb6c8459-bkcbj 0/1 Terminating 0 18m
myapp-deploy-65fb6c8459-fbbl7 0/1 Terminating 0 18m
myapp-deploy-65fb6c8459-fbbl7 0/1 Terminating 0 18m
]# kubectl get rs -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
myapp-deploy-559ff5c66 2 2 2 5m22s myapp ikubernetes/myapp:v2 app=myapp,pod-template-hash=559ff5c66,release=canary
myapp-deploy-65fb6c8459 0 0 0 24m myapp ikubernetes/myapp:v1 app=myapp,pod-template-hash=65fb6c8459,release=canary
通过监视ReplicaSet控制器和Pod资源,可以看见整个Deployment控制器更新的操作;首先Depliyment控制器会创建一个新的ReplicaSet控制器,并在此控制器上创建新的Pod资源对象,然后平滑退出旧的ReplicaSet控制器上的Pod资源;虽然Pod资源被创建调度到了新的ReplicaSet控制器上,但是老的ReplicaSet控制器并不会退出,因为用户可能会做回滚操作,Deployment通过此来做回滚历史版本。
8)访问新的Pod资源对象
]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-deploy-559ff5c66-5zv6t 1/1 Running 0 23s 10.244.1.35 node1 <none> <none>
myapp-deploy-559ff5c66-v9qdf 1/1 Running 0 24s 10.244.1.34 node1 <none> <none>
]# curl 10.244.1.35
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
]# curl 10.244.1.34
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
9)查看滚动更新历史
]# kubectl rollout history deployment
deployment.apps/myapp-deploy
REVISION CHANGE-CAUSE
1 <none>
2 <none>
10)回滚Pod镜像版本
]# kubectl rollout undo deployment/myapp-deploy --to-revision=1
deployment.apps/myapp-deploy rolled back
]# kubectl get rs -w -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
myapp-deploy-559ff5c66 2 2 2 8m16s myapp ikubernetes/myapp:v2 app=myapp,pod-template-hash=559ff5c66,release=canary
myapp-deploy-65fb6c8459 0 0 0 27m myapp ikubernetes/myapp:v1 app=myapp,pod-template-hash=65fb6c8459,release=canary
myapp-deploy-65fb6c8459 0 0 0 29m myapp ikubernetes/myapp:v1 app=myapp,pod-template-hash=65fb6c8459,release=canary
myapp-deploy-65fb6c8459 1 0 0 29m myapp ikubernetes/myapp:v1 app=myapp,pod-template-hash=65fb6c8459,release=canary
myapp-deploy-65fb6c8459 1 0 0 29m myapp ikubernetes/myapp:v1 app=myapp,pod-template-hash=65fb6c8459,release=canary
myapp-deploy-65fb6c8459 1 1 0 29m myapp ikubernetes/myapp:v1 app=myapp,pod-template-hash=65fb6c8459,release=canary
myapp-deploy-65fb6c8459 1 1 1 29m myapp ikubernetes/myapp:v1 app=myapp,pod-template-hash=65fb6c8459,release=canary
myapp-deploy-559ff5c66 1 2 2 10m myapp ikubernetes/myapp:v2 app=myapp,pod-template-hash=559ff5c66,release=canary
myapp-deploy-65fb6c8459 2 1 1 29m myapp ikubernetes/myapp:v1 app=myapp,pod-template-hash=65fb6c8459,release=canary
myapp-deploy-559ff5c66 1 2 2 10m myapp ikubernetes/myapp:v2 app=myapp,pod-template-hash=559ff5c66,release=canary
myapp-deploy-65fb6c8459 2 1 1 29m myapp ikubernetes/myapp:v1 app=myapp,pod-template-hash=65fb6c8459,release=canary
myapp-deploy-65fb6c8459 2 2 1 29m myapp ikubernetes/myapp:v1 app=myapp,pod-template-hash=65fb6c8459,release=canary
myapp-deploy-559ff5c66 1 1 1 10m myapp ikubernetes/myapp:v2 app=myapp,pod-template-hash=559ff5c66,release=canary
myapp-deploy-65fb6c8459 2 2 2 29m myapp ikubernetes/myapp:v1 app=myapp,pod-template-hash=65fb6c8459,release=canary
myapp-deploy-559ff5c66 0 1 1 10m myapp ikubernetes/myapp:v2 app=myapp,pod-template-hash=559ff5c66,release=canary
myapp-deploy-559ff5c66 0 1 1 10m myapp ikubernetes/myapp:v2 app=myapp,pod-template-hash=559ff5c66,release=canary
myapp-deploy-559ff5c66 0 0 0 10m myapp ikubernetes/myapp:v2 app=myapp,pod-template-hash=559ff5c66,release=canary
]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
myapp-deploy-559ff5c66-2sqtc 1/1 Running 0 7m54s
myapp-deploy-559ff5c66-gmgfn 1/1 Running 0 7m57s
myapp-deploy-65fb6c8459-ds9fg 0/1 Pending 0 0s
myapp-deploy-65fb6c8459-ds9fg 0/1 Pending 0 0s
myapp-deploy-65fb6c8459-ds9fg 0/1 ContainerCreating 0 0s
myapp-deploy-65fb6c8459-ds9fg 1/1 Running 0 1s
myapp-deploy-559ff5c66-2sqtc 1/1 Terminating 0 10m
myapp-deploy-65fb6c8459-q6kn9 0/1 Pending 0 0s
myapp-deploy-65fb6c8459-q6kn9 0/1 Pending 0 0s
myapp-deploy-65fb6c8459-q6kn9 0/1 ContainerCreating 0 0s
myapp-deploy-559ff5c66-2sqtc 0/1 Terminating 0 10m
myapp-deploy-65fb6c8459-q6kn9 1/1 Running 0 2s
myapp-deploy-559ff5c66-gmgfn 1/1 Terminating 0 10m
myapp-deploy-559ff5c66-gmgfn 0/1 Terminating 0 10m
myapp-deploy-559ff5c66-gmgfn 0/1 Terminating 0 10m
myapp-deploy-559ff5c66-gmgfn 0/1 Terminating 0 10m
myapp-deploy-559ff5c66-2sqtc 0/1 Terminating 0 10m
myapp-deploy-559ff5c66-2sqtc 0/1 Terminating 0 10m
11)查看滚动后状态与历史
]# kubectl rollout status deployment/myapp-deploy
deployment "myapp-deploy" successfully rolled out
]# kubectl rollout history deployment
deployment.apps/myapp-deploy
REVISION CHANGE-CAUSE
2 <none>
3 <none>
]# kubectl get rs -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
myapp-deploy-559ff5c66 0 0 0 14m myapp ikubernetes/myapp:v2 app=myapp,pod-template-hash=559ff5c66,release=canary
myapp-deploy-65fb6c8459 2 2 2 32m myapp ikubernetes/myapp:v1 app=myapp,pod-template-hash=65fb6c8459,release=canary
12)访问回滚后的Pod资源
]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-deploy-65fb6c8459-djg6k 1/1 Running 0 54s 10.244.2.12 node2 <none> <none>
myapp-deploy-65fb6c8459-jp7hc 1/1 Running 0 53s 10.244.1.36 node1 <none> <none>
]# curl 10.244.2.12
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
]# curl 10.244.1.36
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
13)暂停与恢复Deployment的回滚
]# kubectl rollout undo deployment/myapp-deploy --to-revision=4
deployment.apps/myapp-deploy rolled back
]# kubectl rollout pause deployment/myapp-deploy
deployment.apps/myapp-deploy paused
]# kubectl rollout resume deployment/myapp-deploy
deployment.apps/myapp-deploy resumed
Deployment的清理策略:
可以通过设置.spec.revisonHistoryLimit项来指定Deployment控制器最多保留多少revision历史记录,默认Deployment控制器会保留所有的revision版本;如果该项设置为0,则Deployment控制器就不允许做回滚操作了。