天天看點

基于阿裡雲微服務引擎 MSE 的全鍊路灰階實踐

前提條件

本文假設您的 ACK 叢集已經建立完成。

開啟 MSE 微服務治理

基于阿裡雲微服務引擎 MSE 的全鍊路灰階實踐
  • 安裝

    ack-kubernetes-cronhpa-controller

    ,安裝步驟請參考之前的說明
  • ack-ingress-nginx

  • 通路 MSE 控制台,在K8s叢集清單中選擇相應叢集,點選管理,選擇

    default

    命名空間,點選開啟服務治理能力。
基于阿裡雲微服務引擎 MSE 的全鍊路灰階實踐

開啟 AHAS 應用防護

  • 點選開通 AHAS 應用防護 以使用應用流控能力,請注意,需要開通 AHAS 流量防護專業版
基于阿裡雲微服務引擎 MSE 的全鍊路灰階實踐
  • ack-ahas-sentinel-pilot

部署 Demo 應用程式

将下面的檔案儲存到 mse-demo.yaml 中,并執行

kubectl apply -f mse-demo.yaml

以部署應用,這裡我們将要部署 zuul,A, B, C 三個應用,其中 A、B 兩個應用分别部署一個基線版本和一個灰階版本,B應用的基線版本關閉了無損下線能力,灰階版本開啟了無損下線能力。C應用有一個

spring-cloud-c-warmup

 應用,開啟了服務預熱能力,其中預熱時長為2分鐘。

# 入口 zuul 應用
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-cloud-zuul
spec:
  replicas: 1
  selector:
    matchLabels:
      app: spring-cloud-zuul
  template:
    metadata:
      annotations:
        msePilotCreateAppName: spring-cloud-zuul
        alibabacloud.com/burst-resource: eci
      labels:
        app: spring-cloud-zuul
    spec:
      containers:
        - env:
            - name: JAVA_HOME
              value: /usr/lib/jvm/java-1.8-openjdk/jre
            - name: LANG
              value: C.UTF-8
          image: registry-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-zuul:1.0.1
          imagePullPolicy: Always
          name: spring-cloud-zuul
          ports:
            - containerPort: 20000


# A 應用 base 版本,開啟按照機器緯度全鍊路透傳
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: spring-cloud-a
  name: spring-cloud-a
spec:
  replicas: 2
  selector:
    matchLabels:
      app: spring-cloud-a
  template:
    metadata:
      annotations:
        msePilotCreateAppName: spring-cloud-a
        ahasPilotAutoEnable: "on"
        ahasAppName: spring-cloud-a
        armsPilotAutoEnable: "on"
        armsPilotCreateAppName: spring-cloud-a
        alibabacloud.com/burst-resource: eci
        k8s.aliyun.com/eci-use-specs: 4-8Gi
      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: profiler.micro.service.tag.trace.enable
          value: "true"
        image: registry-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-a:0.1-SNAPSHOT
        imagePullPolicy: Always
        name: spring-cloud-a
        ports:
        - containerPort: 20001
          protocol: TCP
        resources:
          requests:
            cpu: '4'
            memory: 8Gi
        livenessProbe:
          tcpSocket:
            port: 20001
          initialDelaySeconds: 10
          periodSeconds: 30
      
# A 應用 gray 版本,開啟按照機器緯度全鍊路透傳
---            
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: spring-cloud-a-gray
  name: spring-cloud-a-gray
spec:
  replicas: 2
  selector:
    matchLabels:
      app: spring-cloud-a-gray
  strategy:
  template:
    metadata:
      annotations:
        alicloud.service.tag: gray
        msePilotCreateAppName: spring-cloud-a
        alibabacloud.com/burst-resource: eci
        k8s.aliyun.com/eci-use-specs: 4-8Gi
      labels:
        app: spring-cloud-a-gray
    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"
        image: registry-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-a:0.1-SNAPSHOT
        imagePullPolicy: Always
        name: spring-cloud-a-gray
        ports:
        - containerPort: 20001
          protocol: TCP
        resources:
          requests:
            cpu: '4'
            memory: 8Gi
        livenessProbe:
          tcpSocket:
            port: 20001
          initialDelaySeconds: 10
          periodSeconds: 30
            
