ASP.NET Core on K8s学习之旅(14)Ingress灰度发布
【云原生】|?作者/Edison Zhou
這是恰童鞋騷年的第236篇原創文章
上一篇介紹了Ingress的基本概念和Nginx Ingress的基本配置和使用,然后我還錄了一個快速分享小視頻介紹了一下藍綠發布和灰度發布策略的基本概念,本篇介紹一下如何實戰使用Nginx Ingress實現灰度發布(金絲雀發布)。
1一些準備工作
1.1 WebAPI項目準備
首先,我們還是準備兩個版本的ASP.NET Core WebAPI項目,具體項目代碼可以參考我的這篇Rolling Update的文章。
他們之間的差別在于一個接口的返回JSON數據,比如V1.0版本中返回的是Version: 1.0,而V1.1版本中返回的是Version:1.1。
[Route("api/[controller]")] [ApiController] public class HomeController : ControllerBase {// GET api/home[HttpGet]public?ActionResult<IEnumerable<string>>?Get(){return?new?string[]?{"Hello,?welcome?to?EDC's?demo.?Version:?1.0"};} }運行結果為:
(2)將此項目各個版本根據Dockerfile打成鏡像,分別是xilife/canary-api-demo:1.0,1.1。
(3)將本地鏡像push到遠程鏡像倉庫,這里我傳送到了我在docker hub的一個公共倉庫里邊:
docker push xilife/canary-api-demo:1.0 docker push xilife/canary-api-demo:1.11.2 WebAPI項目部署
其次,我們將這兩個WebAPI項目部署到K8s集群中,還是通過熟悉的yaml文件來將其部署為Service:
(1)V1.0版本(假設為線上版本)
apiVersion: apps/v1 kind: Deployment metadata:name: canary-api-demonamespace: xdp-poclabels:name: canary-api-demo spec:replicas: 2selector:matchLabels:name: canary-api-demotemplate:metadata:labels:name: canary-api-demospec:containers:- name: canary-api-demoimage: xilife/canary-api-demo:1.0ports:- containerPort: 80imagePullPolicy: IfNotPresent---kind: Service apiVersion: v1 metadata:name: canary-api-svcnamespace: xdp-poc spec:type: NodePortports:- port: 80targetPort: 80selector:name: canary-api-demo(2)V1.1版本(假設為灰度版本)
apiVersion: apps/v1 kind: Deployment metadata:name: canary-api-demo-graynamespace: xdp-poclabels:name: canary-api-demo-gray spec:replicas: 2selector:matchLabels:name: canary-api-demo-graytemplate:metadata:labels:name: canary-api-demo-grayspec:containers:- name: canary-api-demo-grayimage: xilife/canary-api-demo:1.1ports:- containerPort: 80imagePullPolicy: IfNotPresent---kind: Service apiVersion: v1 metadata:name: canary-api-svc-graynamespace: xdp-poc spec:type: NodePortports:- port: 80targetPort: 80selector:name: canary-api-demo-gray將這兩個應用部署至K8s集群:
kubectl apply -f deploy-canary-api-svc.yml kubectl apply -f deploy-canary-api-gray-svc.yml2Ingress實現灰度發布
Ingress-Nginx 支持配置 Ingress Annotations 來實現不同場景下的灰度發布和測試,可以滿足金絲雀發布、藍綠部署與 A/B 測試等業務場景。
因此我們準備兩個版本的Ingress的yml文件,它提供了兩種方式:
一是基于用戶請求的流量切分,具體又包括了基于Request Header的流量切分與基于Cookie的流量切分兩種方式;如下圖所示:
二是基于服務權重的流量切分;如下圖所示:
2.1?基于Request Header的流量切分
根據Request Header的流量切分方式的約定,適用于灰度發布及A/B測試。當 Request Header 設置為 always時,請求將會被一直發送到 Canary 版本;當 Request Header 設置為 never時,請求不會被發送到 Canary 入口;對于任何其他 Header 值,將忽略 Header,并通過優先級將請求與其他金絲雀規則進行優先級的比較。
為1.0版本準備一個Ingress,讓它先工作著:
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata:name: nginx-ingressnamespace: xdp-pocannotations:kubernetes.io/ingress.class: "nginx"nginx.ingress.kubernetes.io/rewrite-target: /api/$2 spec:rules:- host: portal.k8s.xi-life.cnhttp:paths:- path: /api(/|$)(.*)backend:serviceName: canary-api-svcservicePort: 80應用至K8s集群:
kubectl apply -f ingress-nginx.yaml再為1.1版本準備一個Ingress,讓它作為灰度版本的入口逐步替換原v1版本的流量接入:
應用至K8s集群:
快速驗證:
2.2 基于Cookie的流量切分
根據基于 Cookie 的流量切分方式的約定,當 Cookie 值設置為 always時,它將被路由到 Canary 入口;當 Cookie 值設置為 never時,請求不會被發送到 Canary 入口;對于任何其他值,將忽略 Cookie 并將請求與其他金絲雀規則進行優先級的比較。
為灰度版本準備Ingress:
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata:name: nginx-ingress-graynamespace: xdp-pocannotations:kubernetes.io/ingress.class: "nginx"nginx.ingress.kubernetes.io/proxy-body-size: "100m"nginx.ingress.kubernetes.io/limit-rps: '10'nginx.ingress.kubernetes.io/rewrite-target: /api/$2nginx.ingress.kubernetes.io/canary: "true"nginx.ingress.kubernetes.io/canary-by-cookie: "xdp-v2-cookie" spec:rules:- host: portal.k8s.xi-life.cnhttp:paths:- path: /api(/|$)(.*)backend:serviceName: canary-api-svc-grayservicePort: 80應用至K8s集群:
kubectl apply -f ingress-nginx-gray.yaml快速驗證:
(1)未添加Cookie
(2)為要訪問的域名添加一個Cookie
(3)再次請求驗證
2.3 基于服務權重的流量切分
根據基于服務權重的流量切分方式的約定,適用于藍綠部署,權重范圍 0 - 100 按百分比將請求路由到 Canary Ingress 中指定的服務。權重為 0 意味著該金絲雀規則不會向 Canary 入口的服務發送任何請求。權重為 100 意味著所有請求都將被發送到 Canary 入口。
為灰度版本準備Ingress:
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata:name: nginx-ingress-graynamespace: xdp-pocannotations:kubernetes.io/ingress.class: "nginx"nginx.ingress.kubernetes.io/proxy-body-size: "100m"nginx.ingress.kubernetes.io/limit-rps: '10'nginx.ingress.kubernetes.io/rewrite-target: /api/$2nginx.ingress.kubernetes.io/canary: "true"nginx.ingress.kubernetes.io/canary-weight: "50" spec:rules:- host: portal.k8s.xi-life.cnhttp:paths:- path: /api(/|$)(.*)backend:serviceName: canary-api-svc-grayservicePort: 80應用至K8s集群:
kubectl apply -f ingress-nginx-gray.yaml快速驗證:這里我直接通過瀏覽器來測試,需要注意的是這里的50%是一個近似分布值,可能實際中不會太精確。
2.4 三種方式的優先級
Nginx Ingress提供的三種灰度發布的方式的優先級順序為:
canary-by-header -> canary-by-cookie -> canary-weight對于Nginx Ingress的使用目前已知限制:
(1)Ingress-Nginx是在0.21.0版本中才引入的Canary功能,因此建議確保版本在0.22.0及之后(據說0.21.0版本的基于Cookie方式有點問題);
(2)目前每個Ingress規則中最多只能應用一個canary入口!
3小結
本文介紹了Nginx Ingress提供的三種灰度發布(canary)的方式,然后介紹了如何使用Nginx Ingress并進行配置實現ASP.NET Core WebAPI應用服務的灰度發布實踐,最后對比三種方式的優先級及限制,希望對你有所幫助。
4參考資料
JadePeng,《K8s基于Nginx Ingress實現灰度發布》
我的小碗湯,《Nginx Ingress實現灰度和金絲雀發布》
梁寬,《再也不采坑的K8s實戰指南》
WangT,《K8s基于Nginx Ingress進行藍綠部署/金絲雀發布》
linus.lin,《一文明白藍綠部署、滾動部署、灰度發布、金絲雀發布》
往期精彩回顧
.NET Core on K8s學習系列文章目錄
騷年快享:K8s下發布策略基本概念一覽
基于Jenkins的開發測試全流程持續集成實踐
基于Jenkins的ASP.NET Core持續集成實踐
如果本文對你有用,
不妨點個“在看”/轉發朋友圈
總結
以上是生活随笔為你收集整理的ASP.NET Core on K8s学习之旅(14)Ingress灰度发布的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 掌握了Docker Layer Cach
- 下一篇: 开发大会上,前微软CEO放出的狠话!.N