iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 12
0

Deployment 是一種無狀態的水平擴展控制器,主要功能也是確保Pod能正常運作, 它建構在Pod和ReplicaSets之上, 可以為Pod和ReplicaSets提供聲明式更新, 大部分的功能都可以透過調用ReplicaSet Controller來實現。它能根據資源狀況分配Pod到各節點,並提供滾動更新與回滾的功能。

https://ithelp.ithome.com.tw/upload/images/20200915/201296565peXa1IOGV.png

圖片參考書:【Kubernetes 進階實踐】

Deployment 特性:

  • 事件與狀態查看: 可以記錄每一次的操作, 包含deployment object 升級的詳細進度與狀態。
  • 回滾: 更新後發現問題可以指定返回到歷史紀錄中的上一個版本。
  • 版本紀錄: 對每一個object的操作都會保存下來, 為了後續可能操作的回滾做準備。
  • 暫停和啟動: 每一次的升級都能夠隨時暫停和啟動。
  • 多種自動更新方案:
    1. Recreate: 全面停止、刪除舊的Pod之後以新版本重建。
    2. RollingUpdate: 逐步替換舊有的Pod直到全部更新為新版本為止。

創建 Deployment

由於它建構在ReplicaSet之上, 所以spec中的字段包含ReplicaSet Controller的replicas, selector, template, minReadySeconds, 他也是利用這些字段內容完成了下一層的ReplicaSet創建。

  • 創建YAML範例
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-example
spec:
  replicas: 3
  selector:
    matchLabels:
      app: deploy-demo
  template:
    metadata:
      labels:
        app: deploy-demo
    spec:
      containers:
      - name: deploy-hello
        image: nginx:latest
        ports:
        - name: http
          containerPort: 80
  minReadySeconds: 5
  • 執行
-> % kubectl apply -f deploy-demo.yaml --record
deployment.apps/deploy-example created
  • 查看狀態
-> % kubectl get deploy
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
deploy-example     3/3     3            3           117s

UP-TO-DATE 表示達到期望狀態的數量
AVAILABLE 表示處於可用狀態的數量

  • deployment 部署後會自動創建相關的replicsset, 並使用相同的標籤選擇器
-> % kubectl get replicasets -l app=deploy-demo -L app
NAME                        DESIRED   CURRENT   READY   AGE     APP
deploy-example-5b9b49dd7d   3         3         3       6m55s   deploy-demo

由此可知 deployment大部分都和ReplicaSet相同, 最大的不同在於 deployment支援滾動更新, 這也是為什麼deployment是被實踐最多的Controller。

更新策略

Deployment 支援兩種自動更新方案:
1. Recreate: 全面停止、刪除舊的Pod之後以新版本重建。
這也是ReplicaSet的更新方式, 他會導致新舊版本更新期間服務中斷, 優點是服務不會有中間狀態, 不是新版本就是舊版本。

2. RollingUpdate: 逐步替換舊有的Pod直到全部更新為新版本為止。
   Deployment更新策略 `default` 為滾動更新, 在刪除舊版本的同時也在創建新版本, 優點是服務不中斷, 缺點是在更新期間執行的請求不保證會是新版本。

Deployment的滾動更新會將新舊版本拆成兩個ReplicaSet Controller 同時分別執行, V1少一個Pod的同時, V2就多一個Pod, 會一直執行到V2版本的Pod符合期望值為止。
https://ithelp.ithome.com.tw/upload/images/20200915/20129656wn25Hvn6Y3.png

圖片參考書:【Kubernetes 進階實踐】

Canary Release (金絲雀發布)

Deployment 支援自訂義滾動更新的節奏, 包含暫停(pause)和繼續(resume), 可以在一個新的pod建立成功之後就先暫停更新, 讓環境中同時存在新舊版本, 用戶再針對新版本進行檢測, 沒問題就繼續更新, 有問題也可以執行回滾, 這就是金絲雀發布的概念。

礦井中的金絲雀
17世紀, 美國礦場的工人發現金絲雀對於瓦斯十分敏感, 空氣中哪怕只有微量的瓦斯氣體, 金絲雀也會停止歌唱;當瓦斯含量超過一定濃度時, 人類可能尚未察覺, 金絲雀卻早已中毒身亡。在當時採礦設備相對簡陋的情況下, 工人在下礦場之前都會帶上一隻金絲雀當作瓦斯檢測工具, 以便在危險情況下緊急撤離。

https://ithelp.ithome.com.tw/upload/images/20200916/20129656KPZRsBezIf.png

圖片參考書:【Kubernetes 進階實踐】

先添加, 再刪除, 保持可用的Pod數量超過期望值, 這就是金絲雀的概念。

回滾

因為各種原因導致滾動更新無法正常執行,例如image拉不到或是金絲雀死掉的狀況, 就要執行回滾。

查看歷史版本

先apply一個deployment, image: nginx:latest, 修改YAML:image: nginx:v1.0.0 再apply一次
之後查看歷史版本會有兩筆:

-> % kubectl rollout history deployments deploy-example
deployment.apps/deploy-example
REVISION  CHANGE-CAUSE
1         kubectl apply --filename=deploy-demo.yaml --record=true
2         kubectl apply --filename=deploy-demo.yaml --record=true

先看一下目前的deployment內容:
https://ithelp.ithome.com.tw/upload/images/20200916/20129656XAUvfGhEhz.png

kubectl 操作有三種回滾方式

  • Rollback to the previous deployment

    kubectl rollout undo deployment/abc
    
  • Rollback to daemonset revision 3

    kubectl rollout undo daemonset/abc --to-revision=3
    
  • Rollback to the previous deployment with dry-run

    kubectl rollout undo --dry-run=true deployment/abc
    
  • 這邊試試看第1種, 回滾到上一版

    -> % kubectl rollout undo deployment/deploy-example
    deployment.apps/deploy-example rolled back
    
  • deployment內容
    https://ithelp.ithome.com.tw/upload/images/20200916/20129656PbKIorIN7C.png

  • 再看一次歷史版本也會異動

    -> % kubectl rollout history deployments deploy-example
    deployment.apps/deploy-example
    REVISION  CHANGE-CAUSE
    2         kubectl apply --filename=deploy-demo.yaml --record=true
    3         kubectl apply --filename=deploy-demo.yaml --record=true
    

回滾也會被當作一次滾動更新寫到歷史紀錄中, 但是被回滾的紀錄會被刪除掉, 所以仍舊是2筆記錄。
如果修改YAML:image: nginx:v1.2.0 再apply一次, 因為是一般的滾動更新,
再查看歷史版本紀錄的時候, 就會看到3筆喔!

  • 回滾時如果前一次的更新停在pause狀態, 要先把PodTamplate改回到前一版然後resume, 否則會因為狀態一直處於暫停而無法進行回滾。

伸縮與擴充

和ReplicaSet一樣, 只差在對象不同, 這邊就跳過了。


上一篇
day 11 Pod Controller(1) - ReplicaSet
下一篇
day 13 Pod Controller(3) - DaemonSet
系列文
K8S - 30天從擦槍到提槍上陣學習筆記。30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言