マルチクラスタ サービス メッシュを設定する

このガイドでは、新しい GKE クラスタを既存のサービス メッシュに追加する方法について説明します。

始める前に

クラスタを追加する前に、GKE Gateway API を使用したデプロイの準備の手順(マルチクラスタ サービスの有効化を含む)を完了してください。

新しい GKE クラスタを作成する

  1. 次のコマンドを使用して新しいクラスタを作成します。

    gcloud container clusters create gke-2 \
      --zone=us-west1-a \
      --enable-ip-alias \
      --workload-pool=PROJECT_ID.svc.id.goog \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --release-channel regular \
      --project=PROJECT_ID
    
  2. 次のコマンドを実行して、作成したクラスタに切り替えます。

    gcloud container clusters get-credentials gke-2 --zone us-west1-a
    
  3. クラスタ コンテキストの名前を変更します。

    kubectl config rename-context gke_PROJECT_ID_us-west1-a_gke-2 gke-2
    

クラスタをフリートに登録する

  1. クラスタを作成したら、クラスタをフリートに登録します。

    gcloud alpha container hub memberships register gke-2 \
      --gke-cluster us-west1-a/gke-2 \
      --enable-workload-identity \
      --project=PROJECT_ID
    
  2. クラスタがフリートに登録されたことを確認します。

    gcloud alpha container hub memberships list --project=PROJECT_ID
    

    フリートには、作成したクラスタと以前に作成したクラスタの両方が含まれます。

    NAME          EXTERNAL_ID
    gke-1  657e835d-3b6b-4bc5-9283-99d2da8c2e1b
    gke-2  f3727836-9cb0-4ffa-b0c8-d51001742f19
    

新しい GKE クラスタに Envoy サイドカー インジェクタをデプロイする

Envoy サイドカー インジェクタのデプロイの手順に沿って、インジェクタをクラスタ gke-2 にデプロイします。

サービス メッシュを新しい GKE クラスタに拡張する

Envoy サイドカー サービス メッシュをデプロイするには、store サービスが実行されるクラスタ gke-1 でサービス メッシュを構成する方法が記載されています。このセクションでは、サービス メッシュを拡張して、クラスタ gke-2 で実行される payments サービスを追加する方法について説明します。Mesh リソースは構成クラスタにすでに存在するため、新しいクラスタに Mesh リソースを作成する必要はありません。

payments サービスをデプロイする

  1. payments.yaml ファイルに次のマニフェストを保存します。

    kind: Namespace
    apiVersion: v1
    metadata:
      name: payments
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: payments
      namespace: payments
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: payments
          version: v1
      template:
        metadata:
          labels:
            app: payments
            version: v1
        spec:
          containers:
          - name: whereami
            image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1.2.20
            ports:
            - containerPort: 8080
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: payments
      namespace: payments
    spec:
      selector:
        app: payments
      ports:
      - port: 8080
        targetPort: 8080
    
  2. マニフェストをクラスタ gke-2 に適用します。

    kubectl apply --context gke-2 -f payments.yaml
    

payments サービスをエクスポートする

Gateway API リソースは構成クラスタ gke-1 に一元的に保存されます。フリート内の他のクラスタのサービスをエクスポートして、サービス メッシュのネットワーク動作を構成するときに、gke-1 クラスタ内の Gateway API リソースがこれらのサービスを参照できるようにする必要があります。

ServiceExportServiceImport の仕組みの詳細については、マルチクラスタ サービスをご覧ください。

  1. クラスタ gke-1 に名前空間 payments を作成します。クラスタ gke-1payments サービスは、同じ名前空間にあるフリート内のすべてのクラスタにエクスポートされます。

    kubectl create namespace payments --context gke-1
    
  2. export-payments.yaml ファイルに次のマニフェストを保存します。

    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: payments
      namespace: payments
    
  3. gke-2 クラスタに ServiceExport マニフェストを適用します。

    kubectl apply --context gke-2 -f export-payments.yaml
    
  4. 数分後、次のコマンドを実行して、付属の serviceImportsgke-1 のマルチクラスタ Service コントローラによって作成されたことを確認します。

    kubectl get serviceimports --context gke-1 --namespace payments
    

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

    NAME           TYPE           IP                  AGE
    payments       ClusterSetIP   ["10.112.31.15"]    6m54s
    

