1. 程式人生 > 實用技巧 >Kubernetes深入Pod控制器-Deployment控制器

Kubernetes深入Pod控制器-Deployment控制器

轉載於https://abcops.cn/1575.html

Deployment控制器簡述介紹

Deployment簡寫(deploy)是Kubernetes控制器的又一種實現,它構建於 ReplicaSet控制器之上,可為Pod和ReplicaSet資源提供宣告式更新,相比較而言,Pod和ReplicaSet是較低階的資源,它們很少被直接使用,Deployment、ReplicaSet和Pod的關係如下圖所示:

Deploymnet控制器資源的主要職責同樣是為了保證Pod資源的健康執行,其大部分功能均可通過呼叫ReplicaSet控制器來實現,同時還增添了部分特性,增添特性如下:

  1. 事件和狀態檢視:必要時可以檢視Deployment獨享升級的詳細進度和狀態。
  2. 回滾:升級操作完成後發現問題時,支援使用回滾機制將應用返回到前一個或由使用者指定的歷史記錄的版本上。
  3. 版本記錄:對Deployment物件的每一次操作都給予儲存,以供後續可能執行的回滾操作使用。
  4. 暫停和啟動:對於每一次升級,都能夠隨時暫停和啟動。
  5. 多種自動更新方案:一是Recreate,即重建更新機制,全面停止、刪除舊的Pod後用新版本替代;另一個是RollingUpdate,即為滾動升級機制,依次替換舊Pod至新版本。

Deployment的功能:

  1. 部署無狀態應用
  2. 管理Pod和ReplicaSet
  3. 具有上線部署、副本設定、滾動升級、回滾等功能
  4. 提供宣告式更新,例如只更新一個新的Image

Deployment控制器應用場景:

  1. Web服務
  2. 微服務

Deployment控制器建立配置

Deployment是標準的Kubernetes API資源,它構建於ReplicaSet資源之上,於是其spec欄位中巢狀使用的欄位包含了ReplicaSet控制器支援的replicas、selector、template和minReadySeconds,它也正是利用這些資訊完成了二級資源ReplicaSet物件的構建,下面是一個Deployment控制器資源的配置清單:

1.建立資源配置清單

  1. cat nginx-deploy.yaml
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: nginx-deployment
  6. namespace: nginx-namespace
  7. annotations:
  8. deployment.k8sops.cn/type: nginx-deploy
  9. labels:
  10. app: nginx-deploy
  11. spec:
  12. replicas: 3
  13. selector:
  14. matchLabels:
  15. app: nginx-proxy
  16. template:
  17. metadata:
  18. labels:
  19. app: nginx-proxy
  20. version: 1.18.0
  21. spec:
  22. containers:
  23. - name: nginx-proxy
  24. image: nginx:1.18.0
  25. ports:
  26. - containerPort: 80
  27. name: http

上面除了控制器型別和名稱之外,與上章節講的ReplicaSet控制器清單內容幾乎沒有什麼不同

2.建立控制器物件及檢視狀態

  1. #建立deploy控制器
  2. kubectl apply -f nginx-deploy.yaml
  3. deployment.apps/nginx-deployment created
  4. #檢視建立的nginx-deployment控制器狀態,下面UP-TO-DATE表示已經達到期望狀態的Pod副本數量。AVAILABEL表示當前處於可用狀態的應用程式數量
  5. kubectl get deploy -n nginx-namespace
  6. NAME READY UP-TO-DATE AVAILABLE AGE
  7. nginx-deployment 3/3 3 3 4s
  8. #檢視Pod狀態
  9. kubectl get pods -l app=nginx-proxy -n nginx-namespace
  10. NAME READY STATUS RESTARTS AGE
  11. nginx-deployment-84d6c8c7cd-68cr8 1/1 Running 0 25s
  12. nginx-deployment-84d6c8c7cd-jhfrq 1/1 Running 0 25s
  13. nginx-deployment-84d6c8c7cd-q4czp 1/1 Running 0 25s

