iT邦幫忙

2024 iThome 鐵人賽

DAY 17
2
Kubernetes

Kubernetes圖解筆記系列 第 17

Day-17 Deployment:RollingUpdate

  • 分享至 

  • xImage
  •  

又到了 Demo 環節 ( ´ ▽ ` )ノ


來實測看看 Deployment 的 RollingUpdate 吧!

修改 Deployment 的 yaml 設定:
把版本從 1.14.2 換成 1.11.5

apiVersion: apps/v1
kind: Deployment
metadata:
  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

執行更新指令

kubectl apply -f <deployment yaml file>

利用 describe 指令確認目前的 Pod 版本:

kubectl describe pod nginx-deployment-756c76457c-mr79z

https://ithelp.ithome.com.tw/upload/images/20240918/20168437bI4ZnVzOxy.png

可以從 image 的內容看出 Pod 已經被更新成後來設定的 1.11.5版囉!
再看看 Deployment 的資訊:
https://ithelp.ithome.com.tw/upload/images/20240918/20168437QRDPohT3eQ.png
OldReplicaSetsNewReplicaSet 也可以看出版本已經更新。


執行過程中,可能會出現一段提醒訊息:

Warning: resource deployments/nginx-deployment is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically. deployment.apps/nginx-deployment configured

蛤?什麼意思?

kubectl.kubernetes.io/last-applied-configuration 是 Kubernetes 中的重要annotation
它有兩個用途:

  • 儲存前一次使用者透過 kubectl apply 命令執行的完整資源配置。
  • 允許 kubectl 追蹤資源變更紀錄,並在往後的 apply 操作中協助使用者更新。
    當執行 apply 指令時,kubectl 會比較新的設定、目前的資源狀態和這個註解中的前一次配置共三種版本,並判斷正確的部署。
    不過如果資源被手動編輯過(而非使用 yaml 檔執行 kubectl apply),這個註解的紀錄就可能會與實際狀態不同步,在這種情況下,後續執行 apply 操作可能會產生意外的結果。

舉個 🌰:
如果部署一個沒有設定 replicasDeployment 會發生什麼事?
https://ithelp.ithome.com.tw/upload/images/20240918/201684370O8yL3tsmT.png

部署成功啦 (´・Д・)」
https://ithelp.ithome.com.tw/upload/images/20240918/20168437lI6IBRjoe8.png

這時候如果使用 kubectl apply 修改 image 版本,也可以正常更新且不影響目前的 replicas 設定。
這是因為 replicas 其實不屬 kubectl管理範圍,展開 last-applied-configuration

{
  "apiVersion": "apps/v1",
  "kind": "Deployment",
  "metadata": {
    "annotations": {},
    "name": "demo-deployment",
    "namespace": "default"
  },
  "spec": {
    "selector": {
      "matchLabels": {
        "app": "demo"
      }
    },
    "template": {
      "metadata": {
        "labels": {
          "app": "demo"
        }
      },
      "spec": {
        "containers": [
          {
            "image": "nginx:1.14.2",
            "name": "nginx",
            "ports": [
              {
                "containerPort": 80
              }
            ]
          }
        ]
      }
    }
  }
}

從標注內容就可以清楚識別哪些資訊才是屬於 kubectl apply 的比對範圍囉!

總之,這段訊息只是提醒這個 Deployment 沒有執行 apply 指令需要的 last-applied-configuration,而這個遺失的標注(annotation)將會被自動補上。
我們可以透過指令來確認:

kubectl get deployment nginx-deployment -o yaml

https://ithelp.ithome.com.tw/upload/images/20240918/20168437OF8GbBKM1l.png
可以看見 Deploymentmetadata 的確是被補上 kubectl.kubernetes.io/last-applied-configuration 了。
之後再次執行 apply 就不會再跳出訊息啦!

如果記得的話,也可以在 create 的時候加上 --save-config 去建立標注:

kubectl create --save-config -f <deployment yaml file>

補充資訊:kubectl applykubectl replace

在 kubectl 指令中,applyreplace 都可以更新資源,兩者的差別在Day-11:kubectl 中提過的命令式和宣告式。

  • kubectl apply 是宣告式,它會保留未變更的內容,僅修改配置中更新的部分。
  • kubectl replace 則是命令式,它會無視原有配置並完全按照新設定重新建立資源。
    也就是說,如果發生 🌰 中誤刪資訊的情況又使用 kubectl replace 做更新,就很有可能會建置出與預期不符的資源。

在實務管理上建議使用 apply,避免直接針對資源做異動(比如直接去改 Pod 的內容)。


咳咳,扯遠了。
如果覺得要下一大堆指令去確認更新狀態很麻煩,可以透過指令:

kubectl rollout history deployment/<deployment name>

來確認更新紀錄。

再次修改 Deployment 的 yaml 設定:
把版本從 1.11.5 換回 1.14.2,並再次執行 kubectl apply 指令。
(這次的確沒有再出現 Warning)
然後調閱更新紀錄:

kubectl rollout history deployment/<deployment name>

https://ithelp.ithome.com.tw/upload/images/20240918/2016843736XNRCeSGv.png

  • revision:修訂版本
    Deployment 的屬性為 revisionHistoryLimit,未指定時預設為 10,超過這個數量的舊版本將會被自動刪除。
    (字太多了直接看截圖的最後一行)
    https://ithelp.ithome.com.tw/upload/images/20240918/20168437582Iwu9X2H.png
    透過調整 revisionHistoryLimit 就可以設定要保留的歷史修訂版本數量囉!

透過--revision指令可以看到每一個版本的部署內容:

kubectl rollout history deployment/nginx-deployment --revision=<欲調閱的版本號>

https://ithelp.ithome.com.tw/upload/images/20240918/20168437mImTfgbt2N.png
用這個方式可以快速的確認異動紀錄。

對了,要更新 image 除了修改 yaml 再執行 apply 更新之外,其實也可以使用指令調整:

kubectl set image deployment <deployment-name> <container-name>=<new image>
# 範例
kubectl set image deployment nginx-deployment nginx=nginx:1.17

不過,這種透過指令直接修改元件的方式並不利於後續維護,相關的操作並不會同步回 yaml 設定上,往後在部署新版本的時候也難以查詢異動軌跡,很容易就會把改動過的內容覆蓋掉了。

用在測試或自行練習的時候倒是很方便。

最後補充幾個操作指令:

  • 查詢 Update 狀態
kubectl rollout status deployment <deployment-name>
  • 暫停 Update
kubectl rollout pause deployment <deployment-name>
  • 繼續執行
kubectl rollout resume deployment <deployment-name>

小結

雖說一般執行 Deployment 更新,都會建議使用 apply 比較保險,但也不是說 replace 就沒用處了。在 Kubernetes 的預設值中,有些資訊是不能透過 apply 指令做修改的。這時候,就需要使用 replace 讓資源刪除後重新建立才能順利更新。


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

尚未有邦友留言

立即登入留言