深入剖析全鏈路灰度技術(shù)內(nèi)幕(3)
從 0 到 1 實(shí)踐全鏈路灰度
Cloud Native
前提條件
必備的資源列表
- 已擁有一個(gè) MSE 云原生網(wǎng)關(guān)
- 已擁有一個(gè) MSE Nacos 注冊(cè)中心
- 已擁有一個(gè) ACK 運(yùn)維集群
- 已開(kāi)通 MSE 微服務(wù)治理專(zhuān)業(yè)版
部署 Demo 應(yīng)用程序
將下面的文件保存到 ingress-gray.yaml 中,并執(zhí)行 kubectl apply -f ingress-gray.yaml 以部署應(yīng)用,這里我們將要部署 A,B,C 三個(gè)應(yīng)用,A 和 C 應(yīng)用分別部署一個(gè)基線版本和一個(gè)灰度版本,B 應(yīng)用部署一個(gè)基線版本。
-
全鏈路灰度能力是與注冊(cè)中心無(wú)關(guān)的,本文用例暫以 MSE Nacos 作為注冊(cè)中心,所以需要將 spring.cloud.nacos.discovery.server-addr 換成業(yè)務(wù)自己的 Nacos 注冊(cè)中心地址
- 接入云原生網(wǎng)關(guān)的服務(wù),如果需要使用灰度發(fā)布,需要在發(fā)布服務(wù)時(shí)在元數(shù)據(jù)信息增加版本標(biāo)。在我們的例子,服務(wù) A 是需要暴露給網(wǎng)關(guān),所以發(fā)布時(shí)為基線版本添加spring.cloud.nacos.discovery.metadata.version=base,為灰度版本添加 spring.cloud.nacos.discovery.metadata.version=gray。
# A 應(yīng)用 base 版本---apiVersion: apps/v1kind: Deploymentmetadata: labels: app: spring-cloud-a name: spring-cloud-aspec: replicas: 2 selector: matchLabels: app: spring-cloud-a template: metadata: annotations: msePilotCreateAppName: spring-cloud-a labels: app: spring-cloud-a spec: containers: env: name: LANG value: C.UTF-8 name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre name: spring.cloud.nacos.discovery.server-addr value: mse-455e0c20-nacos-ans.mse.aliyuncs.com:8848 name: spring.cloud.nacos.discovery.metadata.version value: base image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT imagePullPolicy: Always name: spring-cloud-a ports: containerPort: 20001 protocol: TCP resources: requests: cpu: 250m memory: 512Mi # A 應(yīng)用 gray 版本 apiVersion: apps/v1kind: Deploymentmetadata: labels: app: spring-cloud-a-new name: spring-cloud-a-newspec: replicas: 2 selector: matchLabels: app: spring-cloud-a-new strategy: template: metadata: annotations: gray : msePilotCreateAppName: spring-cloud-a labels: app: spring-cloud-a-new spec: containers: env: name: LANG value: C.UTF-8 name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre name: profiler.micro.service.tag.trace.enable value: "true" name: spring.cloud.nacos.discovery.server-addr value: mse-455e0c20-nacos-ans.mse.aliyuncs.com:8848 name: spring.cloud.nacos.discovery.metadata.version value: gray image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT imagePullPolicy: Always name: spring-cloud-a-new ports: containerPort: 20001 protocol: TCP resources: requests: cpu: 250m memory: 512Mi # B 應(yīng)用 base 版本---apiVersion: apps/v1kind: Deploymentmetadata: labels: app: spring-cloud-b name: spring-cloud-bspec: replicas: 2 selector: matchLabels: app: spring-cloud-b strategy: template: metadata: annotations: msePilotCreateAppName: spring-cloud-b labels: app: spring-cloud-b spec: containers: env: name: LANG value: C.UTF-8 name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre name: spring.cloud.nacos.discovery.server-addr value: mse-455e0c20-nacos-ans.mse.aliyuncs.com:8848 image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:0.2-demo-SNAPSHOT imagePullPolicy: Always name: spring-cloud-b ports: containerPort: 8080 protocol: TCP resources: requests: cpu: 250m memory: 512Mi # C 應(yīng)用 base 版本---apiVersion: apps/v1kind: Deploymentmetadata: labels: app: spring-cloud-c name: spring-cloud-cspec: replicas: 2 selector: matchLabels: app: spring-cloud-c template: metadata: annotations: msePilotCreateAppName: spring-cloud-c labels: app: spring-cloud-c spec: containers: env: name: LANG value: C.UTF-8 name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre name: spring.cloud.nacos.discovery.server-addr value: mse-455e0c20-nacos-ans.mse.aliyuncs.com:8848 image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:0.2-demo-SNAPSHOT imagePullPolicy: Always name: spring-cloud-c ports: containerPort: 8080 protocol: TCP resources: requests: cpu: 250m memory: 512Mi # C 應(yīng)用 gray 版本---apiVersion: apps/v1kind: Deploymentmetadata: labels: app: spring-cloud-c-new name: spring-cloud-c-newspec: replicas: 2 selector: matchLabels: app: spring-cloud-c-new template: metadata: annotations: gray : msePilotCreateAppName: spring-cloud-c labels: app: spring-cloud-c-new spec: containers: env: name: LANG value: C.UTF-8 name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre name: spring.cloud.nacos.discovery.server-addr value: mse-455e0c20-nacos-ans.mse.aliyuncs.com:8848 image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:0.2-demo-SNAPSHOT imagePullPolicy: Always name: spring-cloud-c-new ports: containerPort: 8080 protocol: TCP resources: requests: cpu: 250m memory: 512Mi
完成云原生網(wǎng)關(guān)初步配置
第一步,為云原生網(wǎng)關(guān)添加 Nacos 服務(wù)來(lái)源,服務(wù)管理,來(lái)源管理,點(diǎn)擊創(chuàng)建來(lái)源,
選擇服務(wù)來(lái)源為 MSE Nacos,選擇服務(wù) sc-A。
點(diǎn)擊服務(wù) A 的策略配置,為入口服務(wù) A 創(chuàng)建多版本,版本劃分依據(jù)服務(wù)注冊(cè)時(shí)所帶的元數(shù)據(jù)信息 version(注意,這里可以是任意可以區(qū)分服務(wù)版本的標(biāo)簽值,取決于用戶(hù)注冊(cè)服務(wù)時(shí)所采用的元數(shù)據(jù)信息),創(chuàng)建以下兩個(gè)版本 base 和 gray。
路由配置
創(chuàng)建基線環(huán)境的路由匹配規(guī)則,關(guān)聯(lián)域名 base.example.com,路由到服務(wù) sc-A 的 base 版本中。
創(chuàng)建灰度環(huán)境的路由匹配規(guī)則,關(guān)聯(lián)的域名與基線環(huán)境保持一致,注意此處增加了請(qǐng)求頭相關(guān)的配置,并且路由的目標(biāo)服務(wù)為服務(wù) sc-A 的 gray 版本。
這時(shí),我們有了如下兩條路由規(guī)則,
此時(shí),訪問(wèn) base.example.com 路由到基線環(huán)境
curl -H "Host: base.example.com" http://118.31.118.69/aA[172.21.240.105] -> B[172.21.240.106] -> C[172.21.240.46]
如何訪問(wèn)灰度環(huán)境呢?只需要在請(qǐng)求中增加一個(gè) header x-mse-tag: gray 即可。
curl -H "Host: base.example.com" -H "x-mse-tag: gray" http://118.31.118.69/aAgray[172.21.240.44] -> B[172.21.240.146] -> Cgray[172.21.240.147]
可以看到 云原生網(wǎng)關(guān) 將灰度流量路由到了 A 和 C 的灰度版本,由于B沒(méi)有指定的灰度版本,所以流量自動(dòng)回退到基線版本。
3
分析
從上面可以看出,我們只需要開(kāi)通 MSE 微服務(wù)治理專(zhuān)業(yè)版,在云原生網(wǎng)關(guān)配置入口服務(wù)的路由規(guī)則,并且對(duì)入口流量進(jìn)行灰度染色,即可滿(mǎn)足我們對(duì) A 和 C 全鏈路灰度的要求。另外還有一個(gè)很重要的點(diǎn)是,業(yè)務(wù)需要自行對(duì)節(jié)點(diǎn)打標(biāo)并對(duì)入口服務(wù)開(kāi)啟鏈路傳遞。為 Pod 模板的 Annotations添加 alicloud.service.tag 鍵值對(duì)完成節(jié)點(diǎn)打標(biāo),Java Agent 會(huì)在業(yè)務(wù)向注冊(cè)中心時(shí)登記節(jié)點(diǎn)時(shí)自動(dòng)為其添加這個(gè)元數(shù)據(jù)信息,同時(shí)需要為入口服務(wù)的業(yè)務(wù)容器添加環(huán)境變量 profiler.micro.service.tag.trace.enable=true 開(kāi)啟鏈路傳遞灰度標(biāo)識(shí)。MSE 服務(wù)治理組件默認(rèn)使用 x-mse-tag 來(lái)標(biāo)識(shí)流量,并在整個(gè)調(diào)用鏈路中傳遞。
總結(jié)
Cloud Native
本文從單體架構(gòu)向微服務(wù)架構(gòu)演進(jìn)過(guò)程中帶來(lái)的挑戰(zhàn)展開(kāi),著重對(duì)其子領(lǐng)域服務(wù)發(fā)布在單體架構(gòu)和微服務(wù)架構(gòu)體系下的形態(tài)進(jìn)行分析,引出了分布式應(yīng)用場(chǎng)景中特有的全鏈路灰度問(wèn)題。針對(duì)業(yè)務(wù)對(duì)全鏈路能力的要求,介紹了基于物理環(huán)境隔離和基于邏輯環(huán)境隔離兩種方案,其中對(duì)基于邏輯環(huán)境隔離方案進(jìn)行詳細(xì)分析,對(duì)涉及到的各個(gè)技術(shù)點(diǎn)也進(jìn)行了很好的解釋?zhuān)又岢隽巳N基于邏輯環(huán)境隔離的落地方案,并進(jìn)行了簡(jiǎn)單的對(duì)比分析,最后引出了阿里云 MSE 云原生、MSE 服務(wù)治理和服務(wù)網(wǎng)格 ASM 是如何提供不限于全鏈路灰度的流量治理能力。
# A 應(yīng)用 base 版本---apiVersion: apps/v1kind: Deploymentmetadata: labels: app: spring-cloud-a name: spring-cloud-aspec: replicas: 2 selector: matchLabels: app: spring-cloud-a template: metadata: annotations: msePilotCreateAppName: spring-cloud-a labels: app: spring-cloud-a spec: containers: env: name: LANG value: C.UTF-8 name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre name: spring.cloud.nacos.discovery.server-addr value: mse-455e0c20-nacos-ans.mse.aliyuncs.com:8848 name: spring.cloud.nacos.discovery.metadata.version value: base image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT imagePullPolicy: Always name: spring-cloud-a ports: containerPort: 20001 protocol: TCP resources: requests: cpu: 250m memory: 512Mi # A 應(yīng)用 gray 版本 apiVersion: apps/v1kind: Deploymentmetadata: labels: app: spring-cloud-a-new name: spring-cloud-a-newspec: replicas: 2 selector: matchLabels: app: spring-cloud-a-new strategy: template: metadata: annotations: gray : msePilotCreateAppName: spring-cloud-a labels: app: spring-cloud-a-new spec: containers: env: name: LANG value: C.UTF-8 name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre name: profiler.micro.service.tag.trace.enable value: "true" name: spring.cloud.nacos.discovery.server-addr value: mse-455e0c20-nacos-ans.mse.aliyuncs.com:8848 name: spring.cloud.nacos.discovery.metadata.version value: gray image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT imagePullPolicy: Always name: spring-cloud-a-new ports: containerPort: 20001 protocol: TCP resources: requests: cpu: 250m memory: 512Mi # B 應(yīng)用 base 版本---apiVersion: apps/v1kind: Deploymentmetadata: labels: app: spring-cloud-b name: spring-cloud-bspec: replicas: 2 selector: matchLabels: app: spring-cloud-b strategy: template: metadata: annotations: msePilotCreateAppName: spring-cloud-b labels: app: spring-cloud-b spec: containers: env: name: LANG value: C.UTF-8 name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre name: spring.cloud.nacos.discovery.server-addr value: mse-455e0c20-nacos-ans.mse.aliyuncs.com:8848 image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:0.2-demo-SNAPSHOT imagePullPolicy: Always name: spring-cloud-b ports: containerPort: 8080 protocol: TCP resources: requests: cpu: 250m memory: 512Mi # C 應(yīng)用 base 版本---apiVersion: apps/v1kind: Deploymentmetadata: labels: app: spring-cloud-c name: spring-cloud-cspec: replicas: 2 selector: matchLabels: app: spring-cloud-c template: metadata: annotations: msePilotCreateAppName: spring-cloud-c labels: app: spring-cloud-c spec: containers: env: name: LANG value: C.UTF-8 name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre name: spring.cloud.nacos.discovery.server-addr value: mse-455e0c20-nacos-ans.mse.aliyuncs.com:8848 image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:0.2-demo-SNAPSHOT imagePullPolicy: Always name: spring-cloud-c ports: containerPort: 8080 protocol: TCP resources: requests: cpu: 250m memory: 512Mi # C 應(yīng)用 gray 版本---apiVersion: apps/v1kind: Deploymentmetadata: labels: app: spring-cloud-c-new name: spring-cloud-c-newspec: replicas: 2 selector: matchLabels: app: spring-cloud-c-new template: metadata: annotations: gray : msePilotCreateAppName: spring-cloud-c labels: app: spring-cloud-c-new spec: containers: env: name: LANG value: C.UTF-8 name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre name: spring.cloud.nacos.discovery.server-addr value: mse-455e0c20-nacos-ans.mse.aliyuncs.com:8848 image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:0.2-demo-SNAPSHOT imagePullPolicy: Always name: spring-cloud-c-new ports: containerPort: 8080 protocol: TCP resources: requests: cpu: 250m memory: 512Mi