# B 應用 base 版本,關閉無損下線能力
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: spring-cloud-b
  name: spring-cloud-b
spec:
  replicas: 2
  selector:
    matchLabels:
      app: spring-cloud-b
  strategy:
  template:
    metadata:
      annotations:
        msePilotCreateAppName: spring-cloud-b
        alibabacloud.com/burst-resource: eci
        k8s.aliyun.com/eci-use-specs: 4-8Gi
      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: micro.service.shutdown.server.enable
          value: "false"
        - name: profiler.micro.service.http.server.enable
          value: "false"
        - name: profiler.micro.service.warmup.enable
          value: "true"
        image: registry-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-b:0.1-SNAPSHOT
        imagePullPolicy: Always
        name: spring-cloud-b
        ports:
        - containerPort: 8080
          protocol: TCP
        resources:
          requests:
            cpu: '4'
            memory: 8Gi
        livenessProbe:
          tcpSocket:
            port: 20002
          initialDelaySeconds: 10
          periodSeconds: 30
            
# B 應用 gray 版本,預設開啟無損下線功能
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: spring-cloud-b-gray
  name: spring-cloud-b-gray
spec:
  replicas: 2
  selector:
    matchLabels:
      app: spring-cloud-b-gray
  template:
    metadata:
      annotations:
        alicloud.service.tag: gray
        msePilotCreateAppName: spring-cloud-b
        alibabacloud.com/burst-resource: eci
        k8s.aliyun.com/eci-use-specs: 4-8Gi
      labels:
        app: spring-cloud-b-gray
    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.warmup.enable
          value: "true"
        image: registry-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-b:0.1-SNAPSHOT
        imagePullPolicy: Always
        name: spring-cloud-b-gray
        ports:
        - containerPort: 8080
          protocol: TCP
        resources:
          requests:
            cpu: '4'
            memory: 8Gi
        livenessProbe:
          tcpSocket:
            port: 20002
          initialDelaySeconds: 10
          periodSeconds: 30
        lifecycle:
            preStop:
              exec:
                command:
                  - /bin/sh
                  - '-c'
                  - >-
                    wget http://127.0.0.1:54199/offline 2>/tmp/null;sleep
                    30;exit 0
            
# C 應用 base 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: spring-cloud-c
  name: spring-cloud-c
spec:
  replicas: 2
  selector:
    matchLabels:
      app: spring-cloud-c
  template:
    metadata:
      annotations:
        msePilotCreateAppName: spring-cloud-c
        alibabacloud.com/burst-resource: eci
        k8s.aliyun.com/eci-use-specs: 4-8Gi
      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
        image: registry-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-c:0.1-SNAPSHOT
        imagePullPolicy: Always
        name: spring-cloud-c
        ports:
        - containerPort: 8080
          protocol: TCP
        resources:
          requests:
            cpu: '4'
            memory: 8Gi
        livenessProbe:
          tcpSocket:
            port: 20003
          initialDelaySeconds: 10
          periodSeconds: 30
            
# C 應用 warmup 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: spring-cloud-c-warmup
  name: spring-cloud-c-warmup
