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
ホストのカスタム ドメインを設定する
仮想サービスは、トラフィック ルーティング ルールを定義します。一致したトラフィックは、名前付き宛先サービスに送信されます。
新しいマネージド ゾーンを作成します。
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)。
リソース レコードセットを作成します。
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 を予約します。
外部 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_NAME は
VirtualService
の名前です。 - NAMESPACE は、提供されているサンプル サービスを使用する場合は
default
です。それ以外の場合は、NAMESPACE を Namespace 名に置き換えます。 - GKE_SERVICE_NAME は、提供されたサンプル サービスを使用する場合は
ads
です。それ以外の場合は、GKE_SERVICE_NAME を GKE サービスの名前に置き換えます。
- VIRTUAL_SERVICE_NAME は
既存の 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 サービスをサービス メッシュに参加させる手順は次のとおりです。
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"]')
メッシュ 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
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:
....