Cloud Service Mesh ワークロードから Cloud Run サービスにトラフィックを転送する

このページでは、GKE 上の Cloud Service Mesh ワークロードから Cloud Run サービスにネットワーク トラフィックを安全に転送する方法について説明します。

GKE から Cloud Run にトラフィックを転送する場合、Cloud Run サービスが Cloud Service Mesh に参加する必要はありません。ただし、Cloud Run サービスは Cloud Service Mesh の GKE クラスタと同じプロジェクトに存在する必要があります。この制限は、この機能が公開プレビュー版で提供されている間に適用されます。

始める前に

以降のセクションでは、次のものがあることを前提としています。

  1. Cloud Service Mesh が有効になっている GKE クラスタ
  2. デプロイ済みの Cloud Run サービス

次のコマンドを実行してサンプルの Cloud Run サービスをデプロイすることもできます。

  1. クラスタの kubeconfig コンテキストを生成します。

    gcloud container clusters get-credentials CLUSTER_NAME --project=PROJECT_ID  --location=CLUSTER_LOCATION
    

    ここで

    • CLUSTER_NAME: クラスタの名前。
    • PROJECT_ID: プロジェクトのプロジェクト ID。
    • CLUSTER_LOCATION: クラスタのリージョンまたはゾーン。
  2. サンプルの Cloud Run サービスをデプロイします。

    gcloud run deploy hello-world \
      --image=us-docker.pkg.dev/cloudrun/container/hello \
      --no-allow-unauthenticated \
      --port=8080 \
      --service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com \
      --region=us-central1 \
      --project=PROJECT_ID
    

    ここで

    • PROJECT_NUMBER: プロジェクトのプロジェクト番号。
    • PROJECT_ID: プロジェクトのプロジェクト ID。

IAM を構成する

Cloud Run サービスを呼び出すには、Cloud Run の Identity and Access Management(IAM)チェックに合格する必要があります。Google サービス アカウントに Cloud Run 起動元ロールを付与する必要があります。また、Google サービス アカウントの権限を借用するために、GKE Kubernetes サービス アカウント(KSA)を構成する必要があります。

Kubernetes サービス アカウントが Google サービス アカウントの権限を借用できるようにするには、次の操作を行います。

  1. IAM サービス アカウントに IAM ポリシー バインディングを追加します。

    gcloud iam service-accounts add-iam-policy-binding PROJECT_NUMBER-compute@developer.gserviceaccount.com \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA]"
    

    ここで

    • NAMESPACE: Namespace 名。このガイドでは、default Namespace を使用します。
    • KSA: Kubernetes サービス アカウントの名前。このガイドでは、default KSA を使用します。
  2. サービス アカウントにアノテーションを付けます。

    kubectl annotate serviceaccount KSA \
      --namespace NAMESPACE \
      iam.gke.io/gcp-service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com
    
  3. Google サービス アカウントに Cloud Run 起動元ロールを付与します。

    gcloud run services add-iam-policy-binding hello-world \
      --region=us-central1 \
      --member="serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
      --role="roles/run.invoker"
    

Cloud Run サービスを GCPBackend として構成する

このセクションでは、GCPBackend を使用して Cloud Run サービスを GKE ワークロードに公開します。GCPBackend は次の要素で構成されます。

  1. フロントエンド情報 - 具体的には、GKE ワークロードがこの GCPBackend を呼び出すために使用するホスト名とポート。
  2. バックエンド情報 - Cloud Run サービスの詳細(サービス名、ロケーション、プロジェクト番号など)。

GCPBackend には、ホスト名およびポートの詳細と、Cloud Service の詳細(サービス名、ロケーション、プロジェクト番号)が含まれます。GKE ワークロードは、HTTP リクエストで GCPBackend のホスト名とポートを使用して Cloud Run サービスにアクセスする必要があります。

