在 Google Cloud 外部設定多叢集網格

本指南說明如何為下列平台設定多叢集網格:

  • Google Distributed Cloud
  • Google Distributed Cloud
  • GKE on Azure
  • GKE on AWS
  • 已連接的叢集,包括 Amazon EKS 叢集和 Microsoft AKS 叢集

本指南說明如何設定兩個叢集,但您可以擴充這個程序,將任意數量的叢集納入網格。

事前準備

本指南假設您已使用 asmcli install 安裝 Cloud Service Mesh。您需要 asmcli,以及 asmcli 下載至您在執行 asmcli install 時在 --output_dir 中指定的目錄的設定套件。如果需要設定,請按照「安裝依附工具並驗證叢集」中的步驟:

您需要存取在網格中設定的所有叢集的 kubeconfig 檔案。

設定環境變數和預留位置

安裝東西向閘道時,您需要下列環境變數。

  1. 建立專案編號的環境變數。在下列指令中,將 FLEET_PROJECT_ID 替換為車隊主機專案的專案 ID。

    export PROJECT_NUMBER=$(gcloud projects describe FLEET_PROJECT_ID \
    --format="value(projectNumber)")
    
  2. 建立網格 ID 的環境變數。

    export MESH_ID="proj-${PROJECT_NUMBER}"
    
  3. asmcli 所需的格式建立叢集名稱的環境變數。

    export CLUSTER_1="cn-FLEET_PROJECT_ID-global-CLUSTER_NAME_1"
    export CLUSTER_2="cn-FLEET_PROJECT_ID-global-CLUSTER_NAME_2"
    
  4. 使用這項指令輸出內容中 NAME 欄下的值,取得叢集的內容名稱:

    kubectl config get-contexts
  5. 將環境變數設為叢集內容名稱,本指南稍後的許多步驟都會使用這些名稱:

    export CTX_1=CLUSTER1_CONTEXT_NAME
    export CTX_2=CLUSTER2_CONTEXT_NAME
    

安裝東西向閘道

在下列指令中:

  • CLUSTER_NAME_1CLUSTER_NAME_2 替換為叢集名稱。

  • PATH_TO_KUBECONFIG_1PATH_TO_KUBECONFIG_2 替換為叢集的 kubeconfig 檔案。

Anthos 叢集

Mesh CA 或 CA 服務

  1. 在叢集 1 中安裝專門用於東西向流量的閘道,以連線至 $CLUSTER_2。根據預設,這個閘道會在網際網路上公開。實際運作系統可能需要額外的存取限制 (例如防火牆規則),以防範外部攻擊。

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_1}  \
        --network default \
        --revision asm-1253-8 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_1 \
        install -y --set spec.values.global.pilotCertProvider=kubernetes -f -
    
  2. $CLUSTER_2 中安裝專門用於 $CLUSTER_1 的東西向流量閘道。

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_2}  \
        --network default \
        --revision asm-1253-8 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_2 \
        install -y --set spec.values.global.pilotCertProvider=kubernetes -f -
    

Istio CA

  1. 在叢集 1 中安裝專門用於東西向流量的閘道,以連線至 $CLUSTER_2。根據預設,這個閘道會在網際網路上公開。實際運作系統可能需要額外的存取限制 (例如防火牆規則),以防範外部攻擊。

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_1}  \
        --network default \
        --revision asm-1253-8 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_1 \
        install -y --set spec.values.global.pilotCertProvider=istiod -f -
    
  2. $CLUSTER_2 中安裝專門用於 $CLUSTER_1 的東西向流量閘道。

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_2}  \
        --network default \
        --revision asm-1253-8 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_2 \
        install -y --set spec.values.global.pilotCertProvider=istiod -f -
    

Azure、AWS 和已附加

Mesh CA

  1. 在叢集 1 中安裝專門用於東西向流量的閘道,以連線至 $CLUSTER_2。根據預設,這個閘道會在網際網路上公開。實際運作系統可能需要額外的存取限制 (例如防火牆規則),以防範外部攻擊。

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_1}  \
        --network default \
        --revision asm-1253-8 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_1 \
        install -y --set spec.values.global.pilotCertProvider=istiod -f -
    
  2. $CLUSTER_2 中安裝專門用於 $CLUSTER_1 的東西向流量閘道。

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_2}  \
        --network default \
        --revision asm-1253-8 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_2 \
        install -y --set spec.values.global.pilotCertProvider=istiod -f -
    

