k8s通過service標簽實現藍綠發布
- 通過`k8s service label`標簽實現`藍綠發布`
- 方法1:使用kubelet完成藍綠切換
- 1. 創建綠色版本
- 1.1 創建綠色版本 Deployment
- 1.2 創建綠色版本 Service
- 2. 創建藍色版本
- 2.1 創建藍色版本 Deployment
- 2.2 創建藍色版本 Service
- 3. 創建`藍綠切換SVC` (用于外部訪問)
- 4. 創建 Ingress
- 5. 切換藍綠版本
- 5.1 將 `app-svc` 指向綠色版本:
- 5.2 將 `app-svc` 切換到藍色版本:
- 總結
- 方法2:k8s 藍綠yaml 配置
- `service.yaml` 文件
- `deploy.yaml` 文件
- 藍`v1-deploy.yaml` 文件
- 綠`v2-deploy.yaml`文件
- 部署與測試
- 測試流量是否到v1版本
- 切換入口流量從v1 到 v2
- 測試流量是否到v2版本
通過k8s service label
標簽實現藍綠發布
- 建
兩個版本
的deploy
和svc
, - 為
svc
打版本標簽
, - 然后選擇
Service Label
標簽對應的deploy版本
方法1:使用kubelet完成藍綠切換
在 Kubernetes 中,使用 kubectl
命令完成藍綠部署.
1. 創建綠色版本
1.1 創建綠色版本 Deployment
# 創建一個名為 "yewu-app-green-deploy" 的 Deployment
kubectl create deployment yewu-app-green-deploy \--image=yewu-app:v2 # 使用鏡像 "yewu-app:v2" 部署應用
1.2 創建綠色版本 Service
# 將名為 "yewu-app-green-deploy" 的 Deployment 暴露為一個 Service
## port是service的端口
## --target-port是pod(中的容器)的端口
## --type 指定Service 的類型為ClusterIP,用于通過節點的IP和指定端口訪問服務
## --name=green-svc 指定 Service 的名稱為 "green-svc"
## --save-config 保存當前命令的配置到資源的注解中,便于后續管理
kubectl expose deployment yewu-app-green-deploy --type=ClusterIP --name=green-svc --port=80 --target-port=8080 --save-config
2. 創建藍色版本
2.1 創建藍色版本 Deployment
# 創建一個名為 "yewu-app-blue-deploy" 的 Deployment
kubectl create deployment yewu-app-blue-deploy \--image=yewu-app:v1 # 使用鏡像 "yewu-app:v1" 部署應用
2.2 創建藍色版本 Service
# 將名為 "yewu-app-blue-deploy" 的 Deployment 暴露為一個 Service
## port是service的端口
## --target-port是pod(中的容器)的端口
## --type 指定Service 的類型為ClusterIP,用于通過節點的IP和指定端口訪問服務
## --name=blue-svc 指定 Service 的名稱為 "blue-svc"
## --save-config 保存當前命令的配置到資源的注解中,便于后續管理
kubectl expose deployment yewu-app-blue-deploy --type=ClusterIP --name=blue-svc --port=80 --target-port=8080 --save-config
3. 創建藍綠切換SVC
(用于外部訪問)
創建一個外部 Service,用于切換藍綠版本:
# 創建一個 ClusterIP 類型的 Service,名稱為 "app-svc"
kubectl create service clusterip app-svc \--tcp=80:80 # 將 Service 的端口 80 映射到后端 Pod 的端口 80
4. 創建 Ingress
創建 Ingress 資源以暴露服務:
# 使用 kubectl 創建一個 Ingress 資源
kubectl create ingress app-ingress \--rule="your-domain.com/*=app-svc:80"# --rule 參數定義了 Ingress 的規則:# - your-domain.com 是主機名# - /* 表示匹配所有路徑# - app-svc:80 表示將流量轉發到名為 app-svc 的 Service 的 80 端口
5. 切換藍綠版本
5.1 將 app-svc
指向綠色版本:
# 更新名為 "app-svc" 的 Service 的 selector,使其指向綠色版本的 Deployment
kubectl patch svc app-svc \-p '{"spec":{"selector":{"app":"yewu-app-green-deploy"}}}'# -p 參數指定了一個 JSON 格式的部分更新內容# 將 Service 的 selector 更新為匹配標簽 "app=yewu-app-green-deploy"
5.2 將 app-svc
切換到藍色版本:
# 更新名為 "app-svc" 的 Service 的 selector,使其指向藍色版本的 Deployment
kubectl patch svc app-svc \-p '{"spec":{"selector":{"app":"yewu-app-blue-deploy"}}}'# -p 參數指定了一個 JSON 格式的部分更新內容# 將 Service 的 selector 更新為匹配標簽 "app=yewu-app-blue-deploy"
總結
先完成藍綠部署
,然后通過修改 app-svc
的 selector
來切換流量。
方法2:k8s 藍綠yaml 配置
service.yaml
文件
# 定義 API 版本為 v1
apiVersion: v1
# 定義資源類型為 Service
kind: Service
# 定義 Service 的元數據
metadata:# 定義 Service 的名稱為 demoname: demo# 定義 Service 所在的命名空間為 defaultnamespace: default# 定義 Service 的標簽,app 標簽值為 demolabels:app: demo
# 定義 Service 的規格
spec:# 定義 Service 的端口配置ports:# 定義一個端口配置- # 定義端口為 80port: 80# 定義目標端口為 httptargetPort: http# 定義協議為 TCPprotocol: TCP# 定義端口名稱為 httpname: http# 注意這里我們匹配 app 和 version 標簽,當要切換流量的時候,我們更新 version 標簽的值,比如:v2# 定義 Service 的選擇器selector:# 定義選擇器的 app 標簽值為 demoapp: demo# 定義選擇器的 version 標簽值為 v1version: v1
deploy.yaml
文件
藍v1-deploy.yaml
文件
# 定義 API 版本為 apps/v1
apiVersion: apps/v1
# 定義資源類型為 Deployment
kind: Deployment
# 定義 Deployment 的元數據
metadata:# 定義 Deployment 的名稱為 demo1-deploymentname: demo1-deployment# 定義 Deployment 所在的命名空間為 defaultnamespace: default# 定義 Deployment 的標簽,app 標簽值為 demolabels:# 定義 app 標簽值為 demoapp: demo# 定義 version 標簽值為 v1version: v1
# 定義 Deployment 的規格
spec:# 定義副本數量為 1replicas: 1# 定義修訂歷史限制為 3revisionHistoryLimit: 3# 定義更新策略strategy:# 定義滾動更新策略rollingUpdate:# 定義最大 surge 百分比為 30%maxSurge: 30%# 定義最大不可用百分比為 30%maxUnavailable: 30%# 定義選擇器selector:# 定義選擇器的標簽匹配規則matchLabels:# 定義 app 標簽值為 demoapp: demo# 定義 version 標簽值為 v1version: v1# 定義 Pod 模板template:# 定義 Pod 的元數據metadata:# 定義 Pod 的標簽labels:# 定義 app 標簽值為 demoapp: demo# 定義 version 標簽值為 v1version: v1# 定義 Pod 的規格spec:# 定義容器列表containers:# 定義一個容器- # 定義容器名稱為 demo1name: demo1# 定義容器使用的鏡像為 mritd/demoimage: mritd/demo# 定義存活探針livenessProbe:# 定義 HTTP GET 請求httpGet:# 定義請求路徑為 /path: /# 定義請求端口為 80port: 80# 定義請求協議為 HTTPscheme: HTTP# 定義初始延遲秒數為 30initialDelaySeconds: 30# 定義超時秒數為 5timeoutSeconds: 5# 定義周期秒數為 30periodSeconds: 30# 定義成功閾值為 1successThreshold: 1# 定義失敗閾值為 5failureThreshold: 5# 定義就緒探針readinessProbe:# 定義 HTTP GET 請求httpGet:# 定義請求路徑為 /path: /# 定義請求端口為 80port: 80# 定義請求協議為 HTTPscheme: HTTP# 定義初始延遲秒數為 30initialDelaySeconds: 30# 定義超時秒數為 5timeoutSeconds: 5# 定義周期秒數為 10periodSeconds: 10# 定義成功閾值為 1successThreshold: 1# 定義失敗閾值為 5failureThreshold: 5# 定義容器端口列表ports:# 定義一個端口- # 定義端口名稱為 httpname: http# 定義容器端口為 80containerPort: 80# 定義協議為 TCPprotocol: TCP
綠v2-deploy.yaml
文件
# 定義 API 版本為 apps/v1
apiVersion: apps/v1
# 定義資源類型為 Deployment
kind: Deployment
# 定義 Deployment 的元數據
metadata:# 定義 Deployment 的名稱為 demo1-deploymentname: demo1-deployment# 定義 Deployment 所在的命名空間為 defaultnamespace: default# 定義 Deployment 的標簽,app 標簽值為 demolabels:# 定義 app 標簽值為 demoapp: demo# 定義 version 標簽值為 v1version: v1
# 定義 Deployment 的規格
spec:# 定義副本數量為 1replicas: 1# 定義修訂歷史限制為 3revisionHistoryLimit: 3# 定義更新策略strategy:# 定義滾動更新策略rollingUpdate:# 定義最大 surge 百分比為 30%maxSurge: 30%# 定義最大不可用百分比為 30%maxUnavailable: 30%# 定義選擇器selector:# 定義選擇器的標簽匹配規則matchLabels:# 定義 app 標簽值為 demoapp: demo# 定義 version 標簽值為 v1version: v1# 定義 Pod 模板template:# 定義 Pod 的元數據metadata:# 定義 Pod 的標簽labels:# 定義 app 標簽值為 demoapp: demo# 定義 version 標簽值為 v1version: v1# 定義 Pod 的規格spec:# 定義容器列表containers:# 定義一個容器- # 定義容器名稱為 demo1name: demo1# 定義容器使用的鏡像為 mritd/demoimage: mritd/demo# 定義存活探針livenessProbe:# 定義 HTTP GET 請求httpGet:# 定義請求路徑為 /path: /# 定義請求端口為 80port: 80# 定義請求協議為 HTTPscheme: HTTP# 定義初始延遲秒數為 30initialDelaySeconds: 30# 定義超時秒數為 5timeoutSeconds: 5# 定義周期秒數為 30periodSeconds: 30# 定義成功閾值為 1successThreshold: 1# 定義失敗閾值為 5failureThreshold: 5# 定義就緒探針readinessProbe:# 定義 HTTP GET 請求httpGet:# 定義請求路徑為 /path: /# 定義請求端口為 80port: 80# 定義請求協議為 HTTPscheme: HTTP# 定義初始延遲秒數為 30initialDelaySeconds: 30# 定義超時秒數為 5timeoutSeconds: 5# 定義周期秒數為 10periodSeconds: 10# 定義成功閾值為 1successThreshold: 1# 定義失敗閾值為 5failureThreshold: 5# 定義容器端口列表ports:# 定義一個端口- # 定義端口名稱為 httpname: http# 定義容器端口為 80containerPort: 80# 定義協議為 TCPprotocol: TCP
- 上面定義的資源對象中,最重要的就是
Service 中 label selector
的定義:
selector:app: demoversion: v1
部署與測試
- 部署v1 v2 deploy服務 和 service服務
# 使用 kubectl 工具應用多個 YAML 配置文件
# -f service.yaml: 應用服務配置文件
# -f v1-deploy.yaml: 應用版本1的部署配置文件
# -f v2-deploy.yaml: 應用版本2的部署配置文件
kubectl apply -f service.yaml -f v1-deploy.yaml -f v2-deploy.yaml
測試流量是否到v1版本
# 登陸任意一個pod,向 demo service 發起請求
while sleep 0.3; do curl http://demo; done# 輸出日志
Host: demo1-deployment-b5bd596d8-dw27b, Version: v1
Host: demo1-deployment-b5bd596d8-dw27b, Version: v1
切換入口流量從v1 到 v2
# 使用 kubectl 工具更新服務的配置
# patch service demo: 對名為 demo 的服務進行補丁操作
# -p '{"spec":{"selector":{"version":"v2"}}}': 指定補丁內容,將服務的選擇器更新為 version=v2
kubectl patch service demo -p '{"spec":{"selector":{"version":"v2"}}}'
測試流量是否到v2版本
# 登陸任意一個pod,向 demo service 發起請求
while sleep 0.3; do curl http://demo; done# 輸出日志
Host: demo2-deployment-b5bd596d8-dw27b, Version: v2
Host: demo2-deployment-b5bd596d8-dw27b, Version: v2