spec:
  replicas: 1
  selector:
    matchLabels:
      app: spring-cloud-c-warmup
  template:
    metadata:
      annotations:
        msePilotCreateAppName: spring-cloud-c-warmup
        alibabacloud.com/burst-resource: eci
        k8s.aliyun.com/eci-use-specs: 4-8Gi
      labels:
        app: spring-cloud-c-warmup
    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.warmup.enable
          value: "true"
        - name: profiler.micro.service.warmup.time
          value: "120"
        image: registry-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-c:0.1-SNAPSHOT
        imagePullPolicy: IfNotPresent
        name: spring-cloud-c-warmup
        ports:
        - containerPort: 8080
          protocol: TCP
        resources:
          requests:
            cpu: '4'
            memory: 8Gi
        livenessProbe:
          tcpSocket:
            port: 20003
          initialDelaySeconds: 10
          periodSeconds: 30
        lifecycle:
            preStop:
              exec:
                command:
                  - /bin/sh
                  - '-c'
                  - >-
                    wget http://127.0.0.1:54199/offline 2>/tmp/null;sleep
                    30;exit 0

# Nacos Server
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nacos-server
  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-vpc.cn-beijing.aliyuncs.com/wangtao-mse/nacos-server:latest
        imagePullPolicy: Always
        name: nacos-server
        resources:
          requests:
            cpu: 250m
            memory: 512Mi
      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

#HPA 配置
---
apiVersion: autoscaling.alibabacloud.com/v1beta1
kind: CronHorizontalPodAutoscaler
metadata:
  labels:
    controller-tools.k8s.io: "1.0"
  name: spring-cloud-b
spec:
   scaleTargetRef:
      apiVersion: apps/v1beta2
      kind: Deployment
      name: spring-cloud-b
   jobs:
   - name: "scale-down"
     schedule: "0 */4 * * * *"
     targetSize: 2
   - name: "scale-up"
     schedule: "2 */4 * * * *"
     targetSize: 4
---
apiVersion: autoscaling.alibabacloud.com/v1beta1
kind: CronHorizontalPodAutoscaler
metadata:
  labels:
    controller-tools.k8s.io: "1.0"
  name: spring-cloud-b-gray
spec:
   scaleTargetRef:
      apiVersion: apps/v1beta2
      kind: Deployment
      name: spring-cloud-b-gray
   jobs:
   - name: "scale-down"
     schedule: "0 */5 * * * *"
     targetSize: 2
   - name: "scale-up"
     schedule: "3 */5 * * * *"
     targetSize: 4
---
apiVersion: autoscaling.alibabacloud.com/v1beta1
kind: CronHorizontalPodAutoscaler
metadata:
  labels:
    controller-tools.k8s.io: "1.0"
  name: spring-cloud-c-warmup
spec:
   scaleTargetRef:
      apiVersion: apps/v1beta2
      kind: Deployment
      name: spring-cloud-c-warmup
   jobs:
   - name: "scale-down"
     schedule: "0 */4 * * * *"
     targetSize: 0
   - name: "scale-up"
     schedule: "1 */4 * * * *"
     targetSize: 1


# zuul 網關開啟 SLB 暴露展示頁面   
---     
apiVersion: v1
kind: Service
metadata:
  name: zuul-slb
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 20000
  selector:
    app: spring-cloud-zuul
  type: ClusterIP


# 為 zuul 網關開啟 Ingress
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: zuul
spec:
  rules:
    - http:
        paths:
          - backend:
              serviceName: zuul-slb
              servicePort: 80
            path: /      

流量壓力來源

spring-cloud-zuul

應用中,每個 pod 具備并發為 100 qps 的通路本地 zuul 端口的

127.0.0.1:20000:/A/a

的http請求流量,另外有10 qps 會通路

127.0.0.1:20000:/A/a

并且帶上

x-mse-tag=gray

這個header,目前 zuul 的 pod 數為1,是以

spring-cloud-a

 應用的平均qps為 110。壓力可以通過 環境變量

demo.qps

來調節壓力大小,預設為100

流量架構圖如下:

基于阿裡雲微服務引擎 MSE 的全鍊路灰階實踐

結果驗證

MSE 場景一:對經過機器的流量進行自動染色,實作全鍊路灰階

我們在 MSE 控制台對

spring-cloud-a

  應用配置如下流量比例規則,由于我們對 spring-cloud-a 應用增加了

