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 クラスタと同じプロジェクトに存在する必要があります。この制限は、この機能が公開プレビュー版で提供されている間に適用されます。
始める前に
以降のセクションでは、次のものがあることを前提としています。
次のコマンドを実行してサンプルの Cloud Run サービスをデプロイすることもできます。
クラスタの kubeconfig コンテキストを生成します。
gcloud container clusters get-credentials CLUSTER_NAME --project=PROJECT_ID --location=CLUSTER_LOCATION
ここで
- CLUSTER_NAME: クラスタの名前。
- PROJECT_ID: プロジェクトのプロジェクト ID。
- CLUSTER_LOCATION: クラスタのリージョンまたはゾーン。
サンプルの 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 サービス アカウントの権限を借用できるようにするには、次の操作を行います。
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 を使用します。
- NAMESPACE: Namespace 名。このガイドでは、
サービス アカウントにアノテーションを付けます。
kubectl annotate serviceaccount KSA \ --namespace NAMESPACE \ iam.gke.io/gcp-service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com
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 は次の要素で構成されます。
- フロントエンド情報 - 具体的には、GKE ワークロードがこの GCPBackend を呼び出すために使用するホスト名とポート。
- バックエンド情報 - Cloud Run サービスの詳細(サービス名、ロケーション、プロジェクト番号など)。
GCPBackend には、ホスト名およびポートの詳細と、Cloud Service の詳細(サービス名、ロケーション、プロジェクト番号)が含まれます。GKE ワークロードは、HTTP リクエストで GCPBackend のホスト名とポートを使用して Cloud Run サービスにアクセスする必要があります。
ホスト名 DNS をクラスタ内で解決可能にするには(デフォルトでは解決できません)、選択したホスト名の下のすべてのホストを任意の IP アドレスに解決するように Google Cloud DNS を構成する必要があります。この DNS エントリを構成しないと、リクエストは失敗します。 Google Cloud DNS の構成は、カスタム ドメインごとに 1 回だけ設定します。
マネージド ゾーンを作成します。
gcloud dns managed-zones create prod \ --description="zone for gcpbackend" \ --dns-name=gcpbackend \ --visibility=private \ --networks=default
この例では、DNS 名は gcpbackend で、VPC ネットワークは default です。
ドメインを解決可能にするためのレコードを設定します。
gcloud beta dns record-sets create *.gcpbackend \ --ttl=3600 --type=A --zone=prod \ --rrdatas=10.0.0.1
前のドメインの下のホスト名を使用して 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_NAME は
cr-gcp-backend
です。テスト用の 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_NAME は cr-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:
....