ASP.NET Core on K8s学习之旅(14)Ingress灰度发布
【云原生】|?作者/Edison Zhou
這是恰童鞋騷年的第236篇原創(chuàng)文章
上一篇介紹了Ingress的基本概念和Nginx Ingress的基本配置和使用,然后我還錄了一個(gè)快速分享小視頻介紹了一下藍(lán)綠發(fā)布和灰度發(fā)布策略的基本概念,本篇介紹一下如何實(shí)戰(zhàn)使用Nginx Ingress實(shí)現(xiàn)灰度發(fā)布(金絲雀發(fā)布)。
1一些準(zhǔn)備工作
1.1 WebAPI項(xiàng)目準(zhǔn)備
首先,我們還是準(zhǔn)備兩個(gè)版本的ASP.NET Core WebAPI項(xiàng)目,具體項(xiàng)目代碼可以參考我的這篇Rolling Update的文章。
他們之間的差別在于一個(gè)接口的返回JSON數(shù)據(jù),比如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"};} }運(yùn)行結(jié)果為:
(2)將此項(xiàng)目各個(gè)版本根據(jù)Dockerfile打成鏡像,分別是xilife/canary-api-demo:1.0,1.1。
(3)將本地鏡像push到遠(yuǎn)程鏡像倉(cāng)庫(kù),這里我傳送到了我在docker hub的一個(gè)公共倉(cāng)庫(kù)里邊:
docker push xilife/canary-api-demo:1.0 docker push xilife/canary-api-demo:1.11.2 WebAPI項(xiàng)目部署
其次,我們將這兩個(gè)WebAPI項(xiàng)目部署到K8s集群中,還是通過熟悉的yaml文件來將其部署為Service:
(1)V1.0版本(假設(shè)為線上版本)
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版本(假設(shè)為灰度版本)
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將這兩個(gè)應(yīng)用部署至K8s集群:
kubectl apply -f deploy-canary-api-svc.yml kubectl apply -f deploy-canary-api-gray-svc.yml2Ingress實(shí)現(xiàn)灰度發(fā)布
Ingress-Nginx 支持配置 Ingress Annotations 來實(shí)現(xiàn)不同場(chǎng)景下的灰度發(fā)布和測(cè)試,可以滿足金絲雀發(fā)布、藍(lán)綠部署與 A/B 測(cè)試等業(yè)務(wù)場(chǎng)景。
因此我們準(zhǔn)備兩個(gè)版本的Ingress的yml文件,它提供了兩種方式:
一是基于用戶請(qǐng)求的流量切分,具體又包括了基于Request Header的流量切分與基于Cookie的流量切分兩種方式;如下圖所示:
二是基于服務(wù)權(quán)重的流量切分;如下圖所示:
2.1?基于Request Header的流量切分
根據(jù)Request Header的流量切分方式的約定,適用于灰度發(fā)布及A/B測(cè)試。當(dāng) Request Header 設(shè)置為 always時(shí),請(qǐng)求將會(huì)被一直發(fā)送到 Canary 版本;當(dāng) Request Header 設(shè)置為 never時(shí),請(qǐng)求不會(huì)被發(fā)送到 Canary 入口;對(duì)于任何其他 Header 值,將忽略 Header,并通過優(yōu)先級(jí)將請(qǐng)求與其他金絲雀規(guī)則進(jìn)行優(yōu)先級(jí)的比較。
為1.0版本準(zhǔn)備一個(gè)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應(yīng)用至K8s集群:
kubectl apply -f ingress-nginx.yaml再為1.1版本準(zhǔn)備一個(gè)Ingress,讓它作為灰度版本的入口逐步替換原v1版本的流量接入:
應(yīng)用至K8s集群:
快速驗(yàn)證:
2.2 基于Cookie的流量切分
根據(jù)基于 Cookie 的流量切分方式的約定,當(dāng) Cookie 值設(shè)置為 always時(shí),它將被路由到 Canary 入口;當(dāng) Cookie 值設(shè)置為 never時(shí),請(qǐng)求不會(huì)被發(fā)送到 Canary 入口;對(duì)于任何其他值,將忽略 Cookie 并將請(qǐng)求與其他金絲雀規(guī)則進(jìn)行優(yōu)先級(jí)的比較。
為灰度版本準(zhǔn)備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應(yīng)用至K8s集群:
kubectl apply -f ingress-nginx-gray.yaml快速驗(yàn)證:
(1)未添加Cookie
(2)為要訪問的域名添加一個(gè)Cookie
(3)再次請(qǐng)求驗(yàn)證
2.3 基于服務(wù)權(quán)重的流量切分
根據(jù)基于服務(wù)權(quán)重的流量切分方式的約定,適用于藍(lán)綠部署,權(quán)重范圍 0 - 100 按百分比將請(qǐng)求路由到 Canary Ingress 中指定的服務(wù)。權(quán)重為 0 意味著該金絲雀規(guī)則不會(huì)向 Canary 入口的服務(wù)發(fā)送任何請(qǐng)求。權(quán)重為 100 意味著所有請(qǐng)求都將被發(fā)送到 Canary 入口。
為灰度版本準(zhǔn)備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應(yīng)用至K8s集群:
kubectl apply -f ingress-nginx-gray.yaml快速驗(yàn)證:這里我直接通過瀏覽器來測(cè)試,需要注意的是這里的50%是一個(gè)近似分布值,可能實(shí)際中不會(huì)太精確。
2.4 三種方式的優(yōu)先級(jí)
Nginx Ingress提供的三種灰度發(fā)布的方式的優(yōu)先級(jí)順序?yàn)?#xff1a;
canary-by-header -> canary-by-cookie -> canary-weight對(duì)于Nginx Ingress的使用目前已知限制:
(1)Ingress-Nginx是在0.21.0版本中才引入的Canary功能,因此建議確保版本在0.22.0及之后(據(jù)說0.21.0版本的基于Cookie方式有點(diǎn)問題);
(2)目前每個(gè)Ingress規(guī)則中最多只能應(yīng)用一個(gè)canary入口!
3小結(jié)
本文介紹了Nginx Ingress提供的三種灰度發(fā)布(canary)的方式,然后介紹了如何使用Nginx Ingress并進(jìn)行配置實(shí)現(xiàn)ASP.NET Core WebAPI應(yīng)用服務(wù)的灰度發(fā)布實(shí)踐,最后對(duì)比三種方式的優(yōu)先級(jí)及限制,希望對(duì)你有所幫助。
4參考資料
JadePeng,《K8s基于Nginx Ingress實(shí)現(xiàn)灰度發(fā)布》
我的小碗湯,《Nginx Ingress實(shí)現(xiàn)灰度和金絲雀發(fā)布》
梁寬,《再也不采坑的K8s實(shí)戰(zhàn)指南》
WangT,《K8s基于Nginx Ingress進(jìn)行藍(lán)綠部署/金絲雀發(fā)布》
linus.lin,《一文明白藍(lán)綠部署、滾動(dòng)部署、灰度發(fā)布、金絲雀發(fā)布》
往期精彩回顧
.NET Core on K8s學(xué)習(xí)系列文章目錄
騷年快享:K8s下發(fā)布策略基本概念一覽
基于Jenkins的開發(fā)測(cè)試全流程持續(xù)集成實(shí)踐
基于Jenkins的ASP.NET Core持續(xù)集成實(shí)踐
如果本文對(duì)你有用,
不妨點(diǎn)個(gè)“在看”/轉(zhuǎn)發(fā)朋友圈
總結(jié)
以上是生活随笔為你收集整理的ASP.NET Core on K8s学习之旅(14)Ingress灰度发布的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 掌握了Docker Layer Cach
- 下一篇: 你需要了解操作系统发展历程