概述#
接續上一章 Deployment 內建的 Recreate 與 Rolling Update,這次我們把藍綠部署(Blue-Green Deployment)放上桌。Kubernetes 的優勢在於可以用 Service 或 Ingress 等資源自由地調度流量,所以即便沒有「藍綠」這種預設策略,我們仍能輕易把它的精神實作出來。本章用最直覺的 Service 做示範。
藍綠部署的特色#
藍綠部署是常見的零停機(Zero Downtime)策略:穩定、單純,且同一時間線上不會出現新舊版本並存的疑慮。代價是更新期間需要兩倍資源同時運作;只要資源能撐住,這通常是最划算的穩定性換時間方案。
落實步驟#
在 Kubernetes 中,藍綠部署的關鍵在於透過 Label 與 Selector 控制流量去向:
- 啟動 v1 版本,並用 Service 的 Label Selector 鎖定 v1 作為對外入口。
- 部署 v2 版本,待它完全就緒。此時新舊兩個版本同時存在。
- 把 Service 的 Selector 從 v1 切到 v2,瞬間完成版本切換。
- 確認穩定後,關閉舊的 v1 版本資源。
實戰練習#
1. 啟動 v1 版本與 Service#
# app-v1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: foo-deployment
labels:
app: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
version: v1
template:
metadata:
labels:
app: my-app
version: v1
spec:
containers:
- name: foo
image: mikehsu0618/foo
ports:
- containerPort: 8080# service.yaml
apiVersion: v1
kind: Service
metadata:
name: blue-green-service
spec:
selector:
app: my-app
version: v1
type: LoadBalancer
ports:
- protocol: TCP
port: 8080
targetPort: 8080Service 的 Selector 同時指定了
app: my-app與version: v1,所以對外只會看到 v1 版本。
部署並驗證:
kubectl apply -f app-v1.yaml -f service.yaml
kubectl get all
curl localhost:8080 # {"data":"Hello foo"}2. 預先把 v2 啟動起來#
# app-v2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: bar-deployment
labels:
app: bar
spec:
replicas: 3
selector:
matchLabels:
app: my-app
version: v2
template:
metadata:
labels:
app: my-app
version: v2
spec:
containers:
- name: bar
image: mikehsu0618/bar
ports:
- containerPort: 8080kubectl apply -f app-v2.yaml
kubectl get all此時叢集裡 v1 與 v2 都在運作,但對外仍只有 v1 接收流量:
curl localhost:8080 # 仍然回傳 {"data":"Hello foo"}3. 將 Service 的 Selector 切換到 v2#
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: blue-green-service
spec:
selector:
app: my-app
version: v2 # 從 v1 改為 v2
type: LoadBalancer
ports:
- protocol: TCP
port: 8080
targetPort: 8080kubectl apply -f service.yaml
kubectl describe service blue-green-service切換後 Service 的 Endpoints 會立刻指向 v2 對應的 Pod,再次測試:
curl localhost:8080 # {"data":"Hello bar"}4. 關閉舊的 v1 版本#
kubectl delete -f app-v1.yaml
kubectl get all只剩下 v2 的 bar-deployment,藍綠部署正式完成切換。
小結#
只用 Deployment 與 Service 就能拼出一條完整的藍綠流水線。重點在於把 Label 設計好、用 Selector 當成「流量開關」,瞬間完成版本切換並保留隨時回滾的能力。再次印證:Kubernetes 的部署策略並沒有死板的形式,能穩穩落實精神就是好設計。
原文出處#
- GitHub:https://github.com/MikeHsu0618/2022-ithelp/tree/main/Day14
- iThome:https://ithelp.ithome.com.tw/articles/10290317