一、更新執行在 Pod 內的應用程式
1. 修改 Pod 模板
將導致應用程式在一定時間內不可用
2. 修改 Service 的 Pod 選擇器
需要同時執行兩倍的 Pod
3. 滾動升級
應用程式需支援兩個版本同時對外提供服務
舊版本 ReplicationController 縮容,同時新版本擴容
通過新舊 ReplicationController 副本數的改變,逐漸將所有 Pod 替換成新版本,結束後刪除原有的 ReplicationController
二、使用 Deployment
用於部署應用程式,並以宣告的方式升級應用
建立 Deployment 時自動建立 ReplicaSet,Pod 由 ReplicaSet 建立和管理
1. 建立 Deployment
定義類似於 ReplicationController。但能指定部署策略:在修改 Deployment 資源時如何執行更新
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubia
spec:
replicas: 3
selector:
matchLabels:
app: kubia
template:
metadata:
name: kubia
labels:
app: kubia
spec:
containers:
- image: luksa/kubia:v1
name: nodejs
# --record:記錄歷史版本號
$ kubectl create -f kubia-deployment-v1.yaml --record
# 檢視部署狀態
$ kubectl rollout status deployment kubia
deployment "kubia" successfully rolled out
# 檢視部署的資源
$ kubectl get all
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/kubia 3/3 3 3 3m34s
NAME DESIRED CURRENT READY AGE
replicaset.apps/kubia-59d857b444 3 3 3 3m34s
NAME READY STATUS RESTARTS AGE
pod/kubia-59d857b444-4c7v8 1/1 Running 0 3m34s
pod/kubia-59d857b444-7r76k 1/1 Running 0 3m34s
pod/kubia-59d857b444-lrjtp 1/1 Running 0 3m34s
- ReplicaSet 建立的 Pod 名稱是由 ReplicaSet 名稱加上執行時生成的隨機字串組成的
- Deployment 建立的 ReplicaSet 包含 Pod 模板的雜湊值
2. 升級 Deployment
只需修改 Deployment 資源中定義的 Pod 模板,K8s 會自動將系統狀態收斂到定義的狀態
升級策略:
- RollingUpdate:滾動更新。預設策略
- 漸進刪除舊 Pod,同時建立新 Pod
- Pod 數量會浮動,其上下限可配置
- Recreate:一次性刪除所有舊 Pod,之後建立新 Pod
- 適用:系統不支援多個版本同時對外提供服務。但會出現短暫不可用
演示 RollingUpdate
# 1. 減慢滾動升級速度
# kubectl patch 常用於修改單個或少量資源屬性,無需編輯器編輯
$ kubectl patch deployment kubia -p '{"spec": {"minReadySeconds": 10}}'
# 因為 Pod 模板沒變,故不會觸發滾動升級
# 2. 觸發滾動升級
# 指定新的映象(可設定任何包含容器的資源)
$ kubectl set image deployment kubia nodejs=luksa/kubia:v2
# 3. 檢視滾動升級
$ while true; do curl 10.109.157.15; done
# 可以看到剛開始請求 v1,後來慢慢全部切換到 v2
升級過程由 Deployment 控制器完成。流程為:建立新的 ReplicaSet 然後擴容,同時之前的 ReplicaSet 會縮容至 0。舊的 ReplicaSet 仍被保留
若 Deployment 的 Pod 模板引用了 ConfigMap/Secret,更改 ConfigMap/Secret 資源本身不會觸發升級操作
若想觸發更新可建立新的 ConfigMap/Secret 並修改模板引用
3. 回滾 Deployment
使用新映象
# v3 版本請求 5 次後會出錯
$ kubectl set image deployment kubia nodejs=luksa/kubia:v3
# 檢視整個升級過程
$ kubectl rollout status deployment kubia
# 模擬應用出錯
$ while true; do curl 10.109.157.15; done
回滾
# 回滾到先前版本
$ kubectl rollout undo deployment kubia
# 顯示升級的版本(歷史版本號會被儲存到 ReplicaSet 中)
$ kubectl rollout history deployment kubia
deployment.apps/kubia
REVISION CHANGE-CAUSE # 若不指定 --record,CHANGE-CAUSE 會為空
1 kubectl create --filename=kubia-deployment-v1.yaml --record=true
3 kubectl create --filename=kubia-deployment-v1.yaml --record=true
4 kubectl create --filename=kubia-deployment-v1.yaml --record=true
# 回滾到指定版本
$ kubectl rollout undo deployment kubia --to-revision=1
undo 也可以在滾動升級過程中執行:停止升級並刪除已建立 pod
可通過指定 Deployment 的 revisionHistoryLimit 來限制歷史版本數量,預設 10
4. 控制滾動升級速率
spec:
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
- maxSurge:決定 Deployment 配置中期望的副本數之外,最多允許超出的 Pod 例項數量。預設值為 25%(四捨五入)
- maxUnavailable:決定在滾動升級期間,相對於期望副本數能夠允許多少 Pod 例項處於不可用狀態。預設值為 25%(四捨五入)
本例中,replicas=3,因此 Pod 數最多可達到 4 且必須有 2 個 Pod 可用
5. 暫停滾動升級
只升級部分,方便使用者驗證新版本 Pod
kubectl set image deployment kubia nodejs=luksa/kubia:v4
kubectl rollout pause deployment kubia
# 這樣會建立一個(數量不可控)新的 Pod
# 若部署被暫停,在恢復部署之前,撤銷命令不會撤銷它
恢復滾動升級
kubectl rollout resume deployment kubia
暫停功能還可用於阻止更新 Deployment 後的自動升級行為。可更改多次,完成更改後再升級
6. 滾動升級前檢查
minReadySeconds 屬性主要是避免部署出錯版本的應用,而不是單單減緩部署的速度。它指定新建立的 Pod 至少要成功執行多久之後,才能將其視為可用。在 Pod 可用前,滾動升級的過程不會繼續
當容器的所有就緒探針都返回成功時,Pod 被標記為就緒狀態。Pod 就緒後等待 minReadySeconds 後才可用,才繼續滾動升級
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubia
spec:
# 更新可以不用加 replicas
selector:
matchLabels:
app: kubia
minReadySeconds: 10
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0 # 挨個替換
type: RollingUpdate
template:
metadata:
name: kubia
labels:
app: kubia
spec:
containers:
- image: luksa/kubia:v3
name: nodejs
readinessProbe:
periodSeconds: 1 # 1s 執行一次就緒探針
httpGet: # 探針傳送的請求
path: /
port: 8080
kubectl apply -f kubia-deployment-v3.yaml
預設 10min(spec.progressDeadlineSeconds)內不能完成滾動升級就視為失敗,滾動升級會自動取消
可通過 rollout undo 取消滾動升級
修改資源的不同方式
方法 | 作用 | 例子 |
---|---|---|
kubectl edit | 使用預設編輯器開啟資源配置 | kubectl edit pod test |
kubectl patch | 修改單個資源屬性 | kubectl patch pod test -p '{"spec": {"replicas": 4}}' |
kubectl apply | 通過 YAML/JSON 檔案修改或建立資源 | kubectl apply -f test.yaml |
kubectl replace | 通過 YAML/JSON 檔案修改資源(資源需存在) | kubectl replace -f test.yaml |
kubectl set image | 修改包含容器資源的映象 | kubectl set image pod test nodejs=kubia:v2 |
映象拉取策略
- 若更改後的映象推到相同的 tag,會導致映象不被重新拉取。可設定容器的 imagePullPolicy 為 Always
- 若容器使用 latest 的 tag,則 imagePullPolicy 預設為 Always,否則為 IfNotPresent
命令
kubectl delete pod --all
kubectl set selector ...
# 提高日誌級別,輸出所有 kubectl 發起的 API 伺服器請求
kubectl ... --v 6