3.由控制器建立的Pod命名方式
Deployment控制器會自動建立相關的ReplicaSet控制器資源,並以[Deployment-Name]-[Pod-Template-Hash-Value]格式為其命名,其中的hash值由 Deployment控制器自動生成。由Deployment建立的Pod物件會自動使用相同的標籤選擇器。
上面的命令結果中,Pod物件的名稱遵循ReplicaSet控制器的命名格式,它以ReplicaSet控制器的名稱字首,後跟5為隨機字元。

Deployment控制器更新策略

ReplicaSet控制器的應用更新需要手動分成多步並以特定的順序進行,過程繁瑣且容易出錯,而Deployment卻只需要由使用者指定在Pod模版中要改動的內容,例如容器映象檔案的版本,餘下的步驟可交給控制器自動完成,同樣,更新應用程式的規模也只需要修改期望的副本數量,餘下的事情交給Deployment控制器即可。
Deployment控制器詳細資訊中包含了其更新策略的相關配置資訊,如下圖中命令輸出的StrategyTypeRollingUpdateStrategyOldReplicaSets欄位等。

1.Deployment控制器預設支援兩種更新策略:

  • 滾動更新(rolling update)
  • 重新建立(recreate)

滾動更新(rolling update)

滾動升級是Deployment預設的更新策略,它在刪除一部分舊版本Pod資源的同時,補充建立一部分新版本的Pod物件進行應用升級,其優勢是升級期間,容器中應用提供的服務不會中斷,但要求應用程式能夠應對新舊版本同時工作的情況,例如新舊版本相容同一個資料庫方案等。不過更新操作期間,不同客戶端得到的響應內容可能會來自不同版本的應用。

幫助文件:kubectl explain deploy.spec.strategy.rollingUpdate

重新建立(recreate)

重新建立更新類似與上章節講的ReplicaSet的第一種更新方式,首先刪除現有的Pod物件,而後由控制器基於新模版重新創建出新版本的資源物件。通常,只應該在應用的新舊版本不相容時才會使用recreate策略(如依賴的後端資料庫的 schema 不同且無法相容),因為它會導致應用替換期間暫時不可用,好處在於它不存在中間狀態,使用者訪問到的要麼是應用的新版本,要麼是舊版本。

Deployment控制器的滾動更新操作並非在同一個ReplicaSet控制器物件下刪除並建立Pod資源,而是將它們分置於兩個不同的控制器之下:舊控制器的Pod物件數量不斷減少的同時,新控制器的Pod數量不斷增加,直到舊控制器不在擁有Pod物件,而新控制器的副本數量變的完全符合使用者期望狀態副本數量為止。

滾動更新時,應用升級期間還要確保可用的Pod物件數量不低於某閾值以確保可以持續處理客戶端的服務請求,變動的方式和Pod物件的數量範圍將通過deployment控制器清單中spec.strategy.rollingUpdate.maxSurgespec.strategy.rollingUpdate.maxUnavailable兩個屬性協同進行定義。

maxSurge幫助文件:kubectl explain deploy.spec.strategy.rollingUpdate.maxSurge
maxUnavailable幫助文件:kubectl explain deploy.spec.strategy.rollingUpdate.maxUnavailable

maxSurge:

指定升級期間總存在的Pod物件數量,最多可超出期望Pod數量的個數,值可以為0或者整數,也可以是一個期望值的百分比;例如當前Pod副本期望值為3,maxSurge屬性值為1,則表示Pod物件在升級期間Pod總數量不能超過4個。

maxUnavailable:

升級期間正常可用的Pod副本數(包括舊版本)最多不能低於期望Pod數量的個數,值可以是一個0或者整數,也可以是一個百分比;預設為1,例如當前Pod副本期望值為3,則表示Pod物件在升級期間Pod總數量不能低2個處於正常服務狀態。

