全部產品
Search
文件中心

Alibaba Cloud Service Mesh:通過ASM實現TCP應用流量遷移

更新時間:Jun 30, 2024

當您需要最佳化網路拓撲、擴容應用伺服器或調整業務流量時,可以通過ASM的流量管理中心實現TCP應用流量的平滑遷移,確保關鍵業務的連續性和服務的高可用性。以Istio官方Task TCP-Traffic-Shifting為例,本文介紹如何在一個TCP服務的兩個版本之間進行流量灰階切換。該Task中的Echo服務有兩個版本,v1版本響應時會在接收到的訊息前添加首碼“one”,v2版本會添加“two”,您可以觀察流量轉移的效果,並對分流策略進行微調,以滿足具體的業務需求和效能目標。

前提條件

步驟一:部署樣本應用

  1. 部署TCP- Echo應用的2個版本。

    1. 登入Container Service管理主控台,在左側導覽列選擇叢集

    2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇工作負載 > 無狀態

    3. 無狀態頁面上方,選擇目標命名空間,然後單擊右上方的使用YAML建立資源

    4. 設定樣本模板自訂,將下面的YAML粘貼到模板文字框,然後單擊建立

      展開查看YAML

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: tcp-echo-v1
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: tcp-echo
            version: v1
        template:
          metadata:
            labels:
              app: tcp-echo
              version: v1
          spec:
            containers:
            - name: tcp-echo
              image: docker.io/istio/tcp-echo-server:1.1
              imagePullPolicy: IfNotPresent
              args: [ "9000", "one" ]
              ports:
              - containerPort: 9000
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: tcp-echo-v2
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: tcp-echo
            version: v2
        template:
          metadata:
            labels:
              app: tcp-echo
              version: v2
          spec:
            containers:
            - name: tcp-echo
              image: docker.io/istio/tcp-echo-server:1.1
              imagePullPolicy: IfNotPresent
              args: [ "9000", "two" ]
              ports:
              - containerPort: 9000

      無狀態頁面,可以看到新建立的兩個版本的TCP-Echo應用。

  2. 建立一個服務,並將其對外暴露。

    1. 登入Container Service管理主控台,在左側導覽列選擇叢集

    2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇網路 > 服務

    3. 服務頁面上方,選擇目標命名空間,然後單擊右上方的建立

    4. 建立服務對話方塊,佈建服務的相關資訊,然後單擊確定

      配置項

      說明

      服務名稱

      配置為tcp-echo

      服務類型

      選擇服務類型,即服務訪問的方式。支援虛擬叢集IP節點連接埠負載平衡

      說明

      服務類型選擇虛擬叢集IP時,才能設定執行個體間探索服務(Headless Service)。您可以使用無頭Service與其他服務發現機制進行介面,不與Kubernetes的實現捆綁在一起。

      服務關聯

      配置名稱apptcp-echo-v1

      說明

      將從關聯的Deployment中提取app這個標籤作為Service的Selector,這決定了Kubernetes service將流量轉寄到哪個Deployment。由於tcp-echo-v1和tcp-echo-v2兩個Deployment擁有相同的標籤,即app:tcp-echo,因此可以關聯任一Deployment。

      外部流量策略

      支援LocalCluster

      說明

      當您的服務類型為節點連接埠負載平衡時,才能設定外部流量策略

      連接埠映射

      本文配置名稱tcp服務連接埠容器連接埠9000協議TCP

      註解

      為該服務添加一個註解(annotation),配置負載平衡的參數。例如,設定service.beta.kubernetes.io/alicloud-loadbalancer-bandwidth:20表示將該服務的頻寬峰值設定為20 Mbit/s,控制服務的流量。關於參數的說明,請參見通過Annotation配置傳統型負載平衡CLB

      標籤

      為服務添加一個標籤,標識該服務。

      建立成功後,在服務頁面,可以看到新建立的tcp-echo服務。

步驟二:設定路由規則

通過設定Service Mesh的Istio網關、虛擬服務和目標規則,將流量全部指向tcp-echo服務的v1版本。

  1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

  2. 網格管理頁面,找到待配置的執行個體,單擊執行個體的名稱或在操作列中單擊管理

  3. 建立服務網關。

    1. 在網格詳情頁面左側導覽列,選擇ASM網關 > 網關規則,然後在右側頁面,單擊使用YAML建立

    2. 建立頁面,命名空間選擇default,選擇任意情境模版,配置以下YAML,然後單擊建立

      apiVersion: networking.istio.io/v1alpha3
      kind: Gateway
      metadata:
        name: tcp-echo-gateway
      spec:
        selector:
          istio: ingressgateway
        servers:
        - port:
            number: 31400
            name: tcp
            protocol: TCP
          hosts:
          - "*"
  4. 建立虛擬服務。

    1. 在網格詳情頁面左側導覽列,選擇流量管理中心 > 虛擬服務,然後在右側頁面,單擊使用YAML建立

    2. 建立頁面,命名空間選擇default,選擇任意情境模版,配置以下YAML,然後單擊建立

      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: tcp-echo
      spec:
        hosts:
        - "*"
        gateways:
        - tcp-echo-gateway
        tcp:
        - match:
          - port: 31400
          route:
          - destination:
              host: tcp-echo
              port:
                number: 9000
              subset: v1
  5. 建立目標規則。

    1. 在網格詳情頁面左側導覽列,選擇流量管理中心 > 目標規則,然後在右側頁面,單擊使用YAML建立

    2. 建立頁面,命名空間選擇default,選擇任意情境模版,配置以下YAML,然後單擊建立

      apiVersion: networking.istio.io/v1alpha3
      kind: DestinationRule
      metadata:
        name: tcp-echo-destination
      spec:
        host: tcp-echo
        subsets:
        - name: v1
          labels:
            version: v1
        - name: v2
          labels:
            version: v2

