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

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

始める前に

以降のセクションでは、Cloud Service Mesh が有効になっている GKE クラスタがあることを前提としています。

GKE Service がデプロイされていない場合は、次のコマンドを使用してサンプル サービスをデプロイします。

cat <<EOF > /tmp/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: ads
spec:
  ports:
  - port: 9999
    targetPort: 8000
  selector:
    run: ads
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ads
spec:
  replicas: 1
  selector:
    matchLabels:
      run: ads
  template:
    metadata:
      labels:
        run: ads
    spec:
      containers:
      - image: docker.io/waip/simple-http:v1.0.1
        name: my-http2-svc
        ports:
        - protocol: TCP
          containerPort: 8000
      securityContext:
        fsGroup: 1337
EOF
kubectl apply -f /tmp/service.yaml

VirtualService ホストのカスタム ドメインを設定する

仮想サービスは、トラフィック ルーティング ルールを定義します。一致したトラフィックは、名前付き宛先サービスに送信されます。

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

    gcloud dns managed-zones create ZONE_NAME \
      --description="zone for service mesh routes" \
      --dns-name=DNS_SUFFIX. \
      --networks=default \
      --visibility=private
    

    ここで

    • ZONE_NAME はゾーンの名前です(例: prod)。
    • DNS_SUFFIX は有効な DNS ホストです(例: mesh.private)。
  2. リソース レコードセットを作成します。

    IP=10.0.0.1
    gcloud dns record-sets create '*.'"DNS_SUFFIX." --type=A --zone="ZONE_NAME" \
      --rrdatas=10.0.0.1 --ttl 3600
    

    IP(RFC 1918 必須)が未使用であることを確認します。または、静的内部 IP を予約します。

  3. 外部 Cloud Run クライアントの VirtualService をエクスポートします。

    cat <<EOF > virtual-service.yaml
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: VIRTUAL_SERVICE_NAME
      namespace: NAMESPACE
    spec:
      hosts:
      - GKE_SERVICE_NAME.DNS_SUFFIX
      gateways:
      - external-mesh
      http:
      - route:
        - destination:
            host: GKE_SERVICE_NAME
    EOF
    kubectl apply -f virtual-service.yaml
    

    ここで

    • VIRTUAL_SERVICE_NAMEVirtualService の名前です。
    • NAMESPACE は、提供されているサンプル サービスを使用する場合は default です。それ以外の場合は、NAMESPACE を Namespace 名に置き換えます。
    • GKE_SERVICE_NAME は、提供されたサンプル サービスを使用する場合は ads です。それ以外の場合は、GKE_SERVICE_NAME を GKE サービスの名前に置き換えます。

既存の VirtualService にターゲットとして external-mesh ゲートウェイを追加することは可能ですが、Kubernetes サービスを外部 Cloud Run クライアントにエクスポートするには、明確な VirtualService を確立する必要があります。別の VirtualService を使用すると、既存の GKE クライアントに影響を与えることなく、エクスポートされたサービスとその構成を管理できます。また、VirtualServices の一部フィールドはメッシュ外部 VirtualServices では無視されますが、GKE サービスでは想定どおりに機能します。そのため、VirtualServices の管理とトラブルシューティングを個別に行うことが有利な場合があります。

GKE クライアントが VirtualService 構成も受信するには、mesh または mesh/default ゲートウェイを追加する必要があります。

メッシュ外部 VirtualService は、VirtualService 宛先の Kubernetes Service と同じ Namespace で定義する必要があります。

サービス メッシュに参加するように Cloud Run サービスを構成する

Cloud Run サービスをサービス メッシュに参加させる手順は次のとおりです。

  1. Cloud Service Mesh GKE クラスタをバッキングするメッシュ ID を確認します。

    MESH=$(kubectl get controlplanerevision --namespace istio-system -o json | jq -r '.items[0].metadata.annotations["mesh.cloud.google.com/external-mesh"]')
    
  2. メッシュ ID を使用して Cloud Run サービスをデプロイし、クラスタの VPC ネットワークにも接続します。

    gcloud alpha run deploy --mesh "$MESH" --network default \
      mesh-svc --image=fortio/fortio \
      --region=REGION --project=PROJECT_ID --no-allow-unauthenticated
    
  3. Cloud Run サービスが GKE ワークロードにリクエストを送信できることを確認します。

    TEST_SERVICE_URL=$(gcloud run services describe mesh-svc --region REGION --format="value(status.url)" --project=PROJECT_ID)
    
    curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" "$TEST_SERVICE_URL/fortio/fetch/GKE_SERVICE_NAME.DNS_SUFFIX"
    

    出力は有効な HTTP 200 レスポンスになります。

トラブルシューティング

このセクションでは、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:
....

次のステップ