注意:
maxSurge和maxUnavailable屬性值不可同時為0,否則Pod物件的副本數量在符合使用者期望的數量後無法做出合理變動以進行滾動更新操作。

2.spec.minReadySeconds控制應用升級速度
配置清單時,還可以使用Deployment控制器的spec.minReadySeconds屬性來控制應用的升級速度。新舊更替過程中,新建立的Pod物件一旦成功響應就緒探測即被視作可用,而後即可開始下一輪的替換操作。而spec.minReadySeconds能夠定義在新的Pod物件建立後至少要等待多久才會將其視為就緒,在此期間,更新操作會被阻塞。因此它可以用來讓Kubernetes在每次建立Pod資源後都要登上一段時間後再開始下一輪更替,這個時間長度的理想值是等到Pod物件中的應用已經可以接受並處理請求流量。

幫助文件:kubectl explain deploy.spec.minReadySeconds

3.spec.revisionHistoryLimit舊版本數量
Deployment控制器也支援使用者保留其滾動更新歷史中的舊ReplicaSet物件版本,如下圖所示,這賦予了控制器進行應用回滾的能力,使用者可按需回滾到指定的歷史版本。控制器可儲存的歷史版本由spec.revisionHistoryLimit屬性進行定義,當然,也只有保存於revision歷史中的ReplicaSet版本可用於回滾,因此,使用者要習慣性地在更新操作時指定保留舊版本。

幫助文件:kubectl explain deploy.spec.revisionHistoryLimit

注意:
為了儲存版本升級的歷史,需要在建立Deployment物件時使用--record選項

儘管滾動更新節約系統資源,但它也存在一些劣勢。直接改動現有環境,會使系統引入不確定性風險,而且升級過程中出現問題後,執行回滾操作也較為緩慢。有鑑於此,金絲雀部署可能是較為理想的實現方式,當然如果不考慮系統系統資源的可用性,那麼傳統的藍綠部署也是不錯的選擇。

Deployment控制器更新示例

修改Pod模版相關的配置引數便能完成Deployment控制器資源的更新,由於是宣告式配置,因此對Deployment控制器資源的修改尤其適合kubectl applykubectl patch命令來進行,如果僅是修改容器映象則可以使用kubectl set image命令。

下面將講解四種方式進行滾動更新:

  1. 修改Deployment控制器清單(非Pod模版內容)。
  2. 修改Deployment控制器清單中Pod模版。
  3. 通過kubectl set image命令直接修改由Deployment所管控Pod的映象。
  4. 通過kubectl patch命令直接修改控制器清單中的任何內容。

1.修改Deployment控制器清單(非Pod模版內容)
修改Deployment控制清單,非Pod模版內容,我們修改內容後,則只對下次新建立的Pod生效,對於已存在的Pod則不會進行更新。

先檢視沒有修改配置前Deployment控制器是什麼配置
如下:minReadySeconds預設為0秒,StrategyType預設為滾動更新,RollingUpdateStrategy預設為百分比25%,

更新deploy控制器配置

  1. cat nginx-deploy.yaml
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: nginx-deployment
  6. namespace: nginx-namespace
  7. annotations:
  8. deployment.k8sops.cn/type: nginx-deploy
  9. labels:
  10. app: nginx-deploy
  11. spec:
  12. replicas: 3
  13. minReadySeconds: 10 #升級等待時間
  14. revisionHistoryLimit: 6 #舊版本歷史數量
  15. strategy:
  16. type: RollingUpdate #指定型別為滾動更新
  17. rollingUpdate:
  18. maxSurge: 1 #可超出期望Pod數量的個數
  19. maxUnavailable: 1 #升級期間不能正常提供服務的Pod
  20. selector:
  21. matchLabels:
  22. app: nginx-proxy
  23. template:
  24. metadata:
  25. namespace: nginx-namespace
  26. labels:
  27. app: nginx-proxy
  28. version: 1.18.0
  29. spec:
  30. containers:
  31. - name: nginx-proxy
  32. image: nginx:1.18.0
  33. ports:
  34. - containerPort: 80
  35. name: http

