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 は名前空間名です。このガイドでは、名前空間 default を使用します。
    • KSA は Kubernetes サービス アカウントの名前です。このガイドでは、KSA default を使用できます。
  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 Workloads がこの GCPBackend の呼び出しに使用するホスト名とポート。
  2. バックエンド情報 - サービス名、ロケーション、プロジェクト番号などの Cloud Run サービスの詳細。

GCPBackend には、ホスト名とポートの詳細情報のほか、Cloud サービスの詳細(サービス名、ロケーション、プロジェクト番号)が含まれます。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 Service にアクセスできるようになりました。

既存の Kubernetes サービスや Istio Service エントリと競合しないように、GCPBackend には一意の名前を使用する必要があります。競合する場合、優先順位は(高いものから低いものへ)Kubernetes Service、istio ServiceEntry、GCPBackend です。

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

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

すべての Cloud Run Service にはホスト名(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 仮想サービスまたは宛先ルールを構成する

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

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

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:
....

次のステップ