步驟三:部署入口網關

在入口網關中,添加連接埠31400,並指向Istio網關的31400連接埠。

  1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

  2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇ASM網關 > 入口網關

  3. 入口網關頁面,單擊建立,進行相關配置,然後單擊建立

    部分配置項說明如下。關於配置項的更多說明,請參見建立入口網關

    配置項

    說明

    部署叢集

    選擇要部署入口網關的叢集。

    負載平衡CLB類型

    本文選擇公網訪問

    選擇負載平衡

    • 使用已有負載平衡:從已有負載平衡列表中選擇。

    • 建立負載平衡CLB:單擊建立負載平衡CLB,從下拉式清單中選擇所需的負載平衡規格。

    說明

    建議您為每個Kubernetes服務分配一個CLB。如果多個Kubernetes服務複用同一個CLB,存在以下風險和限制:

    • 使用已有的CLB會強制覆蓋已有監聽,可能會導致您的應用不可訪問。

    • Kubernetes通過Service建立的CLB不能複用,只能複用您手動在控制台(或調用OpenAPI)建立的CLB。

    • 複用同一個CLB的多個Service不能有相同的前端監聽連接埠,否則會造成連接埠衝突。

    • 複用CLB時,監聽的名字以及虛擬伺服器組的名字被Kubernetes作為唯一識別碼。請勿修改監聽和虛擬伺服器組的名字。

    • 不支援跨叢集複用CLB。

    連接埠映射

    單擊添加連接埠,配置名稱tcp服務連接埠31400

步驟四:檢查部署結果

通過Kubectl確認tcp-echo服務的流量指向是否符合預期。

  1. 通過Kubectl用戶端串連至Kubernetes叢集。具體操作,請參見步驟二:選擇叢集憑證類型

  2. 執行以下命令,獲得服務的地址與連接埠。

    $ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    $ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="tcp")].port}')
  3. 使用telnet指令向tcp-echo服務發起串連請求。

    $ telnet $INGRESS_HOST $INGRESS_PORT
    Trying xxx.xxx.xxx.xxx...
    Connected to xxx.xxx.xxx.xxx.
    Escape character is '^]'
  4. 輸入任一字元串,按Enter發送。

    返回的字串前面帶了“one”,說明tcp-echo服務已經成功部署,且流量全部指向了tcp-echo-v1版本。

步驟五:按比例將流量路由到tcp-echo-v2

此處將20%的流量指向tcp-echo-v2版本,其餘80%仍然打到tcp-echo-v1。

  1. 修改ASM執行個體的虛擬服務配置。

    1. 在網格詳情頁面左側導覽列,選擇流量管理中心 > 虛擬服務

    2. 虛擬服務頁面,單擊tcp-echo所在操作列中的YAML

    3. 編輯執行個體頁面的文字框中輸入以下YAML檔案內容,單擊確定

      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: tcp-echo
      spec:
        hosts:
        - "*"
        gateways:
        - tcp-echo-gateway
        tcp:
        - match:
          - port: 31400
          route:
          - destination:
              host: tcp-echo
              port:
                number: 9000
              subset: v1
            weight: 80
          - destination:
              host: tcp-echo
              port:
                number: 9000
              subset: v2
            weight: 20
  2. 執行以下命令,向tcp-echo服務發起10次請求。

    $ for i in {1..10}; do \
    docker run -e INGRESS_HOST=$INGRESS_HOST -e INGRESS_PORT=$INGRESS_PORT -it --rm busybox sh -c "(date; sleep 1) | nc $INGRESS_HOST $INGRESS_PORT"; \
    done
    one Mon Nov 12 23:38:45 UTC 2018
    two Mon Nov 12 23:38:47 UTC 2018
    one Mon Nov 12 23:38:50 UTC 2018
    one Mon Nov 12 23:38:52 UTC 2018
    one Mon Nov 12 23:38:55 UTC 2018
    two Mon Nov 12 23:38:57 UTC 2018
    one Mon Nov 12 23:39:00 UTC 2018
    one Mon Nov 12 23:39:02 UTC 2018
    one Mon Nov 12 23:39:05 UTC 2018
    one Mon Nov 12 23:39:07 UTC 2018

    根據以上請求的分發情況,可以看到20%的流量指向了tcp-echo-v2。

    說明

    您的測試結果可能不一定總是10次中有2次打到tcp-echo-v2,但從較長時間範圍的總體比例來看,將接近20%。