在代管 Cloud Service Mesh 中設定多叢集網格
Google Cloud 詳情請參閱「Cloud Service Mesh 總覽」。本指南說明如何使用 Mesh CA 或憑證授權單位服務,將兩個叢集加入單一 Cloud Service Mesh,並啟用跨叢集負載平衡功能。您可以輕鬆擴充這個程序,將任意數量的叢集納入網格中。
多叢集 Cloud Service Mesh 設定可解決多種重要的企業情境,例如規模、位置和隔離。詳情請參閱「多叢集應用實例」。
事前準備
本指南假設您有兩個以上 Google Cloud GKE 叢集符合下列條件:
- 在叢集上安裝 Cloud Service Mesh。您需要 asmcli、istioctl工具,以及asmcli下載至您在--output_dir中指定的目錄的範例。
- 您必須先讓網格中的叢集與所有 Pod 建立連線,才能設定 Cloud Service Mesh。此外,如果您加入的叢集不在同一個專案中,則必須註冊至同一個機群主機專案,且叢集必須位於同一個網路的共用虛擬私有雲設定中。此外,我們建議您建立一個專案來主控共用虛擬私有雲,以及兩個服務專案來建立叢集。如需更多資訊,請參閱「透過共用虛擬私人雲端設定叢集」。
- 如果您使用憑證授權單位服務,所有叢集都必須將各自的從屬 CA 集區鏈結至相同的根 CA 集區。否則,所有集區都必須使用相同的 CA 集區。
設定專案和叢集變數
- 為專案 ID、叢集區或區域、叢集名稱和內容建立下列環境變數。 - export PROJECT_1=PROJECT_ID_1 export LOCATION_1=CLUSTER_LOCATION_1 export CLUSTER_1=CLUSTER_NAME_1 export CTX_1="gke_${PROJECT_1}_${LOCATION_1}_${CLUSTER_1}" export PROJECT_2=PROJECT_ID_2 export LOCATION_2=CLUSTER_LOCATION_2 export CLUSTER_2=CLUSTER_NAME_2 export CTX_2="gke_${PROJECT_2}_${LOCATION_2}_${CLUSTER_2}"
- 如果這些是新建立的叢集,請務必使用下列 - gcloud指令擷取每個叢集的憑證,否則,相關聯的- context將無法在本指南的後續步驟中使用。- 指令會因叢集類型而異,叢集類型可分為區域或區域叢集: - 區域- gcloud container clusters get-credentials ${CLUSTER_1} --region ${LOCATION_1} gcloud container clusters get-credentials ${CLUSTER_2} --region ${LOCATION_2}- 可用區- gcloud container clusters get-credentials ${CLUSTER_1} --zone ${LOCATION_1} gcloud container clusters get-credentials ${CLUSTER_2} --zone ${LOCATION_2}
建立防火牆規則
在某些情況下,您需要建立防火牆規則,才能允許跨叢集流量。舉例來說,如果您符合下列情況,就需要建立防火牆規則:
- 您會為網格中的叢集使用不同的子網路。
- Pod 開啟的通訊埠不是 443 和 15002。
GKE 會自動在每個節點中新增防火牆規則,允許同一個子網路內的流量。如果網狀網路包含多個子網路,您必須明確設定防火牆規則,允許跨子網路的流量。您必須為每個子網路新增防火牆規則,允許所有傳入流量的來源 IP CIDR 區塊和目標連接埠。
以下說明如何在專案中的所有叢集之間,或僅在 $CLUSTER_1 和 $CLUSTER_2 之間,允許通訊。
- 收集叢集網路的相關資訊。 - 所有專案叢集- 如果叢集位於同一個專案中,您可以使用下列指令,允許專案中所有叢集之間的通訊。如果專案中含有您不想公開的叢集,請使用「Specific clusters」分頁中的指令。 - function join_by { local IFS="$1"; shift; echo "$*"; } ALL_CLUSTER_CIDRS=$(gcloud container clusters list --project $PROJECT_1 --format='value(clusterIpv4Cidr)' | sort | uniq) ALL_CLUSTER_CIDRS=$(join_by , $(echo "${ALL_CLUSTER_CIDRS}")) ALL_CLUSTER_NETTAGS=$(gcloud compute instances list --project $PROJECT_1 --format='value(tags.items.[0])' | sort | uniq) ALL_CLUSTER_NETTAGS=$(join_by , $(echo "${ALL_CLUSTER_NETTAGS}"))- 特定叢集- 下列指令可讓 - $CLUSTER_1和- $CLUSTER_2之間進行通訊,且不會在專案中公開其他叢集。- function join_by { local IFS="$1"; shift; echo "$*"; } ALL_CLUSTER_CIDRS=$(for P in $PROJECT_1 $PROJECT_2; do gcloud --project $P container clusters list --filter="name:($CLUSTER_1,$CLUSTER_2)" --format='value(clusterIpv4Cidr)'; done | sort | uniq) ALL_CLUSTER_CIDRS=$(join_by , $(echo "${ALL_CLUSTER_CIDRS}")) ALL_CLUSTER_NETTAGS=$(for P in $PROJECT_1 $PROJECT_2; do gcloud --project $P compute instances list --filter="name:($CLUSTER_1,$CLUSTER_2)" --format='value(tags.items.[0])' ; done | sort | uniq) ALL_CLUSTER_NETTAGS=$(join_by , $(echo "${ALL_CLUSTER_NETTAGS}"))
- 建立防火牆規則。 - GKE- gcloud compute firewall-rules create istio-multicluster-pods \ --allow=tcp,udp,icmp,esp,ah,sctp \ --direction=INGRESS \ --priority=900 \ --source-ranges="${ALL_CLUSTER_CIDRS}" \ --target-tags="${ALL_CLUSTER_NETTAGS}" --quiet \ --network=YOUR_NETWORK- Autopilot- TAGS="" for CLUSTER in ${CLUSTER_1} ${CLUSTER_2} do TAGS+=$(gcloud compute firewall-rules list --filter="Name:$CLUSTER*" --format="value(targetTags)" | uniq) && TAGS+="," done TAGS=${TAGS::-1} echo "Network tags for pod ranges are $TAGS" gcloud compute firewall-rules create asm-multicluster-pods \ --allow=tcp,udp,icmp,esp,ah,sctp \ --network=gke-cluster-vpc \ --direction=INGRESS \ --priority=900 --network=VPC_NAME \ --source-ranges="${ALL_CLUSTER_CIDRS}" \ --target-tags=$TAGS
設定端點探索作業
使用宣告式 API 啟用公開或私人叢集之間的端點探索功能
使用機群 API 啟用受管理的 Cloud Service Mesh 後,就會為這個叢集啟用端點探索功能。如果您使用其他工具佈建代管 Cloud Service Mesh,可以手動在機隊中的公用或私人叢集中啟用端點探索功能,方法是套用 asm-options 設定檔地圖中的設定 "multicluster_mode":"connected"。在同一個機群中,已啟用此設定的叢集會在彼此之間自動啟用跨叢集服務探索功能。
如果您採用代管 (TD) 控制平面實作項目,這是設定多叢集端點探索功能的唯一方法;如果您採用代管 (Istiod) 實作項目,則這是設定這項功能的建議方式。
請先建立防火牆規則,再繼續操作。
啟用
如果叢集中已存在 asm-options ConfigMap,請為叢集啟用端點探索功能:
      kubectl patch configmap/asm-options -n istio-system --type merge -p '{"data":{"multicluster_mode":"connected"}}'
