前提知識:
Deployment:Deployment為Pod和Replica Set提供聲明式更新。
你只需要在 Deployment 中描述您想要的
目標狀態(tài)是什么,Deployment controller 就會幫您將 Pod 和ReplicaSet 的實際狀態(tài)改變到您的目標狀態(tài)。您可以定義一個全新的 Deployment 來創(chuàng)建ReplicaSet或者刪除已有的 Deployment 并創(chuàng)建一個新的來替換。
它實現(xiàn)了 Kubernetes 項目中一個非常重要的功能:
Pod的“水平擴展 / 收縮”(horizontal scaling out/in)。這個功能,是從 PaaS 時代開始,一個
平臺級項目就必須具備的編排能力。
舉個例子,如果你更新了 Deployment 的 Pod 模板(比如,修改了容器的鏡像),那么Deployment 就需要遵循一種叫作“滾動更新”(rolling update)的方式,來升級現(xiàn)有的容器。而這個能力的實現(xiàn),依賴的是 Kubernetes 項目中的一個非常重要的概念(API 對象):ReplicaSet
實驗:
-
創(chuàng)建
kubectl create -f nginx-deployment.yaml
image.png yaml文件如下
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-controller
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.8
ports:
- containerPort: 80

通過這張圖,我們就很清楚的看到,一個定義了
replicas=3的 Deployment,與它的ReplicaSet,以及Pod的關(guān)系,實際上是一種“層層控制”的關(guān)系。其中,ReplicaSet 負責(zé)通過“控制器模式”,保證系統(tǒng)中 Pod 的個數(shù)永遠等于指定的個數(shù)(比如,3 個)。這也正是 Deployment 只允許容器的
restartPolicy=Always的主要原因:只有在容器能保證自己始終是 Running狀態(tài)的前提下,ReplicaSet 調(diào)整 Pod 的個數(shù)才有意義。而在此基礎(chǔ)上,Deployment 同樣通過“控制器模式”,來操作 ReplicaSet 的個數(shù)和屬性,進而實現(xiàn)
“水平擴展 / 收縮”和“滾動更新”這兩個編排動作。其中,“水平擴展 / 收縮”非常容易實現(xiàn),Deployment Controller 只需要修改它所控制的ReplicaSet 的 Pod 副本個數(shù)就可以了。
比如,把這個值從 3 改成 4,那么 Deployment 所對應(yīng)的 ReplicaSet,就會根據(jù)修改后的值自動創(chuàng)建一個新的 Pod。這就是“水平擴展”了;“水平收縮”則反之。
-
彈性擴縮
kubectl scale deployment nginx-deployment-controller --replicas=3
image.png -
滾動更新
kubectl rollout status deployment nginx-deployment-controller
image.png -
查看狀態(tài)
kubectl describe deployment nginx-deployment-controller
image.png
kubectl get replicasets.apps

- 查看“滾動更新”新、舊兩個 ReplicaSet 的最終狀態(tài):
kubectl get rs
image.png - 編輯模式,修改配置文件
kubectl edit deployments.apps nginx-deployment-controller
版本回退
創(chuàng)建記錄
kubectl create -f nginx-deployment.yaml --record-
查看版本
kubectl rollout history deployment nginx-deployment-controller --revision=2
image.png -
擴容至3個
為了方便做版本回退實驗,將pods調(diào)整為3個
kubectl scale deployment nginx-deployment-controller --replicas=3
image.png 設(shè)置一個鏡像版本
把這個鏡像名字修改成為了一個錯誤的名字,比如:nginx:1.91。這樣,這個
Deployment 就會出現(xiàn)一個升級失敗的版本
kubectl set image deployment nginx-deployment-controller nginx=nginx:1.91
由于這個 nginx:1.91 鏡像在 Docker Hub 中并不存在,所以這個 Deployment 的“滾動更新”被觸發(fā)后,會立刻報錯并停止。這時,我們來檢查一下 ReplicaSet 的狀態(tài),如下所示:
kubectl get rs 查看結(jié)果

新版本的 ReplicaSet(hash=9f46bb5)的“水平擴展”已經(jīng)停止。而且此時,它已經(jīng)創(chuàng)建了兩個 Pod,但是它們都沒有進入 READY 狀態(tài)。這當(dāng)然是因為這兩個 Pod 都拉取不到有效的鏡像。與此同時,舊版本的 ReplicaSet(hash=1764197365)的“水平收縮”,也自動停止了。此時,已經(jīng)有一個舊 Pod 被刪除,還剩下兩個舊 Pod。
那么問題來了, 我們?nèi)绾巫屵@個 Deployment 的 3 個 Pod,都回滾到以前的舊版本呢?
查看生成新的版本
kubectl rollout history deployment nginx-deployment-controller-
查看詳情版本信息
kubectl rollout history deployment nginx-deployment-controller --revision=3
image.png -
回滾舊版本
kubectl rollout undo deployment nginx-deployment-controller --to-revision=2
image.png








