使用嚴(yán)格模式流量泳道實現(xiàn)全鏈路流量管理
當(dāng)您需要對整條調(diào)用鏈路進(jìn)行灰度發(fā)布或版本隔離時,可以使用嚴(yán)格模式的流量泳道,將應(yīng)用的相關(guān)版本(或其他特征)隔離成獨立的運行環(huán)境,確保只有符合特定條件的流量被路由到新的服務(wù)版本,提高發(fā)布過程的穩(wěn)定性和可控性。
前提條件
已創(chuàng)建ASM企業(yè)版或旗艦版實例,且版本為1.18.2.111及以上。具體操作,請參見創(chuàng)建ASM實例或升級ASM實例。
說明若您的實例版本為1.17.2.22及以上,1.18.2.111以下,請參見使用泳道模式下的流量管理功能。
已添加集群到ASM實例。具體操作,請參見添加集群到ASM實例。
已創(chuàng)建名稱為ingressgateway的ASM入口網(wǎng)關(guān)。具體操作,請參見創(chuàng)建入口網(wǎng)關(guān)服務(wù)。
已創(chuàng)建名稱為ingressgateway且命名空間為istio-system的網(wǎng)關(guān)規(guī)則。具體操作,請參見管理網(wǎng)關(guān)規(guī)則。
apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: ingressgateway namespace: istio-system spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - '*'
示例說明
本示例使用mocka、mockb、mockc三個服務(wù)創(chuàng)建代表服務(wù)調(diào)用鏈三個版本的三條泳道:s1、s2、s3。
步驟一:部署示例服務(wù)
為default命名空間啟用Sidecar網(wǎng)格代理自動注入。具體操作,請參見啟用自動注入。
關(guān)于自動注入的更多信息,請參見配置Sidecar注入策略。
在ACK集群中執(zhí)行以下命令,部署示例服務(wù)。
kubectl apply -f https://alibabacloudservicemesh.oss-cn-beijing.aliyuncs.com/asm-labs/swimlane/v1/mock-tracing-v1.yaml kubectl apply -f https://alibabacloudservicemesh.oss-cn-beijing.aliyuncs.com/asm-labs/swimlane/v2/mock-tracing-v2.yaml kubectl apply -f https://alibabacloudservicemesh.oss-cn-beijing.aliyuncs.com/asm-labs/swimlane/v3/mock-tracing-v3.yaml
步驟二:創(chuàng)建泳道組和對應(yīng)泳道
創(chuàng)建泳道組。
登錄ASM控制臺,在左側(cè)導(dǎo)航欄,選擇 。
在網(wǎng)格管理頁面,單擊目標(biāo)實例名稱,然后在左側(cè)導(dǎo)航欄,選擇 。
在流量泳道頁面,單擊創(chuàng)建泳道組,在創(chuàng)建泳道組面板,配置相關(guān)信息,然后單擊確定。
配置項
說明
泳道組名稱
本示例配置為test。
入口網(wǎng)關(guān)
選擇ingressgateway。
泳道模式
選擇嚴(yán)格模式。
泳道服務(wù)
選擇目標(biāo)Kubernetes集群和default命名空間,在下方列表中選中mocka、mockb和mockc服務(wù),單擊圖標(biāo),添加目標(biāo)服務(wù)到已選擇區(qū)域。
創(chuàng)建s1、s2、s3泳道,并分別綁定v1、v2、v3版本。
在流量泳道頁面的流量規(guī)則定義區(qū)域,單擊創(chuàng)建泳道。
在創(chuàng)建泳道對話框,配置相關(guān)信息,然后單擊確定。
配置項
說明
泳道名稱
三條泳道分別配置為s1、s2、s3。
配置服務(wù)標(biāo)簽
標(biāo)簽名稱:選擇ASM_TRAFFIC_TAG。
標(biāo)簽值:三條泳道分別選擇v1、v2、v3。
創(chuàng)建s1泳道的示例圖如下:
三條泳道創(chuàng)建完成后,示例效果如下:
三條泳道創(chuàng)建完成后,針對泳道組中的每個服務(wù)都將生成泳道規(guī)則對應(yīng)的目標(biāo)規(guī)則和虛擬服務(wù)。您可以在控制臺左側(cè)導(dǎo)航欄,選擇
或虛擬服務(wù)進(jìn)行查看。例如,針對mocka服務(wù)會自動創(chuàng)建如下目標(biāo)規(guī)則和虛擬服務(wù)。apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: labels: asm-system: 'true' provider: asm swimlane-group: test name: trafficlabel-dr-test-default-mocka namespace: istio-system spec: host: mocka.default.svc.cluster.local subsets: - labels: ASM_TRAFFIC_TAG: v1 name: s1 - labels: ASM_TRAFFIC_TAG: v2 name: s2 - labels: ASM_TRAFFIC_TAG: v3 name: s3
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: labels: asm-system: 'true' provider: asm swimlane-group: test name: trafficlabel-vs-test-default-mocka namespace: istio-system spec: hosts: - mocka.default.svc.cluster.local http: - match: - sourceLabels: ASM_TRAFFIC_TAG: v1 route: - destination: host: mocka.default.svc.cluster.local subset: s1 - match: - sourceLabels: ASM_TRAFFIC_TAG: v2 route: - destination: host: mocka.default.svc.cluster.local subset: s2 - match: - sourceLabels: ASM_TRAFFIC_TAG: v3 route: - destination: host: mocka.default.svc.cluster.local subset: s3
分別創(chuàng)建三條泳道對應(yīng)的引流規(guī)則。
在流量泳道頁面的流量規(guī)則定義區(qū)域,單擊目標(biāo)泳道右側(cè)操作列下的引流規(guī)則。
在添加引流規(guī)則對話框,配置相關(guān)信息,然后單擊確定。
本文以泳道服務(wù)對應(yīng)入口API均為
/mock
為例,為每條泳道配置相同的引流規(guī)則。配置項
說明
入口服務(wù)
選擇mocka.default.svc.cluster.local。
引流規(guī)則
配置名稱為r1,域名為*。
匹配請求的URI
配置匹配方式為精確,匹配內(nèi)容為/mock。
添加Header匹配規(guī)則
單擊添加Header匹配規(guī)則,配置名稱為x-asm-prefer-tag,匹配方式為精確,三條泳道的匹配內(nèi)容分別配置為s1、s2、s3。
為s1泳道添加引流規(guī)則的示例圖如下:
三條泳道的引流規(guī)則創(chuàng)建成功后,示例效果如下:
創(chuàng)建成功后,會自動生成每條泳道的引流規(guī)則,即虛擬服務(wù)。例如,針對s1泳道會生成如下的虛擬服務(wù)。
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: labels: asm-system: 'true' provider: asm swimlane-group: test name: swimlane-ingress-vs-test-s1 namespace: istio-system spec: gateways: - istio-system/ingressgateway hosts: - '*' http: - match: - headers: x-asm-prefer-tag: exact: s1 uri: exact: /mock name: r1 route: - destination: host: mocka.default.svc.cluster.local subset: s1
步驟三:驗證全鏈路灰度功能是否生效
獲取ASM網(wǎng)關(guān)的公網(wǎng)IP。具體操作,請參見獲取ASM網(wǎng)關(guān)地址。
執(zhí)行以下命令,設(shè)置環(huán)境變量。
xxx.xxx.xxx.xxx
為上一步獲取的IP。export ASM_GATEWAY_IP=xxx.xxx.xxx.xxx
驗證全鏈路灰度功能是否生效。
執(zhí)行以下命令,查看s1泳道的訪問效果。
x-asm-prefer-tag
對應(yīng)的值s1
為步驟二中第2步創(chuàng)建s1泳道時配置的泳道名稱。for i in {1..100}; do curl -H 'x-asm-prefer-tag: s1' http://${ASM_GATEWAY_IP}/mock ; echo ''; sleep 1; done;
預(yù)期輸出:
-> mocka(version: v1, ip: 172.17.0.54)-> mockb(version: v1, ip: 172.17.0.129)-> mockc(version: v1, ip: 172.17.0.130)
由預(yù)期輸出得到,通過設(shè)置HTTP標(biāo)頭
x-asm-prefer-tag: s1
聲明的流量流向s1泳道下的相關(guān)服務(wù),符合預(yù)期。執(zhí)行以下命令,查看s2泳道的訪問效果。
x-asm-prefer-tag
對應(yīng)的值s2
為步驟二中第2步創(chuàng)建s2泳道時配置的泳道名稱。for i in {1..100}; do curl -H 'x-asm-prefer-tag: s2' http://${ASM_GATEWAY_IP}/mock ; echo ''; sleep 1; done;
預(yù)期輸出:
-> mocka(version: v2, ip: 172.17.0.9)-> mockb(version: v2, ip: 172.17.0.126)-> mockc(version: v2, ip: 172.17.0.128)
由預(yù)期輸出得到,通過設(shè)置HTTP標(biāo)頭
x-asm-prefer-tag: s2
聲明的流量流向s2泳道下的相關(guān)服務(wù),符合預(yù)期。執(zhí)行以下命令,查看s3泳道的訪問效果。
x-asm-prefer-tag
對應(yīng)的值s3
為步驟二中第2步創(chuàng)建s3泳道時配置的泳道名稱。for i in {1..100}; do curl -H 'x-asm-prefer-tag: s3' http://${ASM_GATEWAY_IP}/mock ; echo ''; sleep 1; done;
預(yù)期輸出:
-> mocka(version: v3, ip: 172.17.0.132)-> mockb(version: v3, ip: 172.17.0.127)-> mockc(version: v3, ip: 172.17.0.69)
由預(yù)期輸出得到,通過設(shè)置HTTP標(biāo)頭
x-asm-prefer-tag: s3
聲明的流量流向s3泳道下的相關(guān)服務(wù),符合預(yù)期。
通過自定義虛擬服務(wù)為嚴(yán)格模式的泳道引流
流量泳道預(yù)置了配置引流規(guī)則的功能。通過為泳道創(chuàng)建引流規(guī)則,可以在流量泳道對應(yīng)的網(wǎng)關(guān)上創(chuàng)建虛擬服務(wù),從而實現(xiàn)通過ASM入口網(wǎng)關(guān)向不同泳道引流(即轉(zhuǎn)發(fā)請求)的效果。
流量泳道的引流規(guī)則包含針對請求頭以及請求路徑的匹配規(guī)則,您可以通過自定義虛擬服務(wù)的方式來實現(xiàn)更復(fù)雜的匹配規(guī)則或者自定義請求路由的需求。
在使用自定義虛擬服務(wù)為泳道引流時,不建議創(chuàng)建泳道的引流規(guī)則,因為自定義虛擬服務(wù)和泳道內(nèi)置的引流規(guī)則可能會發(fā)生沖突,從而導(dǎo)致流量分發(fā)過程出現(xiàn)異常或不可預(yù)期的情況。
基于ASM網(wǎng)關(guān)創(chuàng)建自定義虛擬服務(wù)
以文中場景為例,在步驟二的第3步:分別創(chuàng)建三個泳道對應(yīng)的引流規(guī)則,將創(chuàng)建引流規(guī)則的步驟,改為使用以下內(nèi)容創(chuàng)建虛擬服務(wù)。具體操作,請參見管理虛擬服務(wù)。
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: swimlane-ingress-vs-custom namespace: istio-system spec: gateways: - istio-system/ingressgateway hosts: - '*' http: - match: # 這條匹配規(guī)則表示精準(zhǔn)匹配形如 env: dev 的請求頭 - headers: env: exact: dev name: dev-route route: - destination: host: mocka.default.svc.cluster.local # 流量轉(zhuǎn)發(fā)的目標(biāo)服務(wù) subset: s2 # subset 填寫泳道的名稱 weight: 50 - destination: host: mocka.default.svc.cluster.local # 流量轉(zhuǎn)發(fā)的目標(biāo)服務(wù) subset: s3 # subset 填寫泳道的名稱 weight: 50 - name: base-route route: - destination: host: mocka.default.svc.cluster.local # 流量轉(zhuǎn)發(fā)的目標(biāo)服務(wù) subset: s1 # subset 填寫泳道的名稱
執(zhí)行步驟三:驗證全鏈路灰度功能是否生效中的命令,訪問s1、s2、s3三條泳道的預(yù)期輸出如下:
-> mocka(version: v1, ip: 192.168.0.50)-> mockb(version: v1, ip: 192.168.0.46)-> mockc(version: v1, ip: 192.168.0.48)
執(zhí)行以下命令,驗證在訪問s1泳道時帶有header
env: dev
的效果。for i in {1..100}; do curl -H 'x-asm-prefer-tag: s1' -H 'env: dev' http://${ASM_GATEWAY_IP}/mock ; echo ''; sleep 1; done;
預(yù)期輸出:
-> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
可以看到帶有header
env: dev
時訪問泳道s1返回的是v2和v3的鏈路,比例大約50:50左右。即對于帶有env: dev
請求頭的請求,請求將會以50:50的比例轉(zhuǎn)發(fā)到s2和s3泳道,其余請求將會被轉(zhuǎn)發(fā)到s1泳道。
上述的虛擬服務(wù)在ASM網(wǎng)關(guān)上指定了一個自定義的路由規(guī)則,從而將流量轉(zhuǎn)發(fā)到不同的流量泳道。當(dāng)通過自定義虛擬服務(wù)為嚴(yán)格模式的泳道引流時,想要將請求發(fā)往某條泳道,只需要在虛擬服務(wù)的路由目標(biāo)subset
字段中填寫泳道名稱即可。當(dāng)請求發(fā)往一條流量泳道后,后續(xù)的流量調(diào)用將保持在該泳道內(nèi)部。
基于Sidecar創(chuàng)建自定義虛擬服務(wù)
除了在ASM網(wǎng)關(guān)上指定自定義路由規(guī)則外,您也可以通過生效在所有Sidecar上的虛擬服務(wù)來指定集群內(nèi)部服務(wù)訪問流量泳道內(nèi)服務(wù)的引流規(guī)則。與ASM網(wǎng)關(guān)自定義路由規(guī)則不同,Sidecar虛擬服務(wù)不再需要gateway
字段,且hosts
中填寫的是mocka
服務(wù)的集群本地服務(wù)域名。示例YAML如下:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: swimlane-ingress-vs-custom
namespace: istio-system
spec:
hosts:
- mocka.default.svc.cluster.local
http:
- match: # 這條匹配規(guī)則表示精準(zhǔn)匹配形如 env: dev 的請求頭
- headers:
env:
exact: dev
name: dev-route
route:
- destination:
host: mocka.default.svc.cluster.local # 流量轉(zhuǎn)發(fā)的目標(biāo)服務(wù)
subset: s2 # subset 填寫泳道的名稱
weight: 50
- destination:
host: mocka.default.svc.cluster.local # 流量轉(zhuǎn)發(fā)的目標(biāo)服務(wù)
subset: s3 # subset 填寫泳道的名稱
weight: 50
- name: base-route
route:
- destination:
host: mocka.default.svc.cluster.local # 流量轉(zhuǎn)發(fā)的目標(biāo)服務(wù)
subset: s1 # subset 填寫泳道的名稱
執(zhí)行以下命令,驗證Sidecar模式下不帶
env: dev
請求頭時訪問mocka服務(wù)。kubectl exec -it deploy/sleep -c sleep -- sh -c 'for i in $(seq 1 100); do curl http://mocka:8000; echo ""; sleep 1; done;'
預(yù)期輸出:
-> mocka(version: v1, ip: 192.168.0.50)-> mockb(version: v1, ip: 192.168.0.46)-> mockc(version: v1, ip: 192.168.0.48)
可以看到,不帶
env: dev
請求頭時訪問所有泳道返回的都是v1鏈路,說明流量全部進(jìn)入了s1泳道。執(zhí)行以下命令,驗證Sidecar模式下帶有
env: dev
請求頭時訪問mocka服務(wù)。kubectl exec -it deploy/sleep -c sleep -- sh -c 'for i in $(seq 1 100); do curl -H "env: dev" http://mocka:8000; echo ""; sleep 1; done;'
預(yù)期輸出:
-> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v2, ip: 192.168.0.47)-> mockb(version: v2, ip: 192.168.0.49)-> mockc(version: v2, ip: 192.168.0.43) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45) -> mocka(version: v3, ip: 192.168.0.44)-> mockb(version: v3, ip: 192.168.0.42)-> mockc(version: v3, ip: 192.168.0.45)
可以看到,以上預(yù)期輸出與基于ASM網(wǎng)關(guān)創(chuàng)建自定義虛擬服務(wù)中的預(yù)期輸出一致,帶有
env: dev
請求頭時訪問mocka服務(wù),流量會以50:50的比例進(jìn)入s2和s3泳道。
與基于ASM網(wǎng)關(guān)創(chuàng)建自定義虛擬服務(wù)原理相同,當(dāng)集群內(nèi)其它服務(wù)調(diào)用泳道內(nèi)的mocka服務(wù)時,后續(xù)的請求調(diào)用鏈將一直保持在泳道內(nèi)部。
相關(guān)文檔
流量泳道分為嚴(yán)格與寬松兩種模式。關(guān)于兩種模式的說明和差異,請參見流量泳道概述。
當(dāng)您的應(yīng)用程序在調(diào)用鏈路中存在透傳請求頭的行為時,寬松模式可以實現(xiàn)更為靈活的泳道使用場景,例如只發(fā)布了調(diào)用鏈路中的部分服務(wù)的新版本,基于這些新版本服務(wù)構(gòu)建測試環(huán)境。具體操作,請參見使用寬松模式流量泳道實現(xiàn)全鏈路流量管理。
您可以基于VirtualService和DestinationRule等流量規(guī)則實現(xiàn)流量泳道,同時通過配置流量降級,在某個版本(或者其他特征)的應(yīng)用不可用時,將流量發(fā)往一個指定的降級版本(或其他特征)的應(yīng)用。具體操作,請參見基于流量規(guī)則配置實現(xiàn)流量泳道和流量降級。
關(guān)于虛擬服務(wù)的詳細(xì)CRD定義,請參見虛擬服務(wù)(Virtual Service)CRD說明。