更新配置檔案

  1. kubectl apply -f nginx-deploy.yaml

檢視Pod狀態,已存在的Pod未發生任何改變

  1. kubectl get pods -o wide -n nginx-namespace
  2. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  3. nginx-deployment-84d6c8c7cd-68cr8 1/1 Running 0 3h39m 10.244.5.115 k8s-node03 <none> <none>
  4. nginx-deployment-84d6c8c7cd-jhfrq 1/1 Running 0 3h39m 10.244.3.128 k8s-node01 <none> <none>
  5. nginx-deployment-84d6c8c7cd-q4czp 1/1 Running 0 3h39m 10.244.3.129 k8s-node01 <none> <none>

檢視控制器詳細資訊,如下圖,我們修改的資訊已發生改變,對下次新建立的Pod生效

2.修改Deployment控制器清單中Pod模版
這次我們修改Pod中使用的映象,將nginx映象改為latest版本

  1. cat nginx-deploy.yaml
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: nginx-deployment
  6. namespace: nginx-namespace
  7. annotations:
  8. deployment.k8sops.cn/type: nginx-deploy
  9. labels:
  10. app: nginx-deploy
  11. spec:
  12. replicas: 3
  13. minReadySeconds: 10
  14. revisionHistoryLimit: 6
  15. strategy:
  16. type: RollingUpdate
  17. rollingUpdate:
  18. maxSurge: 1
  19. maxUnavailable: 1
  20. selector:
  21. matchLabels:
  22. app: nginx-proxy
  23. template:
  24. metadata:
  25. namespace: nginx-namespace
  26. labels:
  27. app: nginx-proxy
  28. version: latest #標籤也改了下
  29. spec:
  30. containers:
  31. - name: nginx-proxy
  32. image: nginx:latest #修改nginx映象版本為latest
  33. ports:
  34. - containerPort: 80
  35. name: http

更新配置檔案

  1. kubectl apply -f nginx-deploy.yaml

檢視更新後的映象,已經成功更新

  1. kubectl get pods -n nginx-namespace -o custom-columns=Name:metadata.name,Image:spec.containers[0].image
  2. Name Image
  3. nginx-deployment-698f87c954-d8299 nginx:latest
  4. nginx-deployment-698f87c954-g27sh nginx:latest
  5. nginx-deployment-698f87c954-slqq8 nginx:latest

通過kubectl describe檢視deployment控制器滾動更新的過程

  1. kubectl describe deploy nginx-deployment -n nginx-namespace | grep -A 10 Events
  2. Events:
  3. Type Reason Age From Message
  4. ---- ------ ---- ---- -------
  5. Normal ScalingReplicaSet 9m3s deployment-controller Scaled up replica set nginx-deployment-698f87c954 to 1
  6. Normal ScalingReplicaSet 9m3s deployment-controller Scaled down replica set nginx-deployment-84d6c8c7cd to 2
  7. Normal ScalingReplicaSet 9m3s deployment-controller Scaled up replica set nginx-deployment-698f87c954 to 2
  8. Normal ScalingReplicaSet 8m50s deployment-controller Scaled down replica set nginx-deployment-84d6c8c7cd to 0
  9. Normal ScalingReplicaSet 8m50s deployment-controller Scaled up replica set nginx-deployment-698f87c954 to 3

