概述#
上一章介紹完六種常見的部署策略,本章一次練習其中兩種:Rolling Update 與 Recreate。它們之所以最容易實作,是因為它們本來就是 Deployment 內建可選的兩種 Pod 汰換策略,只要在 spec.strategy 切換型別就能切換行為。
1. 重建部署(Recreate)#
Recreate 是 Deployment 最簡單的策略,只需要把 spec.strategy.type 設為 Recreate。設定後,Deployment 會先把所有舊版本 Pod 終止,再以新版本重新建立。意味著服務的停機時間會等於應用關閉與啟動的時間,因此並不建議用於生產環境。
建立 v1 版本#
# app-v1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: foo-deployment
labels:
app: foo
spec:
replicas: 3
strategy:
type: Recreate
selector:
matchLabels:
app: foo
template:
metadata:
labels:
app: foo
version: v1
spec:
containers:
- name: foo
image: mikehsu0618/foo
ports:
- containerPort: 8080部署:
kubectl apply -f app-v1.yaml另一個終端開 watch 觀察:
kubectl get pods --watch升級到 v2#
v2 設定僅將 template.metadata.labels.version 由 v1 改為 v2(其餘欄位保持不變):
# app-v2.yaml(僅顯示差異)
spec:
template:
metadata:
labels:
app: foo
version: v2 # 由 v1 改成 v2kubectl apply -f app-v2.yaml回頭看 watch 視窗,可以清楚觀察到所有舊 Pod 同時進入 Terminating,等全部終止後才開始建立新版本的 Pod:
foo-deployment-8555547446-ld8fs 1/1 Running 0 8s
foo-deployment-8555547446-nbt2k 1/1 Terminating 0 21s
foo-deployment-8555547446-ld8fs 1/1 Terminating 0 22s
foo-deployment-8555547446-w6m5q 1/1 Terminating 0 22s
foo-deployment-6cbc7db745-vgmmq 0/1 Pending 0 0s
foo-deployment-6cbc7db745-8n6c7 0/1 ContainerCreating 0 0s
foo-deployment-6cbc7db745-5t7p6 1/1 Running 0 8sRecreate 過程中所有舊 Pod 會同時下線,務必確認應用允許短暫停機再使用。
2. 滾動部署(Rolling Update,Ramped)#
Rolling Update 是 Deployment 的預設策略;不特別宣告時,Pod 會以小步快跑、細水長流的方式緩緩替換。如果想顯式指定,把 spec.strategy.type 設為 RollingUpdate,並透過 spec.strategy.rollingUpdate.{maxSurge,maxUnavailable} 控制速率。
建立 v1 版本#
# app-v1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: foo-deployment
labels:
app: foo
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: foo
template:
metadata:
labels:
app: foo
version: v1
spec:
containers:
- name: foo
image: mikehsu0618/foo
ports:
- containerPort: 8080兩個重要旋鈕:
maxSurge:一次最多可以多開幾個 Pod。maxUnavailable:滾動過程中可以容忍幾個 Pod 不可用。
部署:
kubectl apply -f app-v1.yaml
kubectl get pods --watch升級到 v2#
同樣只改 template.metadata.labels.version 為 v2:
# app-v2.yaml(僅顯示差異)
spec:
template:
metadata:
labels:
app: foo
version: v2 # 由 v1 改成 v2kubectl apply -f app-v2.yamlwatch 視窗會看到新 Pod 與舊 Pod 交錯啟動/終止,依照 maxSurge=1、maxUnavailable=0 的設定逐一替換:
foo-deployment-6cbc7db745-vh8tn 0/1 Pending 0 0s
foo-deployment-6cbc7db745-vh8tn 1/1 Running 0 7s
foo-deployment-8555547446-vwtp4 1/1 Terminating 0 104s
foo-deployment-6cbc7db745-crhgt 1/1 Running 0 6s
foo-deployment-8555547446-kg5f7 1/1 Terminating 0 110s
foo-deployment-6cbc7db745-5q5tf 1/1 Running 0 5s
foo-deployment-8555547446-mrmb8 1/1 Terminating 0 115s如此一來新版本始終維持至少 3 個 Pod 可服務,舊版本則陸續被替換掉,達到不中斷的滾動更新。
小結#
Recreate 與 Rolling Update 是 Deployment 內建的兩種策略,最容易上手也最常被使用。值得提醒:部署策略並不是互斥技術,後續章節會看到把 Rolling Update 與 Service / Ingress 的流量切換組合起來,就能拼出 Blue-Green、Canary 等更進階的玩法。
原文出處#
- GitHub:https://github.com/MikeHsu0618/2022-ithelp/tree/main/Day13
- iThome:https://ithelp.ithome.com.tw/articles/10289913