Anthos Service Mesh に GKE クラスタを追加する

このガイドでは、Mesh CA または Citadel を使用して 2 つのクラスタを単一の Anthos Service Mesh に追加し、クラスタ間で負荷分散を行う方法について説明します。このプロセスを拡張することで、任意の数のクラスタをメッシュに組み込むことができます。

マルチクラスタの Anthos Service Mesh 構成を使用すると、大規模な組織で重要な課題(スケール、ロケーション、分離など)を解決できます。詳細については、マルチクラスタのユースケースをご覧ください。また、サービス メッシュを最大限活用するため、アプリケーションを最適化する必要があります。詳細については、Anthos Service Mesh 用のアプリケーションの準備をご覧ください。

前提条件

このガイドでは、次の要件を満たす Google Cloud GKE クラスタが 2 つ以上存在することを前提としています。

  • Anthos Service Mesh バージョン 1.6.8 以降がクラスタにインストールされていること。
    • クラスタが同じプロジェクトにある場合、インストールの概要を参照して、必要なバージョンでクラスタをインストールまたはアップグレードします。
    • クラスタが別のプロジェクトにある場合、複数プロジェクトのインストールと移行の説明に従って、クラスタをインストールまたは必要なバージョンにクラスタをアップグレードします。
  • 異なるプロジェクトのクラスタを追加する場合は、asm-gcp-multiproject プロファイルを使用してクラスタをインストールする必要があります。また、共有 VPC 構成でクラスタを同じネットワークに接続する必要があります。1 つのプロジェクトに共有 VPC をホストし、2 つのサービス プロジェクトでクラスタを作成することをおすすめします。詳細については、共有 VPC を使用したクラスタの設定をご覧ください。
  • Citadel CA を使用する場合は、両方のクラスタで同じカスタムルート CA を使用します。
  • Anthos Service Mesh が限定公開クラスタ上に構築されている場合は、同じ VPC に単一のサブネットを作成することをおすすめします。それ以外の場合は、次のことを確認します。
    1. コントロール プレーンが、クラスタのプライベート IP を使用してリモート プライベート クラスタ コントロール プレーンに到達できる。
    2. リモート コントロール クラスタの承認済みネットワークに、呼び出し元のコントロール プレーンの IP 範囲を追加できる。詳細については、限定公開クラスタ間のエンドポイント検出の構成をご覧ください。

プロジェクトとクラスタ変数を設定する

  1. 便宜上、作業フォルダを設定します。このフォルダは、前提条件の Anthos Service Mesh のインストールの準備で Anthos Service Mesh ファイルをダウンロードして解凍したフォルダです。

    export PROJECT_DIR=YOUR_WORKING_FOLDER
  2. 各クラスタにコンテキスト変数を作成します。コンテキストは、クラスタ プロジェクト ID、クラスタ名、ロケーションから構成される文字列です。ロケーションの値には、クラスタのロケーションを使用します(例: us-west2-a)。この例では、メッシュに 1 つのクラスタがすでに存在し、そのメッシュに別のクラスタを追加しています。

    export CTX_1=gke_CLUSTER_1_PROJECT_ID_CLUSTER_1_LOCATION_CLUSTER_1_NAME
    export CTX_2=gke_CLUSTER_2_PROJECT_ID_CLUSTER_2_LOCATION_CLUSTER_2_NAME

クラスタ間のエンドポイント検出の構成

次のコマンドを使用して、クラスタ間の負荷分散にエンドポイント検出を構成します。この手順では、以下のタスクを実行します。

  • istioctl コマンドを実行して、クラスタに Kube API サーバーへのアクセスを許可するシークレットを作成します。
  • kubectl コマンドを実行してシークレットを別のクラスタに適用し、2 番目のクラスタが最初のクラスタからサービス エンドポイントを読み取るようにします。
istioctl x create-remote-secret --context=${CTX_1} --name=${CLUSTER_1_NAME} | \
  kubectl apply -f - --context=${CTX_2}
istioctl x create-remote-secret --context=${CTX_2} --name=${CLUSTER_2_NAME} | \
  kubectl apply -f - --context=${CTX_1}

デプロイを確認する

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

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

  1. 次のコマンドを使用して、istiod サービスからリビジョン ラベルの値を探します。この値は、後のステップで使用します。

    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. 各クラスタにサンプルの名前空間を作成します。

    kubectl create --context=${CTX_1} namespace sample
    
    kubectl create --context=${CTX_2} namespace sample
    
  2. リビジョン ラベルを上書きします。

    kubectl label --context=${CTX_1} namespace sample \
          istio-injection- istio.io/rev=REVISION --overwrite
    
    kubectl label --context=${CTX_2} namespace sample \
      istio-injection- istio.io/rev=REVISION --overwrite
    

    ここで、REVISION は、以前にメモした istiod のリビジョン ラベルです。

    次のように出力されます。

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

    label "istio-injection" not found. は無視しても問題ありません

  3. 両方のクラスタに HelloWorld サービスを作成します。

    kubectl create --context=${CTX_1} \
        -f ${PROJECT_DIR}/samples/helloworld/helloworld.yaml \
        -l service=helloworld -n sample
    
    kubectl create --context=${CTX_2} \
        -f ${PROJECT_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 ${PROJECT_DIR}/samples/helloworld/helloworld.yaml \
      -l version=v1 -n sample
    kubectl create --context=${CTX_2} \
      -f ${PROJECT_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 ${PROJECT_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}')" \
        -- curl -sS helloworld.sample:5000/hello
    

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

    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}')" \
        -- curl -sS helloworld.sample:5000/hello
    

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

    Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8
    Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv
    ...

負荷分散されたマルチクラスタの Anthos Service Mesh の検証はこれで完了です。

HelloWorld サービスをクリーンアップする

負荷分散の確認が完了したら、クラスタから HelloWorld サービスと Sleep サービスを削除します。

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