如上日誌:
第一行:新的ReplicaSet控制器nginx-deployment-698f87c954啟動一個新Pod,這個時候是有4個Pod。對外提供服務的Pod還是3個。
第二行:舊的ReplicaSet控制器nginx-deployment-84d6c8c7cd將舊Pod由三個縮小至2個,這個時候對外提供服務的Pod,只有兩個舊的。
第三行:新的ReplicaSet控制器nginx-deployment-698f87c954啟動第二個新Pod,這個時候對外提供服務的Pod有4個,兩個新Pod,和兩個舊Pod。
第四行:舊的ReplicaSet控制器nginx-deployment-84d6c8c7cd將舊Pod全部關閉。這個時候提供服務的Pod只有兩個新的Pod
第五行:新的ReplicaSet控制器nginx-deployment-698f87c954啟動第三個新Pod,對外提供服務的Pod有三個新的Pod。

檢視ReplicaSet控制器,如下兩個RS控制器,上面的是新RS控制器,下面的是老的RS控制器。

  1. kubectl get rs -n nginx-namespace
  2. NAME DESIRED CURRENT READY AGE
  3. nginx-deployment-698f87c954 3 3 3 50m
  4. nginx-deployment-84d6c8c7cd 0 0 0 4h41m

kubectl rollout status命令用於列印滾動更新過程中的狀態資訊

  1. kubectl rollout status deploy nginx-deployment -n nginx-namespace
  2. deployment "nginx-deployment" successfully rolled out

kubectl get deploy --watch命令監控其更新過程中Pod物件的變動過程

  1. kubectl get deploy nginx-deployment -n nginx-namespace --watch
  2. NAME READY UP-TO-DATE AVAILABLE AGE
  3. nginx-deployment 3/3 3 3 3h47m
  4. nginx-deployment 3/3 3 3 3h50m
  5. nginx-deployment 3/3 3 3 3h50m
  6. nginx-deployment 3/3 1 3 3h50m
  7. nginx-deployment 3/3 1 3 3h50m
  8. nginx-deployment 2/3 2 2 3h50m
  9. nginx-deployment 3/3 2 2 3h50m
  10. nginx-deployment 4/3 2 2 3h50m
  11. nginx-deployment 4/3 2 4 3h50m
  12. nginx-deployment 4/3 3 4 3h50m
  13. nginx-deployment 2/3 3 2 3h50m
  14. nginx-deployment 3/3 3 2 3h51m
  15. nginx-deployment 3/3 3 3 3h51m

檢視更新的版本

  1. kubectl rollout history deployment nginx-deployment -n nginx-namespace
  2. deployment.apps/nginx-deployment
  3. REVISION CHANGE-CAUSE
  4. 1 <none> #第一個版本是沒更新Pod之前的
  5. 2 <none> #目前我們在第二個版本

檢視版本詳細資訊

  1. kubectl rollout history deployment nginx-deployment --revision=1 -n nginx-namespace
  2. deployment.apps/nginx-deployment with revision #1
  3. Pod Template:
  4. Labels: app=nginx-proxy
  5. pod-template-hash=84d6c8c7cd #第一個版本的模版hash
  6. version=1.18.0
  7. Containers:
  8. nginx-proxy:
  9. Image: nginx:1.18.0 #第一個版本使用的1.18.0映象
  10. Port: 80/TCP
  11. Host Port: 0/TCP
  12. Environment: <none>
  13. Mounts: <none>
  14. Volumes: <none>
  15. kubectl rollout history deployment nginx-deployment --revision=2 -n nginx-namespace
  16. deployment.apps/nginx-deployment with revision #2
  17. Pod Template:
  18. Labels: app=nginx-proxy
  19. pod-template-hash=698f87c954 #第二個版本的模版hash
  20. version=latest
  21. Containers:
  22. nginx-proxy:
  23. Image: nginx:latest #第二個版本使用的latest映象
  24. Port: 80/TCP
  25. Host Port: 0/TCP
  26. Environment: <none>
  27. Mounts: <none>
  28. Volumes: <none>