profiler.micro.service.tag.trace.enable=true

的開關,spring-cloud-a 應用會對經過他的流量進行染色透傳,進而實作全鍊路灰階。

spring-cloud-a

中,灰階分組的流量是10,基線分組的流量是100.

基于阿裡雲微服務引擎 MSE 的全鍊路灰階實踐

spring-cloud-b 中,灰階分組的流量是也是10,基線分組的流量是100.

基于阿裡雲微服務引擎 MSE 的全鍊路灰階實踐

找到 容器服務對外暴露的 Ingress 的端點。

基于阿裡雲微服務引擎 MSE 的全鍊路灰階實踐

在指令行中輸入以下指令,發現正常的流量走到基線的機器上

curl http://$IP/A/a
A[172.16.2.16] -> B[172.16.2.20] -> C[172.16.2.21]      

在指令行中輸入一下指令,帶上特殊的 header ,發現灰階的流量走到灰階的機器上,并且會向後透傳經過 A 和 B 的灰階機器,最後回到 C的基線版本中。

curl -H"x-mse-tag:gray" http://$IP/A/a
Agray[172.16.2.23] -> Bgray[172.16.2.18] -> C[172.16.2.21]      

MSE 場景二:服務預熱

我們在

spring-cloud-c-warmup

應用開啟了定時HPA模拟應用啟動的過程,同時對spring-cloud-c-warmup 應用開啟了預設2分鐘時長的預熱功能

profiler.micro.service.warmup.time=120

基于阿裡雲微服務引擎 MSE 的全鍊路灰階實踐

可以直接在spring-cloud-c-warmup應用直覺地看到效果

基于阿裡雲微服務引擎 MSE 的全鍊路灰階實踐

從上圖可以看出來流量緩慢增大,直覺地服務預熱看到服務預熱的效果。

MSE 場景三:無損下線

由于我們對

spring-cloud-b

spring-cloud-b-gray

應用均開啟了定時HPA,模拟每4分鐘進行一次定時的擴縮容。

基于阿裡雲微服務引擎 MSE 的全鍊路灰階實踐
基于阿裡雲微服務引擎 MSE 的全鍊路灰階實踐

我們可以直接從

spring-cloud-a

應用的監控看出來,未開啟無損下線功能的監控存在錯誤。而 gray的流量因為預設開啟了無損下線功能,流量預設無損。

基于阿裡雲微服務引擎 MSE 的全鍊路灰階實踐

可以看到gray的流量在pod擴縮容的過程中無流量損失,未打标的流量由于關閉了無損下線功能,在pod擴縮容的過程中流量出現了損失,如上圖所示未打标的流量有 122 的請求錯誤。

通過 AHAS 實作限流降級

打開

AHAS 控制台

,找到

spring-cloud-a

應用,選擇接口詳情,找到

/a

接口,點選 + 好号新增流控規則

基于阿裡雲微服務引擎 MSE 的全鍊路灰階實踐

選擇流控規則,輸入單機 QPS 限流門檻值 10,點選下一步,最後點選新增。

基于阿裡雲微服務引擎 MSE 的全鍊路灰階實踐

點選新增添加流控規則

基于阿裡雲微服務引擎 MSE 的全鍊路灰階實踐

等待約 10s 左右,觀察 接口的 QPS 情況,發現通過 QPS 從 100 下降到 20,拒絕 QPS 從 0 上升到 80,因為

spring-cloud-a

有兩台機器,是以總的通過 QPS 為 20.

基于阿裡雲微服務引擎 MSE 的全鍊路灰階實踐

接下來,将該限流規則關閉

基于阿裡雲微服務引擎 MSE 的全鍊路灰階實踐

觀察 QPS , 發現 通過 QPS 回到 100,拒絕 QPS 降低為 0。

基于阿裡雲微服務引擎 MSE 的全鍊路灰階實踐

繼續閱讀