如果叢集中尚未有 asm-options 設定檔地圖,請使用相關聯的資料建立設定檔地圖,並為叢集啟用端點探索功能:
      kubectl --context ${CTX_1} create configmap asm-options -n istio-system --from-file <(echo '{"data":{"multicluster_mode":"connected"}}')
停用
停用叢集的端點探索功能:
      kubectl patch configmap/asm-options -n istio-system --type merge -p '{"data":{"multicluster_mode":"manual"}}'
如果您未停用端點探索功能,就從機群中取消註冊叢集,秘密可能會留在叢集中。您必須手動清理任何剩餘的機密資料。
- 執行下列指令,找出需要清除的機密資料: - kubectl get secrets -n istio-system -l istio.io/owned-by=mesh.googleapis.com,istio/multiCluster=true
- 刪除每個密鑰: - kubectl delete secret SECRET_NAME- 針對其他秘密重複執行這個步驟。 
驗證多叢集連線
本節說明如何將範例 HelloWorld 和 Sleep 服務部署至多叢集環境,以驗證跨叢集負載平衡功能是否正常運作。
設定範例目錄的變數
- 前往下載 - asmcli的位置,然後執行下列指令來設定- ASM_VERSION- export ASM_VERSION="$(./asmcli --version)"
- 將工作資料夾設為您用於驗證跨叢集負載平衡功能是否運作的範例。這些樣本位於您在 - asmcli install指令中指定的- --output_dir目錄中。在下列指令中,將- OUTPUT_DIR變更為您在- --output_dir中指定的目錄。- export SAMPLES_DIR=OUTPUT_DIR/istio-${ASM_VERSION%+*}
啟用補充物注入功能
- 在每個叢集中建立範例命名空間。 - for CTX in ${CTX_1} ${CTX_2} do kubectl create --context=${CTX} namespace sample done
- 啟用要用於插入的命名空間。步驟取決於控制層實作。 - 代管 (TD)- 將預設的注入標籤套用至命名空間:
 - for CTX in ${CTX_1} ${CTX_2} do kubectl label --context=${CTX} namespace sample \ istio.io/rev- istio-injection=enabled --overwrite done- 受管理 (Istiod)- 建議做法:執行下列指令,將預設注入標籤套用至命名空間: - for CTX in ${CTX_1} ${CTX_2} do kubectl label --context=${CTX} namespace sample \ istio.io/rev- istio-injection=enabled --overwrite done- 如果您是現有的 Managed Istiod 控制平面使用者:建議您使用預設插入作業,但系統也支援以修訂版本為基礎的插入作業。請按照下列操作說明進行: - 執行下列指令,找出可用的發布版本: - kubectl -n istio-system get controlplanerevision- 輸出結果會與下列內容相似: - NAME AGE asm-managed-rapid 6d7h- 在輸出內容中, - NAME欄下方的值是修訂版本標籤,對應至 Cloud Service Mesh 版本的發布管道。