payments サービスの HTTPRoute リソースを構成する

  1. 次の HTTPRoute マニフェストを payments-route.yaml ファイルに保存します。

    apiVersion: gateway.networking.k8s.io/v1alpha2
    kind: HTTPRoute
    metadata:
      name: payments-route
      namespace: payments
    spec:
      parentRefs:
      - name: td-mesh
        namespace: default
        group: net.gke.io
        kind: TDMesh
      hostnames:
      - "example.com"
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /payments
        backendRefs:
        - group: net.gke.io
          kind: ServiceImport
          namespace: payments
          name: payments
          port: 8080
    
  2. ルート マニフェストを gke-1 に適用します。

    kubectl apply --context gke-1 -f payments-route.yaml
    

デプロイメントを検証する

Mesh のステータスとイベントを調べて、MeshHTTPRoute が正常にデプロイされていることを確認します。

  1. 次のコマンドを実行します。

    kubectl describe tdmesh td-mesh -–context gke-1
    

    出力例を以下に示します。

    ...
    Status:
      Conditions:
        Last Transition Time:  2022-04-14T22:49:56Z
        Message:
        Reason:                MeshReady
        Status:                True
        Type:                  Ready
        Last Transition Time:  2022-04-14T22:27:17Z
        Message:
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
    Events:
      Type    Reason  Age                From                Message
      ----    ------  ----               ----                -------
      Normal  ADD     23m                mc-mesh-controller  Processing mesh default/td-mesh
      Normal  UPDATE  23m                mc-mesh-controller  Processing mesh default/td-mesh
      Normal  SYNC    23m                mc-mesh-controller  Processing mesh default/td-mesh
      Normal  SYNC    71s                mc-mesh-controller  SYNC on default/td-mesh was a success
    
  2. デプロイを確認するには、いずれかのクラスタにクライアント Pod をデプロイします。client.yaml ファイルに次のものを保存します。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        run: client
      name: client
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          run: client
      template:
        metadata:
          labels:
            run: client
        spec:
          containers:
          - name: client
            image: curlimages/curl
            command:
            - sh
            - -c
            - while true; do sleep 1; done
    
  3. 次のようにマニフェストを適用します。

    kubectl apply -f client.yaml --context $CLUSTER
    

    クラスタで実行されているサイドカー インジェクタは、Envoy コンテナを自動的にクライアント Pod に挿入します。

  4. Envoy コンテナが挿入されていることを確認するには、次のコマンドを実行します。

    kubectl describe pods -l run=client --context $CLUSTER
    

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

    ...
    Init Containers:
      # Istio-init sets up traffic interception for the Pod.
      istio-init:
    ...
      # td-bootstrap-writer generates the Envoy bootstrap file for the Envoy container
      td-bootstrap-writer:
    ...
    Containers:
    # client is the client container that runs application code.
      client:
    ...
    # Envoy is the container that runs the injected Envoy proxy.
      envoy:
    ...
    
  5. mesh とクライアント Pod がプロビジョニングされたら、クライアント Pod から store サービスにリクエストを送信します。

    # Get the name of the client Pod.
    CLIENT_POD=$(kubectl get pod --context $CLUSTER -l run=client -o=jsonpath='{.items[0].metadata.name}')
    
    # The VIP where the following request will be sent. Because requests from the
    # Busybox container are redirected to the Envoy proxy, the IP address can
    # be any other address, such as 10.0.0.2 or 192.168.0.1.
    VIP='10.0.0.1'
    
    # Command to send a request to store.
    TEST_CMD="curl -v -H 'Host: example.com' $VIP/store"
    
    # Execute the test command in the client container.
    kubectl exec -it $CLIENT_POD -c client --context $CLUSTER -- /bin/sh -c "$TEST_CMD"
    

    出力には、gke-1 内の store Pod の 1 つがリクエストを処理していることが示されます。

    {
      "cluster_name": "gke-1",
      "zone": "us-central1-a",
      "host_header": "example.com",
    ...
    }
    
  6. payments サービスにリクエストを送信します。

    # Command to send a request to payments.
    TEST_CMD="curl -v -H 'host: example.com' $VIP/payments"
    
    # Execute the test command in the client container.
    kubectl exec -it $CLIENT_POD -c client -- /bin/sh -c "$TEST_CMD"
    

    出力には、gke-2 内の payments Pod の 1 つがリクエストを処理していることが示されます。

    {
      "cluster_name": "gke-2",
      "zone": "us-west1-a",
      "host_header": "example.com",
    ...
    }
    

次のステップ