Google Cloud の外部でマルチクラスタ メッシュを設定する

このガイドでは、次のプラットフォーム向けにマルチクラスタ メッシュを設定する方法について説明します。

  • GKE on VMware
  • Bare Metal 向け Google Distributed Cloud Virtual

このガイドでは 2 つのクラスタを設定する方法について説明しますが、このプロセスを拡張して任意の数のクラスタをメッシュに組み込むこともできます。

始める前に

このガイドでは、asmcli install を使用して Anthos Service Mesh がインストールされていることを前提としています。asmcli と、asmcli install の実行時に --output_dir で指定したディレクトリに asmcli がダウンロードする構成パッケージが必要です。設定する必要がある場合は、依存ツールのインストールとクラスタの検証の手順に沿って、次の操作を行います。

メッシュで設定するすべてのクラスタの kubeconfig ファイルにアクセスする必要があります。

環境変数とプレースホルダを設定する

east-west ゲートウェイをインストールするには、次の環境変数が必要です。

  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
    

east-west ゲートウェイをインストールする

次のコマンドで、

  • CLUSTER_NAME_1CLUSTER_NAME_2 をクラスタの名前に置き換えます。

  • PATH_TO_KUBECONFIG_1PATH_TO_KUBECONFIG_2 をクラスタの kubeconfig ファイルに置き換えます。

メッシュ CA または CA サービス

  1. east-west トラフィック専用の cluster1 内のゲートウェイを $CLUSTER_2 にインストールします。デフォルトでは、このゲートウェイはインターネット上で公開されます。本番環境のシステムでは、外部からの攻撃を防ぐため、追加のアクセス制限(ファイアウォール ルールなど)が必要になる場合があります。

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID} \
        --cluster ${CLUSTER_1} \
        --network default \
        --revision asm-1146-16 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_1 install -y --set spec.values.global.pilotCertProvider=kubernetes -f -
    
  2. $CLUSTER_1 用の east-west トラフィック専用の $CLUSTER_2 内のゲートウェイをインストールします。

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

Istio CA

  1. east-west トラフィック専用の cluster1 内のゲートウェイを $CLUSTER_2 にインストールします。デフォルトでは、このゲートウェイはインターネット上で公開されます。本番環境のシステムでは、外部からの攻撃を防ぐため、追加のアクセス制限(ファイアウォール ルールなど)が必要になる場合があります。

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID} \
        --cluster ${CLUSTER_1} \
        --network default \
        --revision asm-1146-16 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_1 install -y -f -
    
  2. $CLUSTER_1 用の east-west トラフィック専用の $CLUSTER_2 内のゲートウェイをインストールします。

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID} \
        --cluster ${CLUSTER_2} \
        --network default \
        --revision asm-1146-16 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_2 install -y -f -
    

サービスの公開

クラスタは別々のネットワーク上にあるため、すべてのサービス(*.local)を両方のクラスタの east-west ゲートウェイ上で公開する必要があります。このゲートウェイはインターネットで一般公開されますが、その背後にあるサービスは、信頼できる mTLS 証明書とワークロード ID を持つサービスのみが、両者が同じネットワーク上にあるかのように、アクセスできます。

  1. CLUSTER_NAME_1 用の east-west ゲートウェイ経由でサービスを公開します。

    kubectl --kubeconfig=PATH_TO_KUBECONFIG_1 apply -n istio-system -f \
        asm/istio/expansion/expose-services.yaml
    
  2. CLUSTER_NAME_2 用の east-west ゲートウェイ経由でサービスを公開します。

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

エンドポイント ディスカバリを有効にする

asmcli create-mesh コマンドを実行して、エンドポイント ディスカバリを有効にします。この例では 2 つのクラスタのみが示されていますが、このコマンドを実行して、GKE Hub サービスの制限の対象となる追加のクラスタでエンドポイントの検出を有効にできます。

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

マルチクラスタ接続を確認する

このセクションでは、サンプルの HelloWorld サービスと Sleep サービスをマルチクラスタ環境にデプロイして、クラスタ間でのロード バランシングが機能することを確認する方法について説明します。

サイドカー インジェクションを有効にする

  1. リビジョン ラベルの値を特定します。この値は、後の手順で使用します。手順は Anthos Service Mesh のタイプ(マネージドまたはクラスタ内)によって異なります。

    マネージド

    次のコマンドを使用して、リビジョン ラベルを特定します。このラベルは、後の手順で使用します。

    kubectl get controlplanerevision -n istio-system

    出力は次のようになります。

     NAME                RECONCILED   STALLED   AGE
     asm-managed-rapid   True         False     89d
     

    出力の NAME 列にあるリビジョン ラベルの値をメモします。この例での値は asm-managed-rapid です。次のセクションの手順でリビジョンの値を使用します。

    クラスタ内

    次のコマンドを使用して、リビジョン ラベルを特定します。このラベルは、後の手順で使用します。

    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 列で、接頭辞 istio.io/rev= に続く istiod リビジョン ラベルの値をメモします。この例での値は 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 v1CLUSTER_1 にデプロイし、v2CLUSTER_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
    ...

ロード バランシングされたマルチクラスタの Anthos Service Mesh の検証はこれで完了です。

クリーンアップ

ロード バランシングの確認が完了したら、クラスタから HelloWorld サービスと Sleep サービスを削除します。

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