將 Cloud Run 服務的流量,轉送至 GKE 上的 Cloud Service Mesh 工作負載

本頁說明如何安全地將網路流量從 Cloud Run 服務路由至 GKE 上的 Cloud Service Mesh 工作負載,以使用 Istio API 並充分運用全代管 Envoy Sidecar。

事前準備

以下各節假設您已啟用 Cloud Service Mesh 的 GKE 叢集

如果尚未部署 GKE 服務,請使用下列指令部署範例服務:

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 的名稱。
    • 如果您使用提供的服務範例,NAMESPACEdefault;否則請將 NAMESPACE 替換成您的命名空間名稱。
    • 如果您使用提供的範例服務,GKE_SERVICE_NAMEads;否則請將 GKE_SERVICE_NAME 替換為 GKE 服務的名稱。

雖然可以將 external-mesh 閘道新增為預先存在的 VirtualService 的目標,但您應建立不同的 VirtualService,將 Kubernetes 服務匯出至外部 Cloud Run 用戶端。使用獨立 VirtualService 可簡化匯出服務的管理作業和設定,且不會影響現有的 GKE 用戶端。此外,系統會忽略 VirtualServices 中網狀網路外部的某些欄位,但這些欄位仍會繼續為 GKE 服務提供預期功能。VirtualServices因此,分開管理及排解 VirtualServices 問題可能較為有利。

如要讓 GKE 用戶端也接收 VirtualService 設定,必須新增 meshmesh/default 閘道。

網格外部 VirtualService 必須與 VirtualService 目的地中的 Kubernetes 服務定義在相同命名空間。

設定 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 服務,並確保連線至叢集的虛擬私有雲網路:

    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 Sidecar 記錄

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

您可以使用 CSDS 擷取 trafficdirector 用戶端狀態:

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

後續步驟