将流量从 Cloud Run 服务路由到 GKE 上的 Cloud Service Mesh 工作负载

本页介绍了如何将网络流量从 Cloud Run 服务安全地路由到 GKE 上的 Cloud Service Mesh 工作负载,以使用 Istio API 并利用全代管式 Envoy 边车。

准备工作

以下部分假定您有一个已启用 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 客户端。此外,对于网状结构外部 VirtualServicesVirtualServices 中的某些字段会被忽略,但对于 GKE 服务,这些字段会继续按预期运行。因此,单独管理和排查 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 服务,同时确保还连接到集群的 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

您可以使用 CSDS 检索 trafficdirector 客户端状态:

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

后续步骤