3.通過kubectl set image命令直接修改由Deployment所管控Pod的映象
我們可以通過kubectl set image命令直接修改deployment控制器中Pod使用的映象,修改完後Pod就會自動更新。

  1. #set:在資源物件上設定特定功能
  2. #image:在資源物件上設定映象
  3. #deploy:指定我們資源及資源名稱
  4. #nginx:為容器名稱
  5. #nginx:latest:為映象版本
  6. kubectl set image deployment nginx-deployment nginx-proxy=nginx:1.17.10 -n nginx-namespace

檢視升級過程

檢視升級後的映象版本

  1. kubectl get pods -n nginx-namespace -o custom-columns=Name:metadata.name,Image:spec.containers[0].image
  2. Name Image
  3. nginx-deployment-7764fd4547-gjq5s nginx:1.17.10
  4. nginx-deployment-7764fd4547-rxscv nginx:1.17.10
  5. nginx-deployment-7764fd4547-xgp9c nginx:1.17.10

4.通過kubectl patch命令直接修改控制器清單中的任何內容
將升級等待時間改為5秒

  1. kubectl patch deployment nginx-deployment -p '{"spec": {"minReadySeconds": 5}}' -n nginx-namespace

kubectl patch命令的補丁形式為JSON格式,以-p選項指定,上面命令中的'{"spec": {"minReadySeconds": 5}}'表示設定spec.minReadySeconds為5秒,若要改變Pod的映象,也可以使用patch命令,但我們往往不使用kubectl patch命令修改映象。

Deployment控制器金絲雀釋出

Deploymnet控制器還支援自定義控制更新過程中的滾動節奏,如“暫停”pause或“繼續”resume更新操作,尤其是藉助於上面降到的maxSurgemaxUnavailable屬性還能實現更為精巧的過程控制,比如,待第一批新的Pod資源建立完成後立即暫停更新過程,此時,僅存在一小部分新版本的應用,主體部分還是舊的版本,然後在根據使用者特徵精心篩選出小部分使用者的請求路由至新版本的Pod應用,並持續觀察其是否穩定地按期望的方式執行。確定沒有問題後在繼續完成餘下Pod資源的滾動更新,否則立即回滾更新操作。這便是所謂的金絲雀釋出Canary Release

擴充套件知識:礦井中的金絲雀
17世紀時,英國礦井工人發現,金絲雀對瓦斯這種氣體十分敏感。空氣中哪怕有極其微量的瓦斯氣體,金絲雀也會停止歌唱;當瓦斯含量超過一定限度時,人類依舊毫無察覺,而金絲雀卻早已毒發身亡。當時採礦裝置相對簡陋的條件下,工人們每次下井都會帶上一隻金絲雀作為瓦斯檢測工具,以便在危險的情況下緊急撤離。

為了儘可能地降低對現有系統及其容量的影響,金絲雀釋出過程中通常建議採用“先新增、再刪除”,且可用Pod資源物件總數不低於期望值的方式進行。首次新增的Pod物件數量取決於其接入的第一批請求的規則及單個Pod承載能力,視具體需求而定。

1.檢視現存Pod狀態
現存Pod使用nginx: 1.17.10版本映象

  1. kubectl get pods -n nginx-namespace -o custom-columns=Name:metadata.name,Image:spec.containers[0].image
  2. Name Image
  3. nginx-deployment-7764fd4547-gjq5s nginx:1.17.10
  4. nginx-deployment-7764fd4547-rxscv nginx:1.17.10
  5. nginx-deployment-7764fd4547-xgp9c nginx:1.17.10

2.配置清單修改如下

  1. cat nginx-deploy.yaml
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: nginx-deployment
  6. namespace: nginx-namespace
  7. annotations:
  8. deployment.k8sops.cn/type: nginx-deploy
  9. labels:
  10. app: nginx-deploy
  11. spec:
  12. replicas: 3
  13. minReadySeconds: 10 #每個Pod升級後的等待時長
  14. revisionHistoryLimit: 6
  15. strategy:
  16. type: RollingUpdate
  17. rollingUpdate:
  18. maxSurge: 1
  19. maxUnavailable: 0 #升級過程中不可用的Pod為0個
  20. selector:
  21. matchLabels:
  22. app: nginx-proxy
  23. template:
  24. metadata:
  25. namespace: nginx-namespace
  26. labels:
  27. app: nginx-proxy
  28. version: latest
  29. spec:
  30. containers:
  31. - name: nginx-proxy
  32. image: nginx:latest #使用nginx:latest版本映象
  33. ports:
  34. - containerPort: 80
  35. name: http