ホスト名 DNS をクラスタ内で解決可能にするには(デフォルトでは解決できません)、選択したホスト名の下のすべてのホストを任意の IP アドレスに解決するように Google Cloud DNS を構成する必要があります。この DNS エントリを構成しないと、リクエストは失敗します。 Google Cloud DNS の構成は、カスタム ドメインごとに 1 回だけ設定します。

  1. マネージド ゾーンを作成します。

    gcloud dns managed-zones create prod \
        --description="zone for gcpbackend" \
        --dns-name=gcpbackend \
        --visibility=private \
        --networks=default
    

    この例では、DNS 名は gcpbackend で、VPC ネットワークは default です。

  2. ドメインを解決可能にするためのレコードを設定します。

    gcloud beta dns record-sets create *.gcpbackend \
      --ttl=3600 --type=A --zone=prod \
      --rrdatas=10.0.0.1
    
  3. 前のドメインの下のホスト名を使用して GCPBackend を作成します。

    cat <<EOF > gcp-backend.yaml
    apiVersion: networking.gke.io/v1
    kind: GCPBackend
    metadata:
      name: cr-gcp-backend
      namespace: NAMESPACE
    spec:
      hostname: hello-world.gcpbackend
      type: CloudRun
      cloudrun:
        service: hello-world
        regions: [us-central1]
    EOF
    kubectl apply -f gcp-backend.yaml
    

    この例では、GCP_BACKEND_NAMEcr-gcp-backend です。

  4. テスト用の Pod を作成して、GKE から Cloud Run への接続を確認します。

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: testcurl
      namespace: default
    spec:
      containers:
      - name: curl
        image: curlimages/curl
        command: ["sleep", "3000"]
    EOF
    
    kubectl exec testcurl -c curl -- curl http://hello-world.gcpbackend/hello
    

    これで、GKE ワークロードは hello-world.gcpbackend/hello に HTTP リクエストを送信して Cloud Run サービスにアクセスできるようになりました。

既存の Kubernetes Service や istio ServiceEntry と競合しないように、GCPBackend には一意の名前を使用する必要があります。競合する場合、優先順位は高いものから Kubernetes Service、istio ServiceEntry、GCPBackend の順です。

Virtual Service と GCPBackend は同じ Namespace に存在する必要があり、Cloud Run サービスは Cloud Service Mesh の GKE クラスタと同じプロジェクトに存在する必要があります。

(省略可)Cloud DNS ではなく Cloud Run のホスト名を使用する

すべての Cloud Run サービスにはホスト名(hello-world.us-central1.run.app など)が割り当てられ、DNS はグローバルに解決可能です。このホスト名を GCPBackend ホスト名で直接使用して、Cloud DNS 構成をスキップできます。

cat <<EOF | kubectl apply -f -
apiVersion: networking.gke.io/v1
kind: GCPBackend
metadata:
  name: cr-gcp-backend
  namespace: NAMESPACE
spec:
  hostname: hello-world.us-central1.run.app
  type: CloudRun
  cloudrun:
    service: hello-world
    region: [us-central1]
EOF

これで、GKE ワークロードが hello-world.us-central1.run.app に HTTP リクエストを送信して Cloud Run サービスにアクセスできるようになりました。

(省略可)Istio Virtual Service または Destination Rule を構成する

GCPBackend のホスト名に対する Istio Virtual Service または Istio Destination Rule を構成して、GCPBackend へのリクエスト用のコンシューマ ポリシーまたはクライアント ポリシーを設定できます。

次の例では、GCPBackend に送信されるリクエストの 50% に 5 秒の遅延を挿入し、リクエストの 10% を中止(HTTP ステータス 503)します。

cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: cr-virtual-service
  namespace: NAMESPACE
spec:
  hosts:
  - hello-world.us-central1.run.app
  gateways:
  - mesh
  http:
  - fault:
      delay:
        percentage:
          value: 50  # Delay 50% of requests
        fixedDelay: 5s
      abort:
        percentage:
          value: 10  # Abort 10% of requests
        httpStatus: 503
  - route:
    - destination:
        host: hello-world.us-central1.run.app
EOF

この例では、VIRTUAL_SERVICE_NAMEcr-virtual-service です。

トラブルシューティング

このセクションでは、Cloud Service Mesh と Cloud Run の一般的なエラーのトラブルシューティング方法について説明します。

Cloud Run サイドカーログ

Envoy エラーは Cloud Logging に記録されます。

たとえば、Cloud Run サービス アカウントにメッシュ プロジェクトの trafficdirector クライアント ロールが付与されていない場合、次のようなエラーがログに記録されます。

StreamAggregatedResources gRPC config stream to trafficdirector.googleapis.com:443 closed: 7, Permission 'trafficdirector.networks.getConfigs' denied on resource '//trafficdirector.googleapis.com/projects/525300120045/networks/mesh:test-mesh/nodes/003fb3e0c8927482de85f052444d5e1cd4b3956e82b00f255fbea1e114e1c0208dbd6a19cc41694d2a271d1ab04b63ce7439492672de4499a92bb979853935b03d0ad0' (or it may not exist).

CSDS

trafficdirector クライアントの状態は CSDS を使用して取得できます。

gcloud alpha container fleet mesh debug proxy-status --membership=<CLUSTER_MEMBERSHIP> --location=<CLUSTER_LOCATION>
External Clients:
....

次のステップ