在微服務架構中,當需求開發涉及到多個微服務的改動時,每個微服務通常會有灰度環境或分組來接受灰度流量。如果希望上游應用灰度環境中的流量也能進入到下游應用的灰度環境中,請確保一個請求始終在灰度環境中傳遞。即使調用鏈路上存在一些沒有灰度環境的微服務應用,它們在請求下游應用時,也能夠回到下游應用的灰度環境中。借助阿里云ALB負載均衡的靈活路由功能和MSE的全鏈路灰度能力,您可以輕松實現全鏈路灰度,而無需修改業務代碼。
全鏈路灰度實現流程
注意事項
如果您使用的是Flannel網絡插件,則ALB Ingress后端Service服務僅支持NodePort和LoadBalancer類型。
ALB的交換機所在的VPC需要與ACK集群的VPC一致。關于ALB支持的地域,請參見支持的地域與可用區。
場景示例:按照域名路由,實現全鏈路灰度
若應用的架構由ALB負載均衡以及后端的微服務架構(Spring Cloud)組成,后端調用鏈路有3個:交易中心(A)、商品中心(B)和庫存中心(C),可以通過客戶端或者是HTML來訪問后端服務,這些服務之間通過Nacos注冊中心實現服務發現。
您可以通過不同的域名來區分線上基線環境和灰度環境,灰度環境可單獨配置域名,例如,通過訪問www.example.com
請求灰度環境,通過訪問www.aliyundoc.com
請求基線環境。
如圖所示,調用鏈路為Ingress-ALB > A > B > C,其中A可以是一個Spring Boot的應用。
準備工作
創建Kubernetes集群
通過Kubectl工具連接ACK集群
通過Kubectl工具連接ACK集群。具體操作,請參見獲取集群KubeConfig并通過kubectl工具連接集群。
安裝ALB Ingress Controller組件
為ACK集群安裝ALB Ingress Controller組件。以下兩種方式選擇一種即可。
在ACK創建集群時,通過在組件配置向導頁面的Ingress字段右側,選擇ALB Ingress,為集群安裝ALB Ingress Controller組件。
若已創建ACK集群,在組件管理頁面,可安裝ALB Ingress Controller組件。具體操作,請參見管理組件。
開啟MSE微服務治理
在MSE微服務治理開通頁面,開通微服務治理專業版。
關于微服務治理的計費詳情,請參見計費概述。
將ACK微服務應用接入MSE治理中心,您可以選擇您需要的方式實現應用接入。更多信息,請參見ACK微服務應用接入MSE治理中心。
為ACK命名空間中的應用開啟MSE微服務治理
登錄MSE治理中心控制臺,并在頂部菜單欄選擇地域。
在左側導航欄,選擇治理中心 > 應用治理。
在應用列表頁面,單擊ACK應用接入。
在ACK應用接入對話框中,進行配置,配置完成后,單擊確定。
配置項
說明
集群類型
選擇ACK集群或者ACK Serverless集群。
說明如果您尚未授權容器服務調用微服務引擎,則需要單擊請授權進行授權。
集群名稱/ID
選擇接入MSE微服務治理的集群名稱/ID,可通過關鍵詞搜索。
ack-onepilot
顯示ack-onepilot接入狀態。
如果您未安裝ack-onepilot,單擊ack-onepilot右側的點擊安裝,安裝完成后狀態會顯示為已安裝。
如果您使用子賬號接入,提示沒有權限使用時,您可以登錄容器服務管理控制臺進入目標集群,然后單擊運維管理>組件管理,然后找到ack-onepilot,點擊安裝。
說明該步驟接入的組件為ack-onepilot,您可以登錄容器服務管理控制臺進入目標集群,然后單擊運維管理>組件管理查看詳情。
ack-onepilot安裝后會自動注入探針,可能會導致應用啟動耗時增加(10s內)。
接入類型
選擇命名空間接入。
容器集群命名空間
選擇容器集群命名空間。
治理命名空間
選擇治理命名空間。在對應命名空間下重新部署現有應用或新創建的應用,均會接入到MSE微服務治理中。關于命名空間的相關信息,請參見微服務命名空間管理。
為單個應用開啟MSE微服務治理
登錄MSE治理中心控制臺,并在頂部菜單欄選擇地域。
在左側導航欄,選擇治理中心 > 應用治理。
在應用列表頁面,單擊ACK應用接入。
在ACK應用接入對話框中,進行配置,配置完成后,單擊確定。
配置項
說明
集群類型
選擇ACK集群或者ACK Serverless集群。
說明如果您尚未授權容器服務調用微服務引擎,則需要單擊請授權進行授權。
集群名稱/ID
選擇接入MSE微服務治理的集群名稱/ID,可通過關鍵詞搜索。
ack-onepilot
顯示ack-onepilot接入狀態。
如果您未安裝ack-onepilot,單擊ack-onepilot右側的點擊安裝,安裝完成后狀態會顯示為已安裝。
如果您使用子賬號接入,提示沒有權限使用時,您可以登錄容器服務管理控制臺進入目標集群,然后單擊運維管理>組件管理,然后找到ack-onepilot,點擊安裝。
說明該步驟接入的組件為ack-onepilot,您可以登錄容器服務管理控制臺進入目標集群,然后單擊運維管理>組件管理查看詳情。
ack-onepilot安裝后會自動注入探針,可能會導致應用啟動耗時增加(10s內)。
接入類型
選擇單個應用接入。
接入步驟
按照接入步驟進行操作。
Step 1:進入集群工作負載-無狀態應用頁面,切換到應用的命名空間下。
Step 2:找到所接入的應用,點擊「查看Yaml」。
Step 3:按以下格式編輯Labels,完成后點擊「更新」。
spec: template: metadata: labels: # 填寫“on”表示開啟接入,需加上雙引號 msePilotAutoEnable: "on" # 填寫接入到的治理命名空間,值不存在可自動新建 mseNamespace: 202401 # 填寫接入MSE的實際應用名稱,需加上雙引號 msePilotCreateAppName: "your-deployment-name"
部署Demo應用程序
登錄容器服務管理控制臺,在左側導航欄選擇集群。
在集群列表頁面,單擊目標集群名稱,然后在左側導航欄,選擇 。
在無狀態頁面,選擇命名空間,然后單擊使用YAML創建資源,對模板進行相關配置,完成配置后單擊創建。
本文示例中部署A、B、C三個應用,每個應用分別部署一個基線版本和一個灰度版本,并部署一個Nacos Server應用,用于實現服務發現。
# A應用base版本 --- apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-a spec: replicas: 2 selector: matchLabels: app: spring-cloud-a template: metadata: labels: msePilotCreateAppName: spring-cloud-a app: spring-cloud-a spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-a:3.0.1 imagePullPolicy: Always name: spring-cloud-a ports: - containerPort: 20001 livenessProbe: tcpSocket: port: 20001 initialDelaySeconds: 10 periodSeconds: 30 # A應用gray版本 --- apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-a-new spec: replicas: 2 selector: matchLabels: app: spring-cloud-a-new strategy: template: metadata: labels: alicloud.service.tag: gray msePilotCreateAppName: spring-cloud-a app: spring-cloud-a-new spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre - name: profiler.micro.service.tag.trace.enable value: "true" image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-a:3.0.1 imagePullPolicy: Always name: spring-cloud-a-new ports: - containerPort: 20001 livenessProbe: tcpSocket: port: 20001 initialDelaySeconds: 10 periodSeconds: 30 # B應用base版本 --- apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-b spec: replicas: 2 selector: matchLabels: app: spring-cloud-b strategy: template: metadata: labels: msePilotCreateAppName: spring-cloud-b app: spring-cloud-b spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-b:3.0.1 imagePullPolicy: Always name: spring-cloud-b ports: - containerPort: 8080 livenessProbe: tcpSocket: port: 20002 initialDelaySeconds: 10 periodSeconds: 30 # B應用gray版本 --- apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-b-new spec: replicas: 2 selector: matchLabels: app: spring-cloud-b-new template: metadata: labels: alicloud.service.tag: gray msePilotCreateAppName: spring-cloud-b app: spring-cloud-b-new spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-b:3.0.1 imagePullPolicy: Always name: spring-cloud-b-new ports: - containerPort: 8080 livenessProbe: tcpSocket: port: 20002 initialDelaySeconds: 10 periodSeconds: 30 # C應用base版本 --- apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-c spec: replicas: 2 selector: matchLabels: app: spring-cloud-c template: metadata: labels: msePilotCreateAppName: spring-cloud-c app: spring-cloud-c spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-c:3.0.1 imagePullPolicy: Always name: spring-cloud-c ports: - containerPort: 8080 livenessProbe: tcpSocket: port: 20003 initialDelaySeconds: 10 periodSeconds: 30 # C應用gray版本 --- apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-c-new spec: replicas: 2 selector: matchLabels: app: spring-cloud-c-new template: metadata: labels: alicloud.service.tag: gray msePilotCreateAppName: spring-cloud-c app: spring-cloud-c-new spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-c:3.0.1 imagePullPolicy: IfNotPresent name: spring-cloud-c-new ports: - containerPort: 8080 livenessProbe: tcpSocket: port: 20003 initialDelaySeconds: 10 periodSeconds: 30 # Nacos Server --- apiVersion: apps/v1 kind: Deployment metadata: name: nacos-server spec: replicas: 1 selector: matchLabels: app: nacos-server template: metadata: labels: app: nacos-server spec: containers: - env: - name: MODE value: standalone image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/nacos-server:v2.1.2 imagePullPolicy: Always name: nacos-server dnsPolicy: ClusterFirst restartPolicy: Always # Nacos Server Service配置 --- apiVersion: v1 kind: Service metadata: name: nacos-server spec: ports: - port: 8848 protocol: TCP targetPort: 8848 selector: app: nacos-server type: ClusterIP
配置網絡
針對入口應用A配置兩個K8s Service,spring-cloud-a-base對應A的base版本,spring-cloud-a-gray對應A的gray版本。
apiVersion: v1
kind: Service
metadata:
name: spring-cloud-a-base
spec:
ports:
- name: http
nodePort: 32605
port: 20001
protocol: TCP
targetPort: 20001
selector:
app: spring-cloud-a
sessionAffinity: None
type: NodePort
---
apiVersion: v1
kind: Service
metadata:
name: spring-cloud-a-gray
spec:
ports:
- name: http
nodePort: 31622
port: 20001
protocol: TCP
targetPort: 20001
selector:
app: spring-cloud-a-new
sessionAffinity: None
type: NodePort
步驟一:配置ALB路由
創建ALB Config。具體操作,請參見創建AlbConfig。
重要ALB交換機所在的VPC需與集群所在的VPC一致,否則會影響業務使用。
配置Ingress。
拷貝以下內容到gray-ingress.yaml文件中。
1.19版本以下集群。
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: demo namespace: default spec: ingressClassName: alb rules: - host: www.aliyundoc.com http: paths: - path: /a backend: serviceName: spring-clud-a-base servicePort: 20001 - host: www.example.com http: paths: - backend: serviceName: spring-cloud-a-gray servicePort: 20001 path: /a pathType: ImplementationSpecific
1.19及以上版本集群。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: cafe-ingress spec: ingressClassName: alb rules: - host: www.aliyundoc.com http: paths: # 配置Context Path - path: /a pathType: ImplementationSpecific backend: service: name: spring-clud-a-base port: number: 20001 - host: www.example.com http: paths: # 配置Context Path - path: /a pathType: ImplementationSpecific backend: service: name: spring-clud-a-base-gray port: number: 20001
執行如下命令。
kubectl apply -f gray-ingress.yaml
若沒有出現對應的ADDRESS(端點),可前往以下頁面查看事件,并對照本文的前提條件排查錯誤。
步驟二:配置MSE全鏈路灰度
登錄MSE治理中心控制臺,并在頂部菜單欄選擇地域。
在左側導航欄,選擇治理中心 > 全鏈路灰度。
- 單擊創建泳道組及泳道。如果您選擇的微服務空間內已經創建過泳道組,則單擊+創建泳道組。
在創建泳道組面板,配置泳道組相關參數,然后單擊確定。
添加spring-cloud-a、spring-cloud-b和spring-cloud-c應用到泳道組。
在全鏈路灰度頁面底部,單擊點擊創建第一個分流泳道。在創建泳道面板,設置流控泳道相關參數,選擇標簽gray,然后單擊確定。
步驟三:驗證結果
訪問
www.aliyundoc.com
路由到基線環境。# 測試命令 curl -H"Host:aliyundoc.base.com" http://alb-828vagckg5omzfy49n.cn-beijing.alb.aliyuncs.com/a # 測試結果 A[172.18.XX.XX] -> B[172.18.XX.XX] -> C[172.18.XX.XX]%
訪問
www.example.com
路由到灰度環境。# 測試命令 curl -H"Host:www.example.com" http://alb-828vagckg5omzfy49n.cn-beijing.alb.aliyuncs.com/a # 測試結果 Agray[172.18.XX.XX] -> Bgray[172.18.XX.XX] -> Cgray[172.18.XX.XX]%
其中alb-828vagckg5omzfy49n.cn-beijing.alb.aliyuncs.com
為ALB的地址。