- 將修訂版本標籤套用至命名空間: - for CTX in ${CTX_1} ${CTX_2} do kubectl label --context=${CTX} namespace sample \ istio-injection- istio.io/rev=REVISION_LABEL --overwrite done
 
安裝 HelloWorld 服務
- 在兩個叢集中建立 HelloWorld 服務: - kubectl create --context=${CTX_1} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l service=helloworld -n sample- kubectl create --context=${CTX_2} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l service=helloworld -n sample
將 HelloWorld v1 和 v2 部署至每個叢集
- 將 - HelloWorld v1部署至- CLUSTER_1,並將- v2部署至- CLUSTER_2,以利日後驗證跨叢集負載平衡:- kubectl create --context=${CTX_1} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l version=v1 -n sample- kubectl create --context=${CTX_2} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l version=v2 -n sample
- 請使用下列指令確認 - HelloWorld v1和- v2是否正在執行。確認輸出結果是否類似下列內容:- kubectl get pod --context=${CTX_1} -n sample- NAME READY STATUS RESTARTS AGE helloworld-v1-86f77cd7bd-cpxhv 2/2 Running 0 40s - kubectl get pod --context=${CTX_2} -n sample- NAME READY STATUS RESTARTS AGE helloworld-v2-758dd55874-6x4t8 2/2 Running 0 40s 
部署睡眠資料服務
- 將 - Sleep服務部署至兩個叢集。這個 Pod 會產生人工網路流量,以供示範:- for CTX in ${CTX_1} ${CTX_2} do kubectl apply --context=${CTX} \ -f ${SAMPLES_DIR}/samples/sleep/sleep.yaml -n sample done
- 等待 - Sleep服務在各個叢集中啟動。確認輸出結果是否類似下列內容:- kubectl get pod --context=${CTX_1} -n sample -l app=sleep- NAME READY STATUS RESTARTS AGE sleep-754684654f-n6bzf 2/2 Running 0 5s - kubectl get pod --context=${CTX_2} -n sample -l app=sleep- NAME READY STATUS RESTARTS AGE sleep-754684654f-dzl9j 2/2 Running 0 5s 
驗證跨叢集負載平衡
請多次呼叫 HelloWorld 服務,並查看輸出內容,確認 v1 和 v2 的回覆交替:
- 呼叫 - HelloWorld服務:- kubectl exec --context="${CTX_1}" -n sample -c sleep \ "$(kubectl get pod --context="${CTX_1}" -n sample -l \ app=sleep -o jsonpath='{.items[0].metadata.name}')" \ -- /bin/sh -c 'for i in $(seq 1 20); do curl -sS helloworld.sample:5000/hello; done'- 輸出結果會與下列內容相似: - Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8 Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv ... 
- 再次呼叫 - HelloWorld服務:- kubectl exec --context="${CTX_2}" -n sample -c sleep \ "$(kubectl get pod --context="${CTX_2}" -n sample -l \ app=sleep -o jsonpath='{.items[0].metadata.name}')" \ -- /bin/sh -c 'for i in $(seq 1 20); do curl -sS helloworld.sample:5000/hello; done'- 輸出結果會與下列內容相似: - Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8 Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv ... 
恭喜!您已驗證負載平衡的多叢集 Cloud Service Mesh!
清理 HelloWorld 服務
完成負載平衡驗證後,請從叢集中移除 HelloWorld 和 Sleep 服務。
kubectl delete ns sample --context ${CTX_1}
kubectl delete ns sample --context ${CTX_2}