iT邦幫忙

2024 iThome 鐵人賽

DAY 19
1
Kubernetes

Kubernetes圖解筆記系列 第 19

Day-19 Deployment:Rollback

  • 分享至 

  • xImage
  •  

更新失敗怎麼辦?! Σ(゚д゚lll)


更新上版難免會遇到更新失敗,或程式碼出狀況需要立即退版的情形,

既然 Deployment 做了版本控制,那一定也可以退回上一版對吧!

沒錯!作為容器管理領域的領導者,Kubernetes 自然也具備完善的例外處理機制。
Deployment 除了更新策略,也包含並自動執行滾動更新回滾操作,如果更新版本時失敗,可以自動回滾到先前的穩定版本,以此確保服務的高可用性。

在預設情況下,Deployment 部署的歷史記錄都保留在系統中,可以隨時 Rollback。

立刻就來實做看看 (((o(゚▽゚)o)))


先確認目前的部署版本

kubectl rollout history deployment <deployment-name>
# 也可以使用
kubectl rollout history deployment/<deployment-name>

https://ithelp.ithome.com.tw/upload/images/20240920/201684373XqkTUsTTc.png
目前最新版是 revision 3,如果要 rollback 到 revision 2 可以執行到上一版的指令:

kubectl rollout undo deployment nginx-deployment

https://ithelp.ithome.com.tw/upload/images/20240920/20168437l9zA2KpRYO.png
執行完成後再次執行 rollout history 可以發現 revision 多了新的一版:revision 4,但是revision 2 卻不見了。
這和 Kubernetes 的機制有關:

Deployment 從 revision 3 rollback 回 revision 2 時,Kubernetes 不是直接將元件調整回 reversion 2,而是建立了一個新的 revision (revision 4),這是為了避免混淆和衝突。
kubectl rollout 這個指令做的是 執行 rollback建立新版本,其本身不會直接刪除舊版本。
但是 Kubernetes 會 (⁎⁍̴̛ᴗ⁍̴̛⁎)
為了優化儲存和管理,Deployment 在建立新的 revision 時,會刪除與現版本 完全相同 的舊版本。

為什麼有些 CHANGE-CAUSE 有指令,有些卻是 <none>
差別在於更新用的指令!

# 這個會留下紀錄
kubectl apply -f nginx-deployment.yaml --record
# 這個不會
kubectl apply -f nginx-deployment.yaml

--record 指令可以用於更新時紀錄更新異動指令,不過當你真的下了這個指令就會發現...

Flag --record has been deprecated, --record will be removed in the future
deployment.apps/nginx-deployment configured

--record指令要被棄用啦!!!
畢竟 record 只能記下指令,要是每次都是更新 yaml 檔案,也只會出現一堆 kubectl apply -f nginx-deployment.yaml --record,根本也分不清楚誰是誰。

那要怎麼寫更新紀錄?
可以使用 kubernetes.io/change-cause 註解!
使用方式有兩種:

1. 直接加在 yaml file 中

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    kubernetes.io/change-cause: "Deployed with nginx:1.11.5"
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-app
  template:
    metadata:
      labels:
        app: nginx-app
    spec:
      containers:
      - name: nginx
        image: nginx:1.11.5
        ports:
        - containerPort: 80

metadata 中加上 annotationskubernetes.io/change-cause:<自行撰寫的更新訊息>,就可以將自訂的更新內容記錄在 history revision 中囉!
執行結果:
https://ithelp.ithome.com.tw/upload/images/20240920/20168437UbN7SxXty5.png

2. 用指令加上註解

再啟一個 Deployment2 (因為前一版已經被我試得亂七八糟了)
先不寫 annotations,直接執行 apply
https://ithelp.ithome.com.tw/upload/images/20240920/20168437TFtopPDXNx.png
然後修改 nginx 版本為 1.17,再次執行 apply 指令,完成後確認目前版本。
https://ithelp.ithome.com.tw/upload/images/20240920/20168437rbVmigXNhT.png
然後執行 annotate 指令:

kubectl annotate deployment <deployment-name> kubernetes.io/change-cause="更新說明"
# 範例
kubectl annotate deployment nginx-dp kubernetes.io/change-cause="Updated image to nginx:1.17"

https://ithelp.ithome.com.tw/upload/images/20240920/201684379sefh5YvCM.png
這樣就可以將註解加上去了... 嗎?

不見得喔(´・ω・`)
annotate 指令雖然可以把忘記寫的註記加上去,卻只是針對 Deployment 元件做異動。
分別確認建立用的 yaml 檔和 Kubernetes 中的 Deployment,yaml 檔並沒有加上註記。
https://ithelp.ithome.com.tw/upload/images/20240920/20168437wfsYO7PIe7.png
所以,如果往後繼續使用這個檔案做 apply,一樣不會留有異動紀錄。

另外,如果在這個情況直接用指令更新 Deployment...
https://ithelp.ithome.com.tw/upload/images/20240920/201684372LVf9N4mka.png
就會再次出現已經寫在 Deployment 中的紀錄。

雖然是可以再下一次 annotate 調整內容,但這樣下去沒完沒了啊!!!
只看 yaml file 也根本不會發現註記錯誤的問題。
所以還是比較推薦使用 yaml file 維護的時候就好好寫在檔案裡,沒事不要手動下指令改元件,避免一時不注意就變成維護上的困擾。

那可以 apply 的時候就直接寫好註解嗎?

嗯... 不行。
apply 指令無法和 annotate 同時執行。

那是不是不要同時就可以了?

... 我最討厭像你這樣直覺敏銳的工程師了
硬要做的話串聯指令執行的確也可以達到一樣的效果。

kubectl apply -f deployment-2.yaml && kubectl annotate deployment nginx-dp kubernetes.io/change-cause="Deployed with nginx:1.17"

但要是哪一次忘記寫就又會繞回到前面 yaml 檔與實際元件不同步的問題,不推薦
(但若是做成腳本運行又是另外一回事了)


小結

本篇介紹了使用 kubectl rolloutapplyannotate 等指令進行 Deployment 管理時,關於記錄版本和 Rollback 歷史的問題,要有效管理 Deployment 版本記錄(特別是在未來 --record 被移除的情況下),最建議的還是回歸到 yaml file 的版本控制。畢竟 yaml file 只是文檔,可以用來管理的工具多不勝數,甚至可以根據使用的佈版流程挑選最合適的來使用。如果能將管理方式整併進 CI/CD 流程中做自動化,不管是版本管理上還是將來做問題排查,想必都可以省下不少心力吧。


上一篇
Day-18 番外篇:kubectl apply
下一篇
Day-20 Namespace
系列文
Kubernetes圖解筆記26
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言