下面將使用kubectl apply進行對容器進行進行更新,在更新過程中我們使用kubectl rollout pause命令來暫停更新,然後檢視其更新狀態。

3.更新deployment控制器並暫停

  1. #更新deployment控制器
  2. kubectl apply -f nginx-deploy.yaml
  3. #更新大概幾秒後暫停更新
  4. kubectl rollout pause deploy nginx-deployment -n nginx-namespace

4.檢視當前控制器狀態

  1. kubectl describe deploy nginx-deployment -n nginx-namespace

如下圖所示:
deployment控制器呼叫了一個新的ReplicaSet控制器nginx-deployment-698f87c954啟動了一個新的Pod,使用的是nginx:latest 映象,

檢視當前Pod數量,由於我們在清單中通過maxUnavailable引數設定升級過程中不可用的Pod為0個,所以我們在啟動新Pod的時候,不會將原來舊的Pod移除

  1. kubectl get pods -o wide -n nginx-namespace
  2. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  3. nginx-deployment-698f87c954-hn7wh 1/1 Running 0 2m14s 10.244.3.139 k8s-node01 <none> <none>
  4. nginx-deployment-7764fd4547-gjq5s 1/1 Running 0 15h 10.244.3.138 k8s-node01 <none> <none>
  5. nginx-deployment-7764fd4547-rxscv 1/1 Running 0 15h 10.244.3.136 k8s-node01 <none> <none>
  6. nginx-deployment-7764fd4547-xgp9c 1/1 Running 0 15h 10.244.3.137 k8s-node01 <none> <none>

檢視當前Pod使用的映象版本,如下nginx-deployment-698f87c954-hn7wh Pod是新啟動的Pod

  1. kubectl get pods -n nginx-namespace -o custom-columns=Name:metadata.name,Image:spec.containers[0].image
  2. Name Image
  3. nginx-deployment-698f87c954-hn7wh nginx:latest
  4. nginx-deployment-7764fd4547-gjq5s nginx:1.17.10
  5. nginx-deployment-7764fd4547-rxscv nginx:1.17.10
  6. nginx-deployment-7764fd4547-xgp9c nginx:1.17.10

監控Pod的狀態可以發現如下,控制器建立並啟動了一個新的Pod

最後Pod可用數量為4個,就緒Pod為3個

通過kubectl rollout status檢視控制器更新狀態,可以看到,在建立一個新版本的Pod資源後滾動更新暫停

  1. kubectl rollout status deploy nginx-deployment -n nginx-namespace
  2. Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...

檢視當前ReplicaSet控制器數量,目前新的RS控制器是nginx-deployment-698f87c954

  1. kubectl get rs -n nginx-namespace -o wide
  2. NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
  3. nginx-deployment-698f87c954 1 1 1 16h nginx-proxy nginx:latest app=nginx-proxy,pod-template-hash=698f87c954
  4. nginx-deployment-7764fd4547 3 3 3 15h nginx-proxy nginx:1.17.10 app=nginx-proxy,pod-template-hash=7764fd4547
  5. nginx-deployment-84d6c8c7cd 0 0 0 20h nginx-proxy nginx:1.18.0 app=nginx-proxy,pod-template-hash=84d6c8c7cd

暫停更新後,我們可以通過網路策略將service或者Ingress資源的流量引入新建立的Pod之上進行釋出驗證,執行一段時間後,如果確認沒有問題,即可使用kubectl rollout resume命令繼續此前的滾動更新過程:

5.恢復更新

  1. kubectl rollout resume deploy nginx-deployment -n nginx-namespace

6.檢視更新過程

  1. kubectl rollout status deploy nginx-deployment -n nginx-namespace
  2. Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
  3. Waiting for deployment spec update to be observed...
  4. Waiting for deployment spec update to be observed...
  5. Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
  6. Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
  7. Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
  8. Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
  9. Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
  10. Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
  11. Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
  12. Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
  13. Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
  14. deployment "nginx-deployment" successfully rolled out

如下看到更新過程中,始終的就緒Pod都為3

我們可以使用多種命令動態檢測更新過程中的deploy狀態,Pod狀態等,以下列出幾個

動態檢視deploy控制器狀態變化:kubectl get deploy nginx-deployment -n nginx-namespace --watch
動態檢視Pod狀態變化:kubectl get pods -o wide -n nginx-namespace --watch
動態檢視Pod映象變化:kubectl get pods -n nginx-namespace -o custom-columns=Name:metadata.name,Image:spec.containers[0].image --watch
動態檢視控制器更新過程:kubectl rollout status deploy nginx-deployment -n nginx-namespace
檢視deploy控制的時間資訊:kubectl describe deploy nginx-deployment -n nginx-namespace
動態檢視被deploy呼叫的RS控制器變化:kubectl get rs -n nginx-namespace -o wide --watch

Deployment控制器回滾操作

如果在釋出過程後導致某種問題,或者金絲雀“遇險”等,則需要將該應用回滾到此前的版本,或則回滾到由使用者指定的歷史記錄的版本。Deployment控制器的回滾操作可使用kubectl rollout undo命令完成。

1.檢視釋出的歷史記錄
通過kubectl rollout history命令可以看到控制器的版本記錄

  1. kubectl rollout history deploy nginx-deployment -n nginx-namespace
  2. deployment.apps/nginx-deployment
  3. REVISION CHANGE-CAUSE
  4. 1 <none>
  5. 3 <none>
  6. 4 <none>

2.檢視釋出歷史版本的詳細資訊
通過kubectl rollout history --revision=[number]命令可以看到某個版本的詳細記錄

  1. kubectl rollout history deploy nginx-deployment -n nginx-namespace --revision=3
  2. deployment.apps/nginx-deployment with revision #3
  3. Pod Template:
  4. Labels: app=nginx-proxy
  5. pod-template-hash=7764fd4547
  6. version=latest
  7. Containers:
  8. nginx-proxy:
  9. Image: nginx:1.17.10
  10. Port: 80/TCP
  11. Host Port: 0/TCP
  12. Environment: <none>
  13. Mounts: <none>
  14. Volumes: <none>

3.回滾到上一個版本
回滾到上一個版本直接使用kubectl rolloute undo命令即可完成

  1. kubectl rollout undo deploy nginx-deployment -n nginx-namespace

4.查看回滾後的映象版本

  1. kubectl get pods -n nginx-namespace -o custom-columns=Name:metadata.name,Image:spec.containers[0].image --watch
  2. Name Image
  3. nginx-deployment-7764fd4547-g7zhv nginx:1.17.10
  4. nginx-deployment-7764fd4547-lj5n9 nginx:1.17.10
  5. nginx-deployment-7764fd4547-qjxw7 nginx:1.17.10

5.回滾到指定版本
通過kubectl rollout undo --to-revision=[number]來進行回滾到指定版本

  1. kubectl rollout undo deploy nginx-deployment --to-revision=1 -n nginx-namespace

回滾操作中,其revision記錄中的資訊會發生變動,回滾操作會被當作一次滾到更新追加到歷史記錄中,而被回滾的條目則會被刪除,需要注意的是,如果此前的滾動更新過程處於"暫停"狀態,那麼回滾操作就需要先將Pod模版的版本改回到之前的版本,然後“繼續”更新,否則將一直處於暫停狀態而無法回滾。