Kubernetes里第一個(gè)控制器模式的完整實(shí)現(xiàn):Deployment。Deployment 看似簡(jiǎn)單,但實(shí)際上,它實(shí)現(xiàn)了 Kubernetes 項(xiàng)目中一個(gè)非常重要的功能:Pod的“水平擴(kuò)展 / 收縮”(horizontal scaling out/in)。這個(gè)功能,是從 PaaS 時(shí)代開(kāi)始,一個(gè)平臺(tái)級(jí)項(xiàng)目就必須具備的編排能力。
實(shí)例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Deployment、ReplicaSet與Pod的關(guān)系

通過(guò)這張圖,我們就很清楚的看到,一個(gè)定義了 replicas=3 的 Deployment,與它的ReplicaSet,以及 Pod 的關(guān)系,實(shí)際上是一種“層層控制”的關(guān)系。其中,ReplicaSet 負(fù)責(zé)通過(guò)“控制器模式”,保證系統(tǒng)中 Pod 的個(gè)數(shù)永遠(yuǎn)等于指定的個(gè)數(shù)。這也正是 Deployment 只允許容器的 restartPolicy=Always 的主要原因:只有在容器能保證自己始終是 Running 狀態(tài)的前提下,ReplicaSet 調(diào)整 Pod 的個(gè)數(shù)才有意義。而在此基礎(chǔ)上,Deployment 同樣通過(guò)“控制器模式”,來(lái)操作 ReplicaSet 的個(gè)數(shù)和屬性,進(jìn)
而實(shí)現(xiàn)“水平擴(kuò)展 / 收縮”和“滾動(dòng)更新”這兩個(gè)編排動(dòng)作
kubectl scale deployment nginx-deployment --replicas=3
kubectl get pods
nginx-deployment-69fbc8b64f-4f97r 1/1 Running 0 95m
nginx-deployment-69fbc8b64f-4n9nj 1/1 Running 0 95m
nginx-deployment-69fbc8b64f-wdjcs 1/1 Running 0 95m
kubectl create -f nginx-deployment.yaml --record
#record 的作用在于記錄每次操作的命令
查看deployment的狀態(tài)
[root@k8s-master pods]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 3h39m
[root@k8s-master pods]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-59c9f8dff 0 0 0 3h40m
nginx-deployment-69fbc8b64f 3 3 3 3h40m
#可以看到,在deployment的名字的最后為隨機(jī)數(shù),該值為hash值,通過(guò)kubectl describle deployment nginx-deployment-69fbc8b64f 查看到
- UP-TO-DATE:當(dāng)前處于最新版本的 Pod 的個(gè)數(shù),所謂最新版本指的是 Pod 的 Spec 部分
與 Deployment 里 Pod 模板里定義的完全一致
- AVAILABLE:當(dāng)前已經(jīng)可用的 Pod 的個(gè)數(shù),即:既是 Running 狀態(tài),又是最新版本,并
且已經(jīng)處于 Ready(健康檢查正確)狀態(tài)的 Pod 的個(gè)數(shù) - DESIRED:用戶期望的 Pod 副本個(gè)數(shù)(spec.replicas 的值)
- CURRENT:當(dāng)前處于 Running 狀態(tài)的 Pod 的個(gè)數(shù)
實(shí)時(shí)查看deployment的狀態(tài)
[root@k8s-master pods]# kubectl rollout status deployment/nginx-deployment
deployment.apps/nginx-deployment successfully rolled out
滾動(dòng)更新
通過(guò)edit修改etcd在的API對(duì)象
kubectl edit deployment nginx-deployment-69fbc8b64f
#通過(guò)修改鏡像的版本,達(dá)到滾動(dòng)更新的效果
# revisionHistoryLimit: 10 歷史記錄最大條數(shù)
# maxSurge: 25% 滾動(dòng)更新時(shí),最大啟動(dòng)的臺(tái)數(shù)
# maxUnavailable: 25% 滾動(dòng)更新時(shí),最大不可用的臺(tái)數(shù)
#當(dāng)然,kubectl edit 并不神秘,它不過(guò)是把 API 對(duì)象的內(nèi)容下載到了本地文件,讓你修改完成后再提交上去
查看結(jié)果
kubectl describe deployment nginx-deployme
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 35m deployment-controller Scaled down replica set nginx-deployment-59c9f8dff to 2
Normal ScalingReplicaSet 5m17s deployment-controller Scaled up replica set nginx-deployment-5875d75456 to 1
Normal ScalingReplicaSet 3m deployment-controller Scaled down replica set nginx-deployment-59c9f8dff to 1
Normal ScalingReplicaSet 3m deployment-controller Scaled up replica set nginx-deployment-5875d75456 to 2
Normal ScalingReplicaSet 85s deployment-controller Scaled down replica set nginx-deployment-59c9f8dff to 0
#可以看到是停止一個(gè)舊pod,啟動(dòng)一個(gè)新pod,直到所有的pod均換為新鏡像啟動(dòng)的pod
#查看depliyment的狀態(tài)
[root@k8s-master pods]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-59c9f8dff 2 2 2 54s
nginx-deployment-69fbc8b64f 1 1 0 14s
[root@k8s-master pods]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-59c9f8dff 0 0 0 81s
nginx-deployment-69fbc8b64f 2 2 2 41s
滾動(dòng)更新的優(yōu)勢(shì):在升級(jí)剛開(kāi)始的時(shí)候,集群里只有 1 個(gè)新版本的 Pod。如果這時(shí),新版本 Pod 有問(wèn)題啟動(dòng)不起來(lái),那么“滾動(dòng)更新”就會(huì)停止,從而允許開(kāi)發(fā)和運(yùn)維人員介入。而在這個(gè)過(guò)程中,由于
應(yīng)用本身還有兩個(gè)舊版本的 Pod 在線,所以服務(wù)并不會(huì)受到太大的影響
#修改pod的鏡像,作用與上面的一致
kubectl set image deployment/nginx-deployment nginx=nginx:1.91
回滾的方法
kubectl rollout undo deployment/nginx-deployme
#直接回滾到上一各版本
#回滾到指定版本
kubectl rollout history deployment/nginx-deployment #查看所有的歷史版本,使用record會(huì)有記錄,否則不會(huì)有命令
#回滾
kubectl rollout undo deployment/nginx-deployment --to-revision=2
#查看特定版本的信息
kubectl rollout history deployment/nginx-deployment --revision=2
我們對(duì) Deployment 的多次更新操作,最后只生成一個(gè) ReplicaSet
使 Deployment 進(jìn)入暫停狀態(tài)
kubectl rollout pause deployment nginx-deployment
你就可以隨意使用 kubectl edit 或者 kubectl set image 指令,修改這個(gè)Deployment 的內(nèi)容了。
由于此時(shí) Deployment 正處于“暫?!睜顟B(tài),所以我們對(duì) Deployment 的所有修改,都不會(huì)觸發(fā)新的“滾動(dòng)更新”,也不會(huì)創(chuàng)建新的 ReplicaSet。
kubectl rollout resume deploy/nginx-deployment
恢復(fù)deployment,觸發(fā)執(zhí)行最后一次滾動(dòng)更新