當您需要最佳化網路拓撲、擴容應用伺服器或調整業務流量時,可以通過ASM的流量管理中心實現TCP應用流量的平滑遷移,確保關鍵業務的連續性和服務的高可用性。以Istio官方Task TCP-Traffic-Shifting為例,本文介紹如何在一個TCP服務的兩個版本之間進行流量灰階切換。該Task中的Echo服務有兩個版本,v1版本響應時會在接收到的訊息前添加首碼“one”,v2版本會添加“two”,您可以觀察流量轉移的效果,並對分流策略進行微調,以滿足具體的業務需求和效能目標。
前提條件
已開通以下服務:
已將ACK叢集添加到ASM執行個體。具體操作,請參見建立ASM執行個體和添加叢集到ASM執行個體。
步驟一:部署樣本應用
部署TCP- Echo應用的2個版本。
登入Container Service管理主控台,在左側導覽列選擇叢集。
在叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇。
在無狀態頁面上方,選擇目標命名空間,然後單擊右上方的使用YAML建立資源。
設定樣本模板為自訂,將下面的YAML粘貼到模板文字框,然後單擊建立。
在無狀態頁面,可以看到新建立的兩個版本的TCP-Echo應用。
建立一個服務,並將其對外暴露。
登入Container Service管理主控台,在左側導覽列選擇叢集。
在叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇。
在服務頁面上方,選擇目標命名空間,然後單擊右上方的建立。
在建立服務對話方塊,佈建服務的相關資訊,然後單擊確定。
配置項
說明
服務名稱
配置為tcp-echo。
服務類型
選擇服務類型,即服務訪問的方式。支援虛擬叢集IP、節點連接埠和負載平衡。
說明當服務類型選擇虛擬叢集IP時,才能設定執行個體間探索服務(Headless Service)。您可以使用無頭Service與其他服務發現機制進行介面,不與Kubernetes的實現捆綁在一起。
服務關聯
配置名稱為app,值為tcp-echo-v1。
說明將從關聯的Deployment中提取
app這個標籤作為Service的Selector,這決定了Kubernetes service將流量轉寄到哪個Deployment。由於tcp-echo-v1和tcp-echo-v2兩個Deployment擁有相同的標籤,即app:tcp-echo,因此可以關聯任一Deployment。外部流量策略
支援Local和Cluster。
說明當您的服務類型為節點連接埠或負載平衡時,才能設定外部流量策略。
連接埠映射
本文配置名稱為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版本。
登入ASM控制台,在左側導覽列,選擇。
在網格管理頁面,找到待配置的執行個體,單擊執行個體的名稱或在操作列中單擊管理。
建立服務網關。
在網格詳情頁面左側導覽列,選擇,然後在右側頁面,單擊使用YAML建立。
在建立頁面,命名空間選擇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: - "*"
建立虛擬服務。
在網格詳情頁面左側導覽列,選擇,然後在右側頁面,單擊使用YAML建立。
在建立頁面,命名空間選擇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
建立目標規則。
在網格詳情頁面左側導覽列,選擇,然後在右側頁面,單擊使用YAML建立。
在建立頁面,命名空間選擇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連接埠。
登入ASM控制台,在左側導覽列,選擇。
在網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇。
在入口網關頁面,單擊建立,進行相關配置,然後單擊建立。
部分配置項說明如下。關於配置項的更多說明,請參見建立入口網關。
配置項
說明
部署叢集
選擇要部署入口網關的叢集。
負載平衡CLB類型
本文選擇公網訪問。
選擇負載平衡
使用已有負載平衡:從已有負載平衡列表中選擇。
建立負載平衡CLB:單擊建立負載平衡CLB,從下拉式清單中選擇所需的負載平衡規格。
說明建議您為每個Kubernetes服務分配一個CLB。如果多個Kubernetes服務複用同一個CLB,存在以下風險和限制:
使用已有的CLB會強制覆蓋已有監聽,可能會導致您的應用不可訪問。
Kubernetes通過Service建立的CLB不能複用,只能複用您手動在控制台(或調用OpenAPI)建立的CLB。
複用同一個CLB的多個Service不能有相同的前端監聽連接埠,否則會造成連接埠衝突。
複用CLB時,監聽的名字以及虛擬伺服器組的名字被Kubernetes作為唯一識別碼。請勿修改監聽和虛擬伺服器組的名字。
不支援跨叢集複用CLB。
連接埠映射
單擊添加連接埠,配置名稱為tcp,服務連接埠為31400。
步驟四:檢查部署結果
通過Kubectl確認tcp-echo服務的流量指向是否符合預期。
通過Kubectl用戶端串連至Kubernetes叢集。具體操作,請參見步驟二:選擇叢集憑證類型。
執行以下命令,獲得服務的地址與連接埠。
$ 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}')使用
telnet指令向tcp-echo服務發起串連請求。$ telnet $INGRESS_HOST $INGRESS_PORT Trying xxx.xxx.xxx.xxx... Connected to xxx.xxx.xxx.xxx. Escape character is '^]'輸入任一字元串,按Enter發送。
返回的字串前面帶了“one”,說明tcp-echo服務已經成功部署,且流量全部指向了tcp-echo-v1版本。
步驟五:按比例將流量路由到tcp-echo-v2
此處將20%的流量指向tcp-echo-v2版本,其餘80%仍然打到tcp-echo-v1。
修改ASM執行個體的虛擬服務配置。
在網格詳情頁面左側導覽列,選擇。
在虛擬服務頁面,單擊tcp-echo所在操作列中的YAML。
在編輯執行個體頁面的文字框中輸入以下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
執行以下命令,向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%。