将流量从 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
主机配置自定义网域
虚拟服务用于定义流量路由规则。然后,所有匹配的流量都会发送到指定的目标服务
如需创建新的托管地区,请执行以下操作:
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 替换为您的命名空间名称。 - 如果您使用的是提供的示例服务,则 GKE_SERVICE_NAME 为
ads
;否则,请将 GKE_SERVICE_NAME 替换为您的 GKE 服务的名称。
- VIRTUAL_SERVICE_NAME 是
虽然可以将 external-mesh
网关添加为现有 VirtualService
的目标,但您应创建一个单独的 VirtualService
以将 Kubernetes 服务导出到外部 Cloud Run 客户端。使用单独的 VirtualService
有助于管理导出的服务及其配置,而不会影响现有的 GKE 客户端。此外,对于网状结构外部 VirtualServices
,VirtualServices
中的某些字段会被忽略,但对于 GKE 服务,这些字段会继续按预期运行。因此,单独管理和排查 VirtualServices
问题可能更有优势。
如需让 GKE 客户端也收到 VirtualService
配置,必须添加 mesh
或 mesh/default
网关。
网格外部 VirtualService
必须在 VirtualService
目标中的 Kubernetes 服务所在的命名空间中定义。
配置 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
您可以使用 CSDS 检索 trafficdirector 客户端状态:
gcloud alpha container fleet mesh debug proxy-status --membership=<CLUSTER_MEMBERSHIP> --location=<CLUSTER_LOCATION>
External Clients:
....