Istio CA

  1. 在叢集 1 中安裝專門用於東西向流量的閘道,以連線至 $CLUSTER_2。根據預設,這個閘道會在網際網路上公開。實際運作系統可能需要額外的存取限制 (例如防火牆規則),以防範外部攻擊。

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_1}  \
        --network default \
        --revision asm-1253-8 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_1 \
        install -y --set spec.values.global.pilotCertProvider=istiod -f -
    
  2. $CLUSTER_2 中安裝專門用於 $CLUSTER_1 的東西向流量閘道。

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_2}  \
        --network default \
        --revision asm-1253-8 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_2 \
        install -y --set spec.values.global.pilotCertProvider=istiod -f -
    

公開服務

由於叢集位於不同的網路中,您需要在兩個叢集的東西向閘道上公開所有服務 (*.local)。雖然這個閘道在網際網路上是公開的,但只有具備可信任的 mTLS 憑證和工作負載 ID 的服務,才能存取其後方的服務,就像這些服務位於同一個網路中一樣。

  1. 透過東西向閘道公開 CLUSTER_NAME_1 的服務。

    kubectl --kubeconfig=PATH_TO_KUBECONFIG_1 apply -n istio-system -f \
        asm/istio/expansion/expose-services.yaml
    
  2. 透過東西向閘道公開 CLUSTER_NAME_2 的服務。

    kubectl --kubeconfig=PATH_TO_KUBECONFIG_2 apply -n istio-system -f \
        asm/istio/expansion/expose-services.yaml
    

啟用端點探索功能

執行 asmcli create-mesh 指令,啟用端點探索功能。這個範例只會顯示兩個叢集,但您可以執行指令,在其他叢集中啟用端點探索功能,但須遵守 GKE Hub 服務限制

  ./asmcli create-mesh \
      FLEET_PROJECT_ID \
      PATH_TO_KUBECONFIG_1 \
      PATH_TO_KUBECONFIG_2

驗證多叢集連線

本節說明如何將範例 HelloWorldSleep 服務部署至多叢集環境,以驗證跨叢集負載平衡功能是否正常運作。

啟用補充物注入功能

找出修訂版本標籤值,您會在後續步驟中使用這個值。

使用下列指令找出修訂版本標籤,您將在後續步驟中使用此標籤。

kubectl -n istio-system get pods -l app=istiod --show-labels

輸出看起來類似以下內容:

NAME                                READY   STATUS    RESTARTS   AGE   LABELS
istiod-asm-173-3-5788d57586-bljj4   1/1     Running   0          23h   app=istiod,istio.io/rev=asm-173-3,istio=istiod,pod-template-hash=5788d57586
istiod-asm-173-3-5788d57586-vsklm   1/1     Running   1          23h   app=istiod,istio.io/rev=asm-173-3,istio=istiod,pod-template-hash=5788d57586

在輸出內容的 LABELS 欄下,請記下 istiod 修訂版本標籤的值,該值位於前置字串 istio.io/rev= 之後。在這個範例中,這個值為 asm-173-3。請在下一節的步驟中使用修訂值。

安裝 HelloWorld 服務

  1. 在每個叢集中建立範例命名空間和服務定義。在下列指令中,將 REVISION 替換為您在上一個步驟中記下的 istiod 修訂版本標籤。

    for CTX in ${CTX_1} ${CTX_2}
    do
        kubectl create --context=${CTX} namespace sample
        kubectl label --context=${CTX} namespace sample \
            istio-injection- istio.io/rev=REVISION --overwrite
    done
    

    其中 REVISION 是您先前記下的 istiod 修訂版本標籤。

    輸出結果如下:

    label "istio-injection" not found.
    namespace/sample labeled
    

    您可以放心忽略 label "istio-injection" not found.

  2. 在兩個叢集中建立 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 部署至每個叢集

  1. 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
  2. 請使用下列指令確認 HelloWorld v1v2 是否正在執行。確認輸出結果是否類似下列內容:

    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

部署睡眠資料服務

  1. Sleep 服務部署至兩個叢集。這個 Pod 會產生人工網路流量,以供示範:

    for CTX in ${CTX_1} ${CTX_2}
    do
        kubectl apply --context=${CTX} \
            -f ${SAMPLES_DIR}/samples/sleep/sleep.yaml -n sample
    done
    
  2. 等待 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 的回覆交替:

  1. 呼叫 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
    ...
  2. 再次呼叫 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!

清除所用資源

完成負載平衡驗證後,請從叢集中移除 HelloWorldSleep 服務。

kubectl delete ns sample --context ${CTX_1}
kubectl delete ns sample --context ${CTX_2}