区域 Cloud Service Mesh
借助区域隔离,连接到 Cloud Service Mesh 控制平面特定区域的客户端只能访问该区域内的资源。同样,特定区域内的 API 资源只能引用该区域内的其他资源。
区域 Cloud Service Mesh 存在以下限制:
- 不支持 Istio API。您无法使用 Kubernetes 和 Istio API 通过区域 Traffic Director。此预览版仅支持 Google Cloud API。
- 全球服务路由 API 的现有注意事项和限制适用。
- 支持 xdSTP 命名方案的最低 Envoy 版本为 v1.31.1。
- 不支持 Gateway for Mesh API。
- 最低 gRPC 版本为 v1.65。
仅支持以下区域:
africa-south1 asia-east1 asia-east2 asia-northeast1 asia-northeast2 asia-northeast3 asia-south1 asia-south2 asia-southeast1 asia-southeast2 australia-southeast1 australia-southeast2 europe-central2 europe-north1 europe-north2 europe-southwest1 europe-west10 europe-west12 europe-west1 europe-west2 europe-west3 europe-west4 europe-west6 europe-west8 europe-west9 me-central1 me-central2 me-west1 northamerica-northeast1 northamerica-northeast2 northamerica-south1 southamerica-east1 southamerica-west1 us-central1 us-east1 us-east4 us-east5 us-south1 us-west1 us-west2 us-west3 us-west4
价格
当此功能正式版发布后,支持区域性 Cloud Service Mesh 的每个区域都将具有区域性 SKU。目前,价格与全球价格相同。
为 Cloud Service Mesh 准备 xDS 客户端
Compute 虚拟机 Envoy xDS
手动
手动步骤以使用手动 Envoy 部署设置虚拟机为基础。
主要区别在于,ENVOY_CONTROL_PLANE_REGION 会被设置并注入到引导加载程序中。
创建实例模板:
gcloud compute instance-templates create td-vm-templategcloud compute instance-templates create td-vm-template \ --scopes=https://www.googleapis.com/auth/cloud-platform \ --tags=http-td-tag,http-server,https-server \ --image-family=debian-11 \ --image-project=debian-cloud \ --metadata=startup-script='#! /usr/bin/env bash # Set variables export ENVOY_CONTROL_PLANE_REGION="us-central1" export ENVOY_USER="envoy" export ENVOY_USER_UID="1337" export ENVOY_USER_GID="1337" export ENVOY_USER_HOME="/opt/envoy" export ENVOY_CONFIG="${ENVOY_USER_HOME}/config.yaml" export ENVOY_PORT="15001" export ENVOY_ADMIN_PORT="15000" export ENVOY_TRACING_ENABLED="false" export ENVOY_XDS_SERVER_CERT="/etc/ssl/certs/ca-certificates.crt" export ENVOY_ACCESS_LOG="/dev/stdout" export ENVOY_NODE_ID="$(cat /proc/sys/kernel/random/uuid)~$(hostname -i)" export BOOTSTRAP_TEMPLATE="${ENVOY_USER_HOME}/bootstrap_template.yaml" export GCE_METADATA_SERVER="169.254.169.254/32" export INTERCEPTED_CIDRS="*" export GCP_PROJECT_NUMBER=PROJECT_NUMBER export VPC_NETWORK_NAME=mesh:sidecar-mesh export GCE_ZONE=$(curl -sS -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/zone | cut -d"/" -f4) # Create system user account for Envoy binary sudo groupadd ${ENVOY_USER} \ --gid=${ENVOY_USER_GID} \ --system sudo adduser ${ENVOY_USER} \ --uid=${ENVOY_USER_UID} \ --gid=${ENVOY_USER_GID} \ --home=${ENVOY_USER_HOME} \ --disabled-login \ --system # Download and extract the Cloud Service Mesh tar.gz file cd ${ENVOY_USER_HOME} sudo curl -sL https://storage.googleapis.com/traffic-director/traffic-director-xdsv3.tar.gz -o traffic-director-xdsv3.tar.gz sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/bootstrap_template.yaml \ -C bootstrap_template.yaml \ --strip-components 1 sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/iptables.sh \ -C iptables.sh \ --strip-components 1 sudo rm traffic-director-xdsv3.tar.gz # Generate Envoy bootstrap configuration cat "${BOOTSTRAP_TEMPLATE}" \ | sed -e "s|ENVOY_NODE_ID|${ENVOY_NODE_ID}|g" \ | sed -e "s|ENVOY_ZONE|${GCE_ZONE}|g" \ | sed -e "s|VPC_NETWORK_NAME|${VPC_NETWORK_NAME}|g" \ | sed -e "s|CONFIG_PROJECT_NUMBER|${GCP_PROJECT_NUMBER}|g" \ | sed -e "s|ENVOY_PORT|${ENVOY_PORT}|g" \ | sed -e "s|ENVOY_ADMIN_PORT|${ENVOY_ADMIN_PORT}|g" \ | sed -e "s|XDS_SERVER_CERT|${ENVOY_XDS_SERVER_CERT}|g" \ | sed -e "s|TRACING_ENABLED|${ENVOY_TRACING_ENABLED}|g" \ | sed -e "s|ACCESSLOG_PATH|${ENVOY_ACCESS_LOG}|g" \ | sed -e "s|BACKEND_INBOUND_PORTS|${BACKEND_INBOUND_PORTS}|g" \ | sed -e "s|trafficdirector.googleapis.com|trafficdirector.${ENVOY_CONTROL_PLANE_REGION}.rep.googleapis.com|g" \ | sudo tee "${ENVOY_CONFIG}" # Install Envoy binary wget -O envoy_key https://apt.envoyproxy.io/signing.key cat envoy_key | sudo gpg --dearmor > $(pwd)/envoy-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=$(pwd)/envoy-keyring.gpg] https://apt.envoyproxy.io bullseye main" | sudo tee /etc/apt/sources.list.d/envoy.list sudo apt-get update sudo apt-get install envoy # Run Envoy as systemd service sudo systemd-run --uid=${ENVOY_USER_UID} --gid=${ENVOY_USER_GID} \ --working-directory=${ENVOY_USER_HOME} --unit=envoy.service \ bash -c "/usr/bin/envoy --config-path ${ENVOY_CONFIG} | tee" # Configure iptables for traffic interception and redirection sudo ${ENVOY_USER_HOME}/iptables.sh \ -p "${ENVOY_PORT}" \ -u "${ENVOY_USER_UID}" \ -g "${ENVOY_USER_GID}" \ -m "REDIRECT" \ -i "${INTERCEPTED_CIDRS}" \ -x "${GCE_METADATA_SERVER}"
Compute 虚拟机 gRPC xDS
与全局 Cloud Service Mesh 类似,gRPC 客户端需要配置一个引导加载程序,以告知它如何连接到区域 Cloud Service Mesh。
您可以使用 gRPC 引导生成器来生成此引导。如需将其设置为使用区域 Cloud Service Mesh,请指定一个新标志:--xds-server-region。
在此示例中,将 xds-server-region 设置为 us-central1 会自动确定区域性 Cloud Service Mesh 端点:trafficdirector.us-central1.rep.googleapis.com:443.
K8s 手动 Envoy 注入
以下手动步骤以使用手动 Envoy 注入功能设置 Google Kubernetes Engine Pod 为基础。 不过,您只需要修改有关手动注入 Pod 的部分。
将控制平面从全球级更改为区域级:
wget -q -O - https://storage.googleapis.com/traffic-director/demo/trafficdirector_client_new_api_sample_xdsv3.yaml sed -i "s/PROJECT_NUMBER/PROJECT_NUMBER/g" trafficdirector_client_new_api_sample_xdsv3.yaml sed -i "s/MESH_NAME/MESH_NAME/g" trafficdirector_client_new_api_sample_xdsv3.yaml sed -i "s|trafficdirector.googleapis.com|trafficdirector.${REGION}.rep.googleapis.com|g" trafficdirector_client_new_api_sample_xdsv3.yaml sed -i "s|gcr.io/google-containers/busybox|busybox:stable|g" trafficdirector_client_new_api_sample_xdsv3.yaml应用更改:
kubectl apply -f trafficdirector_client_new_api_sample_xdsv3.yaml ```
设置指南
本部分介绍了五种独立的配置和部署模型。这些都是现有全局服务路由 API 设置指南的区域化版本。
- 使用区域性 GRPCRoute 和区域性 Cloud Service Mesh 配置无代理 gRPC 服务
- 使用区域 HTTPRoute 和区域 Cloud Service Mesh 配置使用 HTTP 服务的 Envoy 边车代理配置
- 使用区域级 TCPRoute 配置 TCP 服务
- 网关 TLS 路由
- 为区域级 Cloud Service Mesh 和区域级路由配置跨项目引用
使用区域 GRPCRoute 和区域 Cloud Service Mesh 配置无代理 gRPC 服务
本部分介绍了如何使用区域级 Cloud Service Mesh 和区域级 GRPCRoute 资源配置无代理 gRPC 服务网格。
为方便起见,请存储您执行配置的 Google Cloud 项目编号,以便将本指南中的所有示例复制并粘贴到命令行中:
export PROJECT="PROJECT_NUMBER"
export REGION="us-central1"
export ZONE="us-central1-a"
将 PROJECT_NUMBER 替换为您的项目编号。
您可以选择性地替换以下内容:
- 将 us-central1 替换为您要使用的其他区域。
- 将 us-central1-a 替换为您要使用的其他可用区。
- default 替换为其他 VPC_NAME。
网格配置
当无代理 gRPC 应用连接到 xds://hostname 时,gRPC 客户端库会建立与 Cloud Service Mesh 的连接,以获取路由主机名请求所需的路由配置。
创建网格规范并将其存储在 mesh.yaml 文件中:
cat <<EOF > mesh.yaml name: grpc-mesh EOF使用 mesh.yaml 规范创建网格:
gcloud network-services meshes import grpc-mesh \ --source=mesh.yaml \ --location=${REGION}创建区域网格后,Cloud Service Mesh 即可提供配置。不过,由于尚未定义任何服务,因此配置为空。
gRPC 服务配置
出于演示目的,您将创建一个区域级后端服务,其中包含自动扩缩虚拟机(使用代管式实例组 [MIG]),该服务将使用 gRPC 协议在端口 50051 上提供 hello world。
使用端口 50051 上公开的
helloworldgRPC 服务创建 Compute Engine 虚拟机实例模板:gcloud compute instance-templates create grpc-td-vm-template \ --scopes=https://www.googleapis.com/auth/cloud-platform \ --tags=allow-health-checks \ --image-family=debian-11 \ --image-project=debian-cloud \ --metadata-from-file=startup-script=<(echo '#! /bin/bash set -e cd /root sudo apt-get update -y sudo apt-get install -y openjdk-11-jdk-headless curl -L https://github.com/grpc/grpc-java/archive/v1.38.0.tar.gz | tar -xz cd grpc-java-1.38.0/examples/example-hostname ../gradlew --no-daemon installDist # Server listens on 50051 sudo systemd-run ./build/install/hostname-server/bin/hostname-server')基于模板创建 MIG:
gcloud compute instance-groups managed create grpc-td-mig-us-central1 \ --zone=${ZONE} \ --size=2 \ --template=grpc-td-vm-template为 gRPC 服务配置已命名端口。这是 gRPC 服务配置为侦听请求的端口。
gcloud compute instance-groups set-named-ports grpc-td-mig-us-central1 \ --named-ports=grpc-helloworld-port:50051 \ --zone=${ZONE}在本示例中,端口为 50051。
创建 gRPC 健康检查。
gcloud compute health-checks create grpc grpc-helloworld-health-check \ --use-serving-port --region=${REGION}创建防火墙规则以允许传入的健康检查关联到您网络中的实例:
gcloud compute firewall-rules create grpc-vm-allow-health-checks \ --network default --action allow --direction INGRESS \ --source-ranges 35.191.0.0/16,209.85.152.0/22,209.85.204.0/22 \ --target-tags allow-health-checks \ --rules tcp:50051使用负载均衡方案
INTERNAL_SELF_MANAGED创建区域后端服务,并将之前创建的健康检查和代管式实例组添加到后端服务。端口名称中指定的端口用于连接到代管式实例组内的虚拟机。gcloud compute backend-services create grpc-helloworld-service \ --load-balancing-scheme=INTERNAL_SELF_MANAGED \ --protocol=GRPC \ --port-name=grpc-helloworld-port \ --health-checks="https://www.googleapis.com/compute/v1/projects/${PROJECT}/regions/${REGION}/healthChecks/grpc-helloworld-health-check" \ --region=${REGION}将代管式实例组添加到
BackendService:gcloud compute backend-services add-backend grpc-helloworld-service \ --instance-group=grpc-td-mig-us-central1 \ --instance-group-zone=${ZONE} \ --region=${REGION}
使用区域 GRPCRoute 设置路由
此时,区域级网格和 gRPC 服务器服务已配置完毕。现在,您可以设置所需的路由。
创建区域性 GRPCRoute 规范并将其存储在 grpc_route.yaml 文件中:
cat <<EOF > grpc_route.yaml name: helloworld-grpc-route hostnames: - helloworld-gce meshes: - projects/${PROJECT_NUMBER}/locations/${REGION}/meshes/grpc-mesh rules: - action: destinations: - serviceName: projects/${PROJECT_NUMBER}/locations/${REGION}/backendServices/grpc-helloworld-service EOF使用 grpc_route.yaml 规范创建区域性 GRPCRoute:
gcloud network-services grpc-routes import helloworld-grpc-route \ --source=grpc_route.yaml \ --location=${REGION}Cloud Service Mesh 现已配置为在托管式实例组中的后端之间对 gRPC 路由中指定的服务进行流量负载均衡。
创建 gRPC 客户端服务
如需验证配置,请实例化一个具有无代理 gRPC 数据平面的客户端应用。此应用必须在其引导文件中指定网格的名称。
配置完成后,此应用可以使用 xds:///helloworld-gce 服务 URI 向与 helloworld-gce 关联的实例或端点发送请求。
在以下示例中,您将使用 grpcurl 工具测试 gRPC 服务。
创建客户端虚拟机:
gcloud compute instances create grpc-client \ --zone=${ZONE}\ --scopes=https://www.googleapis.com/auth/cloud-platform \ --image-family=debian-11 \ --image-project=debian-cloud \ --metadata-from-file=startup-script=<(echo '#! /bin/bash set -ex export PROJECT=PROJECT_NUMBER export REGION=us-central1 export GRPC_XDS_BOOTSTRAP=/run/td-grpc-bootstrap.json echo export GRPC_XDS_BOOTSTRAP=$GRPC_XDS_BOOTSTRAP | sudo tee /etc/profile.d/grpc-xds-bootstrap.sh curl -L https://storage.googleapis.com/traffic-director/td-grpc-bootstrap-0.18.0.tar.gz | tar -xz ./td-grpc-bootstrap-0.18.0/td-grpc-bootstrap --config-mesh=grpc-mesh --xds-server-uri=trafficdirector.${REGION}.rep.googleapis.com:443 --gcp-project-number=${PROJECT} | sudo tee $GRPC_XDS_BOOTSTRAP sudo sed -i "s|\"authorities\": {|\"authorities\": {\n \"traffic-director.${REGION}.xds.googleapis.com\": {\"xds_servers\":[{\"server_uri\": \"trafficdirector.${REGION}.rep.googleapis.com:443\", \"channel_creds\": [ { \"type\": \"google_default\" } ], \"server_features\": [ \"xds_v3\", \"ignore_resource_deletion\" ]}], \"client_listener_resource_name_template\": \"xdstp://traffic-director.${REGION}.xds.googleapis.com/envoy.config.listener.v3.Listener/${PROJECT}/mesh:grpc-mesh/%s\"},|g" $GRPC_XDS_BOOTSTRAP sudo sed -i "s|\"client_default_listener_resource_name_template\": \"xdstp://traffic-director-global.xds.googleapis.com|\"client_default_listener_resource_name_template\": \"xdstp://traffic-director.${REGION}.xds.googleapis.com|g" $GRPC_XDS_BOOTSTRAP')
设置环境变量和引导文件
客户端应用需要引导配置文件。上一部分中的启动脚本会设置 GRPC_XDS_BOOTSTRAP 环境变量,并使用帮助程序脚本生成引导文件。所生成引导文件中 TRAFFICDIRECTOR_GCP_PROJECT_NUMBER 和 zone 的值将从知道 Compute Engine 虚拟机实例这些详细信息的元数据服务器获取。
您可以使用 -gcp-project-number 选项手动将这些值提供给帮助程序脚本。您必须使用 -config-mesh-experimental 选项提供与网格资源匹配的网格名称。
如需验证配置,请登录客户端:
gcloud compute ssh grpc-client --zone=${ZONE}下载并安装
grpcurl工具:curl -L https://github.com/fullstorydev/grpcurl/releases/download/v1.9.3/grpcurl_1.9.3_linux_x86_64.tar.gz | tar -xz运行
grpcurl工具,将xds:///helloworld-gce作为服务 URI,将helloworld.Greeter/SayHello作为服务名称和要调用的方法。./grpcurl --plaintext \ -d '{"name": "world"}' \ xds:///helloworld-gce helloworld.Greeter/SayHello使用 -d 选项传递 SayHello 方法的参数。
您应该会看到如下所示的输出,其中
INSTANCE_NAME是虚拟机实例的名称:Greeting: Hello world, from INSTANCE_HOSTNAME
这将验证无代理 gRPC 客户端是否已成功连接到 Cloud Service Mesh,并使用 xDS 名称解析器获取 helloworld-gce 服务的后端。客户端向服务的其中一个后端发送请求,无需了解 IP 地址或执行 DNS 解析。
使用 HTTP 服务配置 Envoy 边车代理配置,并使用区域级 HTTPRoute 和区域级 Mesh
本部分介绍了如何使用区域级网格和区域级 HTTPRoute 资源配置基于 Envoy 代理的服务网格。
为方便起见,请存储您执行配置的 Google Cloud 项目编号,以便将本指南中的所有示例复制并粘贴到命令行中:
export PROJECT_ID="PROJECT_ID"
export PROJECT="PROJECT_NUMBER"
export REGION="us-central1"
export ZONE="us-central1-a"
替换以下内容
- PROJECT_ID 替换为您的项目 ID。
- 将 PROJECT_NUMBER 替换为您的项目编号。
您可以选择性地替换以下内容:
- 将 us-central1 替换为您要使用的其他区域。
- 将 us-central1-a 替换为您要使用的其他可用区。
网格配置
边车 Envoy 代理从 Cloud Service Mesh 接收服务路由配置。边车会显示区域网格资源的名称,以标识已配置的特定服务网格。从 Cloud Service Mesh 收到的路由配置用于根据在 Route 资源中配置的请求参数(例如主机名或标头),将通过边车代理的流量定向到各种区域性后端服务。
请注意,网格名称是边车代理用于请求与此网格关联的配置的键。
创建区域级网格规范并将其存储在 mesh.yaml 文件中:
cat <<EOF > mesh.yaml name: sidecar-mesh EOF如果未指定,则拦截端口默认为 15001。
使用 mesh.yaml 规范创建区域网格:
gcloud network-services meshes import sidecar-mesh \ --source=mesh.yaml \ --location=${REGION}创建区域网格后,Cloud Service Mesh 即可提供配置。不过,由于尚未定义任何服务,因此配置将为空。
HTTP 服务器配置
出于演示目的,您将创建一个区域后端服务,其中包含自动扩缩的虚拟机(使用代管式实例组 - MIG),这些虚拟机将在端口 80 上使用 gRPC 协议提供“hello world”。
使用端口 80 上公开的
helloworldHTTP 服务创建 Compute Engine 虚拟机实例模板:gcloud compute instance-templates create td-httpd-vm-template \ --scopes=https://www.googleapis.com/auth/cloud-platform \ --tags=http-td-server \ --image-family=debian-11 \ --image-project=debian-cloud \ --metadata=startup-script="#! /bin/bash sudo apt-get update -y sudo apt-get install apache2 -y sudo service apache2 restart echo '<!doctype html><html><body><h1>'\`/bin/hostname\`'</h1></body></html>' | sudo tee /var/www/html/index.html"基于模板创建 MIG:
gcloud compute instance-groups managed create http-td-mig-us-central1 \ --zone=${ZONE} \ --size=2 \ --template=td-httpd-vm-template创建健康检查:
gcloud compute health-checks create http http-helloworld-health-check --region=${REGION}创建防火墙规则以允许传入的健康检查关联到您网络中的实例:
gcloud compute firewall-rules create http-vm-allow-health-checks \ --network default --action allow --direction INGRESS \ --source-ranges 35.191.0.0/16,209.85.152.0/22,209.85.204.0/22 \ --target-tags http-td-server \ --rules tcp:80使用负载均衡方案
INTERNAL_SELF_MANAGED创建区域性后端服务:gcloud compute backend-services create http-helloworld-service \ --load-balancing-scheme=INTERNAL_SELF_MANAGED \ --protocol=HTTP \ --health-checks="https://www.googleapis.com/compute/v1/projects/${PROJECT}/regions/${REGION}/healthChecks/http-helloworld-health-check" \ --region=${REGION}将健康检查以及托管或非托管实例组添加到后端服务:
gcloud compute backend-services add-backend http-helloworld-service \ --instance-group=http-td-mig-us-central1 \ --instance-group-zone=${ZONE} \ --region=${REGION}此示例使用代管式实例组和 Compute Engine 虚拟机模板,该模板运行我们之前创建的示例 HTTP 服务。
使用区域级 HTTPRoute 设置路由
已配置网格资源和 HTTP 服务器。现在,您可以使用 HTTPRoute 资源将它们连接起来,而此资源将主机名与后端服务相关联。
创建 HTTPRoute 规范并将其存储为 http_route.yaml:
cat <<EOF > http_route.yaml name: helloworld-http-route hostnames: - helloworld-gce meshes: - projects/${PROJECT_NUMBER}/locations/${REGION}/meshes/sidecar-mesh rules: - action: destinations: - serviceName: projects/${PROJECT_NUMBER}/locations/${REGION}/backendServices/http-helloworld-service EOF使用 http_route.yaml 规范创建 HTTPRoute:
gcloud network-services http-routes import helloworld-http-route \ --source=http_route.yaml \ --location=${REGION}Cloud Service Mesh 现已配置为在代管式实例组中的后端之间对 HTTPRoute 中指定的服务进行流量负载均衡。
使用 Envoy 边车创建 HTTP 客户端
在本部分中,您将实例化一个带有 Envoy 边车代理的客户端虚拟机,以请求之前创建的 Cloud Service Mesh 配置。请注意,Google Cloud CLI 命令中的 mesh 参数引用了之前创建的网格资源。
gcloud compute instance-templates create td-vm-template \
--scopes=https://www.googleapis.com/auth/cloud-platform \
--tags=http-td-tag,http-server,https-server \
--image-family=debian-11 \
--image-project=debian-cloud \
--metadata=startup-script='#! /usr/bin/env bash
# Set variables
export ENVOY_CONTROL_PLANE_REGION="us-central1"
export ENVOY_USER="envoy"
export ENVOY_USER_UID="1337"
export ENVOY_USER_GID="1337"
export ENVOY_USER_HOME="/opt/envoy"
export ENVOY_CONFIG="${ENVOY_USER_HOME}/config.yaml"
export ENVOY_PORT="15001"
export ENVOY_ADMIN_PORT="15000"
export ENVOY_TRACING_ENABLED="false"
export ENVOY_XDS_SERVER_CERT="/etc/ssl/certs/ca-certificates.crt"
export ENVOY_ACCESS_LOG="/dev/stdout"
export ENVOY_NODE_ID="$(cat /proc/sys/kernel/random/uuid)~$(hostname -i)"
export BOOTSTRAP_TEMPLATE="${ENVOY_USER_HOME}/bootstrap_template.yaml"
export GCE_METADATA_SERVER="169.254.169.254/32"
export INTERCEPTED_CIDRS="*"
export GCP_PROJECT_NUMBER=PROJECT_NUMBER
export VPC_NETWORK_NAME=mesh:sidecar-mesh
export GCE_ZONE=$(curl -sS -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/zone | cut -d"/" -f4)
# Create system user account for Envoy binary
sudo groupadd ${ENVOY_USER} \
--gid=${ENVOY_USER_GID} \
--system
sudo adduser ${ENVOY_USER} \
--uid=${ENVOY_USER_UID} \
--gid=${ENVOY_USER_GID} \
--home=${ENVOY_USER_HOME} \
--disabled-login \
--system
# Download and extract the Cloud Service Mesh tar.gz file
cd ${ENVOY_USER_HOME}
sudo curl -sL https://storage.googleapis.com/traffic-director/traffic-director-xdsv3.tar.gz -o traffic-director-xdsv3.tar.gz
sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/bootstrap_template.yaml \
-C bootstrap_template.yaml \
--strip-components 1
sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/iptables.sh \
-C iptables.sh \
--strip-components 1
sudo rm traffic-director-xdsv3.tar.gz
# Generate Envoy bootstrap configuration
cat "${BOOTSTRAP_TEMPLATE}" \
| sed -e "s|ENVOY_NODE_ID|${ENVOY_NODE_ID}|g" \
| sed -e "s|ENVOY_ZONE|${GCE_ZONE}|g" \
| sed -e "s|VPC_NETWORK_NAME|${VPC_NETWORK_NAME}|g" \
| sed -e "s|CONFIG_PROJECT_NUMBER|${GCP_PROJECT_NUMBER}|g" \
| sed -e "s|ENVOY_PORT|${ENVOY_PORT}|g" \
| sed -e "s|ENVOY_ADMIN_PORT|${ENVOY_ADMIN_PORT}|g" \
| sed -e "s|XDS_SERVER_CERT|${ENVOY_XDS_SERVER_CERT}|g" \
| sed -e "s|TRACING_ENABLED|${ENVOY_TRACING_ENABLED}|g" \
| sed -e "s|ACCESSLOG_PATH|${ENVOY_ACCESS_LOG}|g" \
| sed -e "s|BACKEND_INBOUND_PORTS|${BACKEND_INBOUND_PORTS}|g" \
| sed -e "s|trafficdirector.googleapis.com|trafficdirector.${ENVOY_CONTROL_PLANE_REGION}.rep.googleapis.com|g" \
| sudo tee "${ENVOY_CONFIG}"
# Install Envoy binary
wget -O envoy_key https://apt.envoyproxy.io/signing.key
cat envoy_key | sudo gpg --dearmor > $(pwd)/envoy-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=$(pwd)/envoy-keyring.gpg] https://apt.envoyproxy.io bullseye main" | sudo tee /etc/apt/sources.list.d/envoy.list
sudo apt-get update
sudo apt-get install envoy
# Run Envoy as systemd service
sudo systemd-run --uid=${ENVOY_USER_UID} --gid=${ENVOY_USER_GID} \
--working-directory=${ENVOY_USER_HOME} --unit=envoy.service \
bash -c "/usr/bin/envoy --config-path ${ENVOY_CONFIG} | tee"
# Configure iptables for traffic interception and redirection
sudo ${ENVOY_USER_HOME}/iptables.sh \
-p "${ENVOY_PORT}" \
-u "${ENVOY_USER_UID}" \
-g "${ENVOY_USER_GID}" \
-m "REDIRECT" \
-i "${INTERCEPTED_CIDRS}" \
-x "${GCE_METADATA_SERVER}"
'
gcloud compute instances create td-vm-client \
--zone=${ZONE} \
--source-instance-template td-vm-template
登录已创建的虚拟机:
gcloud compute ssh td-vm-client --zone=${ZONE}验证与所创建的测试服务的 HTTP 连接:
curl -H "Host: helloworld-gce" http://10.0.0.1/该命令会返回托管式实例组中某个虚拟机的响应,并将主机名输出到控制台。
使用区域性 TCPRoute 配置 TCP 服务
此配置流程与使用 HTTP 服务设置 Envoy 代理非常相似,但后端服务提供 TCP 服务,并且路由基于 TCP/IP 参数而不是 HTTP 协议。
为方便起见,请存储您执行配置的 Google Cloud 项目编号,以便将本指南中的所有示例复制并粘贴到命令行中:
export PROJECT_ID="PROJECT_ID"
export PROJECT="PROJECT_NUMBER"
export REGION="us-central1"
export ZONE="us-central1-a"
替换以下内容
- PROJECT_ID 替换为您的项目 ID。
- 将 PROJECT_NUMBER 替换为您的项目编号。
您可以选择性地替换以下内容:
- 将 us-central1 替换为您要使用的其他区域。
- 将 us-central1-a 替换为您要使用的其他可用区。
网格配置
创建区域级网格规范并将其存储在 mesh.yaml 文件中:
cat <<EOF > mesh.yaml name: sidecar-mesh EOF使用 mesh.yaml 规范创建区域网格:
gcloud network-services meshes import sidecar-mesh \ --source=mesh.yaml \ --location=${REGION}
TCP 服务器配置
出于演示目的,您将创建一个区域后端服务,其中包含自动扩缩的虚拟机(使用代管式实例组 - MIG),这些虚拟机将使用端口 10000 上的 gRPC 协议提供“hello world”。
使用 netcat 实用程序创建 Compute Engine 虚拟机实例模板,该模板在端口 10000 上运行测试服务:
gcloud compute instance-templates create tcp-td-vm-template \ --scopes=https://www.googleapis.com/auth/cloud-platform \ --tags=allow-health-checks \ --image-family=debian-11 \ --image-project=debian-cloud \ --metadata=startup-script="#! /bin/bash sudo apt-get update -y sudo apt-get install netcat -y while true; do echo 'Hello from TCP service' | nc -l -s 0.0.0.0 -p 10000; done &"基于模板创建 MIG:
gcloud compute instance-groups managed create tcp-td-mig-us-central1 \ --zone=${ZONE} \ --size=1 \ --template=tcp-td-vm-template将创建的代管式实例组上的已命名端口设置为
port 10000:gcloud compute instance-groups set-named-ports tcp-td-mig-us-central1 \ --zone=${ZONE} --named-ports=tcp:10000创建区域级健康检查:
gcloud compute health-checks create tcp tcp-helloworld-health-check --port 10000 --region=${REGION}创建防火墙规则以允许传入的健康检查关联到您网络中的实例:
gcloud compute firewall-rules create tcp-vm-allow-health-checks \ --network default --action allow --direction INGRESS \ --source-ranges 35.191.0.0/16,209.85.152.0/22,209.85.204.0/22 \ --target-tags allow-health-checks \ --rules tcp:10000创建负载均衡方案为 INTERNAL_SELF_MANAGED 的区域后端服务,并将健康检查以及托管或非托管实例组添加到后端服务。
gcloud compute backend-services create tcp-helloworld-service \ --region=${REGION} \ --load-balancing-scheme=INTERNAL_SELF_MANAGED \ --protocol=TCP \ --port-name=tcp \ --health-checks="https://www.googleapis.com/compute/v1/projects/${PROJECT}/regions/${REGION}/healthChecks/tcp-helloworld-health-check"将 MIG 添加到 BackendService:
gcloud compute backend-services add-backend tcp-helloworld-service \ --instance-group tcp-td-mig-us-central1 \ --instance-group-zone=${ZONE} \ --region=${REGION}
使用区域 TCPRoute 设置路由
创建 TCPRoute 规范并将其存储在 tcp_route.yaml 文件中:
cat <<EOF > tcp_route.yaml name: helloworld-tcp-route meshes: - projects/$PROJECT_NUMBER/locations/$REGION/meshes/sidecar-mesh rules: - action: destinations: - serviceName: projects/$PROJECT_NUMBER/locations/$REGION/backendServices/tcp-helloworld-service matches: - address: '10.0.0.1/32' port: '10000' EOF使用 tcp_route.yaml 规范创建 TCPRoute:
gcloud network-services tcp-routes import helloworld-tcp-route \ --source=tcp_route.yaml \ --location=${REGION}
使用 Envoy 边车创建 TCP 客户端
创建连接到 Cloud Service Mesh 的 Envoy 虚拟机:
gcloud compute instance-templates create td-vm-template \ --scopes=https://www.googleapis.com/auth/cloud-platform \ --tags=http-td-tag,http-server,https-server \ --image-family=debian-11 \ --image-project=debian-cloud \ --metadata=startup-script='#! /usr/bin/env bash # Set variables export ENVOY_CONTROL_PLANE_REGION="us-central1" export ENVOY_USER="envoy" export ENVOY_USER_UID="1337" export ENVOY_USER_GID="1337" export ENVOY_USER_HOME="/opt/envoy" export ENVOY_CONFIG="${ENVOY_USER_HOME}/config.yaml" export ENVOY_PORT="15001" export ENVOY_ADMIN_PORT="15000" export ENVOY_TRACING_ENABLED="false" export ENVOY_XDS_SERVER_CERT="/etc/ssl/certs/ca-certificates.crt" export ENVOY_ACCESS_LOG="/dev/stdout" export ENVOY_NODE_ID="$(cat /proc/sys/kernel/random/uuid)~$(hostname -i)" export BOOTSTRAP_TEMPLATE="${ENVOY_USER_HOME}/bootstrap_template.yaml" export GCE_METADATA_SERVER="169.254.169.254/32" export INTERCEPTED_CIDRS="*" export GCP_PROJECT_NUMBER=PROJECT_NUMBER export VPC_NETWORK_NAME=mesh:sidecar-mesh export GCE_ZONE=$(curl -sS -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/zone | cut -d"/" -f4) # Create system user account for Envoy binary sudo groupadd ${ENVOY_USER} \ --gid=${ENVOY_USER_GID} \ --system sudo adduser ${ENVOY_USER} \ --uid=${ENVOY_USER_UID} \ --gid=${ENVOY_USER_GID} \ --home=${ENVOY_USER_HOME} \ --disabled-login \ --system # Download and extract the Cloud Service Mesh tar.gz file cd ${ENVOY_USER_HOME} sudo curl -sL https://storage.googleapis.com/traffic-director/traffic-director-xdsv3.tar.gz -o traffic-director-xdsv3.tar.gz sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/bootstrap_template.yaml \ -C bootstrap_template.yaml \ --strip-components 1 sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/iptables.sh \ -C iptables.sh \ --strip-components 1 sudo rm traffic-director-xdsv3.tar.gz # Generate Envoy bootstrap configuration cat "${BOOTSTRAP_TEMPLATE}" \ | sed -e "s|ENVOY_NODE_ID|${ENVOY_NODE_ID}|g" \ | sed -e "s|ENVOY_ZONE|${GCE_ZONE}|g" \ | sed -e "s|VPC_NETWORK_NAME|${VPC_NETWORK_NAME}|g" \ | sed -e "s|CONFIG_PROJECT_NUMBER|${GCP_PROJECT_NUMBER}|g" \ | sed -e "s|ENVOY_PORT|${ENVOY_PORT}|g" \ | sed -e "s|ENVOY_ADMIN_PORT|${ENVOY_ADMIN_PORT}|g" \ | sed -e "s|XDS_SERVER_CERT|${ENVOY_XDS_SERVER_CERT}|g" \ | sed -e "s|TRACING_ENABLED|${ENVOY_TRACING_ENABLED}|g" \ | sed -e "s|ACCESSLOG_PATH|${ENVOY_ACCESS_LOG}|g" \ | sed -e "s|BACKEND_INBOUND_PORTS|${BACKEND_INBOUND_PORTS}|g" \ | sed -e "s|trafficdirector.googleapis.com|trafficdirector.${ENVOY_CONTROL_PLANE_REGION}.rep.googleapis.com|g" \ | sudo tee "${ENVOY_CONFIG}" # Install Envoy binary wget -O envoy_key https://apt.envoyproxy.io/signing.key cat envoy_key | sudo gpg --dearmor > $(pwd)/envoy-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=$(pwd)/envoy-keyring.gpg] https://apt.envoyproxy.io bullseye main" | sudo tee /etc/apt/sources.list.d/envoy.list sudo apt-get update sudo apt-get install envoy # Run Envoy as systemd service sudo systemd-run --uid=${ENVOY_USER_UID} --gid=${ENVOY_USER_GID} \ --working-directory=${ENVOY_USER_HOME} --unit=envoy.service \ bash -c "/usr/bin/envoy --config-path ${ENVOY_CONFIG} | tee" # Configure iptables for traffic interception and redirection sudo ${ENVOY_USER_HOME}/iptables.sh \ -p "${ENVOY_PORT}" \ -u "${ENVOY_USER_UID}" \ -g "${ENVOY_USER_GID}" \ -m "REDIRECT" \ -i "${INTERCEPTED_CIDRS}" \ -x "${GCE_METADATA_SERVER}" ' gcloud compute instances create td-vm-client \ --zone=${ZONE} \ --source-instance-template td-vm-template登录已创建的虚拟机:
gcloud compute ssh td-vm-client --zone=${ZONE}验证与所创建的测试服务的连接:
curl 10.0.0.1:10000 --http0.9 -v您应该会看到返回的文本
Hello from TCP service,并且能够看到在远程虚拟机上运行的 netcat 服务返回的任何文本。
宿主项目中的区域网格配置
将项目指定为宿主项目。任何有权在此项目中创建/更新/删除网格的服务账号都可以控制附加到此项目中区域性网格的路由配置。
定义一个将在整个示例中使用的变量:
export REGION="us-central1"您可以选择将 us-central1 替换为您要使用的其他区域。
创建网格规范并将其存储在 mesh.yaml 文件中:
cat <<EOF > mesh.yaml name: shared-mesh EOF在此项目中定义一个具有所需配置的网格资源:
gcloud network-services meshes import shared-mesh \ --source=mesh.yaml \ --location=${REGION}记下此网格资源的完整 URI。服务所有者将来需要使用此 URI 将其路由关联到此网格。
将
networkservices.meshes.useIAM 权限授予此网格以及能够将其服务信息关联到此网格的跨项目服务账号:gcloud projects add-iam-policy-binding HOST_PROJECT_NUMBER --member='HTTP_ROUTE_SERVICE_OWNER_ACCOUNT' --role='roles/compute.networkAdmin'现在,被授予
networkservices.meshes.use权限的所有服务所有者都可以将其路由规则添加到此网格。
服务项目中的路由配置
每个服务所有者都需要在其项目中创建区域后端服务和区域路由资源,类似于使用 HTTP 服务设置 Envoy 代理。唯一的区别是,每个 HTTPRoute/GRPCRoute/TCPRoute 都将在 meshes 字段中包含宿主项目的网格资源的 URI。
创建 sharedvpc-http-route:
echo "name: sharedvpc-http-route hostnames: - helloworld-gce meshes: - /projects/HOST_PROJECT_NUMBER/locations/${REGION}/meshes/shared-mesh rules: - action: destinations: - serviceName: \"SERVICE_URL\"" | \ gcloud network-services http-routes import sharedvpc-http-route \ --source=- \ --location=${REGION}
在服务项目中配置客户端服务
配置位于服务项目中的 Cloud Service Mesh 客户端(Envoy 代理或无代理客户端)时,需要在其引导配置中指定网格资源所在的项目编号和网格名称:
TRAFFICDIRECTOR_GCP_PROJECT_NUMBER=HOST_PROJECT_NUMBER
TRAFFICDIRECTOR_MESH_NAME=MESH_NAME
网关 TLS 路由
本部分演示了如何使用区域级网关和区域级 TLSRoute 资源设置基于 Envoy 代理的入站流量网关。
区域级外部直通式网络负载平衡器会将流量定向到充当入站流量网关的 Envoy 代理。Envoy 代理使用 TLS 直通路由并将流量定向到后端虚拟机实例上运行的 HTTPS 服务器。
定义一些将在整个示例中使用的变量。
export PROJECT_ID="PROJECT_ID"
export PROJECT_NUMBER="PROJECT_NUMBER"
export REGION="us-central1"
export ZONE="us-central1-b"
export NETWORK_NAME = "default"
替换以下内容:default
- PROJECT_ID 替换为您的项目 ID。
- 将 PROJECT_NUMBER 替换为您的项目编号。
您可以选择性地替换以下内容:
- 将 us-central1 替换为您要使用的其他区域。
- 将 us-central1-b 替换为您要使用的其他可用区。
- 将 default 替换为您要使用的其他网络名称。
在多项目共享 VPC 环境中交叉引用区域网格和区域路由资源
在某些场景下,服务网格配置包含由不同项目拥有的服务。例如,在共享 VPC 或对等互连 VPC 部署中,每个项目所有者都可以定义自己的一组服务,以使这些服务可用于所有其他项目。
此配置称为“跨项目”配置,因为将不同项目中定义的多个资源相结合,形成可提供给代理或无代理客户端的单个配置。
配置防火墙规则
配置防火墙规则,以允许来自任何来源的流量。修改端口和来源 IP 地址范围的命令。
gcloud compute firewall-rules create allow-gateway-health-checks \ --network=${NETWORK_NAME} \ --direction=INGRESS \ --action=ALLOW \ --rules=tcp \ --source-ranges="35.191.0.0/16,209.85.152.0/22,209.85.204.0/22" \ --target-tags=gateway-proxy
配置 IAM 权限
为网关代理创建服务账号身份:
gcloud iam service-accounts create gateway-proxy将所需的 IAM 角色分配给服务账号身份:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:gateway-proxy@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/trafficdirector.client"gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:gateway-proxy@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/logging.logWriter"
配置区域级网关:
在名为 gateway8443.yaml 的文件中,创建用于 HTTP 流量的 Gateway 规范:
cat <<EOF > gateway8443.yaml name: gateway8443 scope: gateway-proxy-8443 ports: - 8443 type: OPEN_MESH EOF使用 gateway8443.yaml 规范创建区域级 Gateway 资源:
gcloud network-services gateways import gateway8443 \ --source=gateway8443.yaml \ --location=${REGION}
使用 Envoy 代理创建代管式实例组
在本部分中,您将为运行自动部署的 Envoy 服务代理的虚拟机创建实例模板。Envoy 的范围设置为 gateway-proxy。请勿将服务端口作为 --service-proxy 标志的参数传递。
使用 Envoy 代理创建代管式实例组:
gcloud beta compute instance-templates create gateway-proxy \ --scopes=https://www.googleapis.com/auth/cloud-platform \ --tags=gateway-proxy,http-td-tag,http-server,https-server \ --image-family=debian-11 \ --image-project=debian-cloud \ --network-interface=network=${NETWORK_NAME} \ --service-account="gateway-proxy@${PROJECT_ID}.iam.gserviceaccount.com" \ --metadata=startup-script='#! /usr/bin/env bash # Set variables export ENVOY_CONTROL_PLANE_REGION="us-central1" export GCP_PROJECT_NUMBER=PROJECT_NUMBER export VPC_NETWORK_NAME=scope:gateway-proxy-8443 export ENVOY_USER="envoy" export ENVOY_USER_UID="1337" export ENVOY_USER_GID="1337" export ENVOY_USER_HOME="/opt/envoy" export ENVOY_CONFIG="${ENVOY_USER_HOME}/config.yaml" export ENVOY_PORT="15001" export ENVOY_ADMIN_PORT="15000" export ENVOY_TRACING_ENABLED="false" export ENVOY_XDS_SERVER_CERT="/etc/ssl/certs/ca-certificates.crt" export ENVOY_ACCESS_LOG="/dev/stdout" export ENVOY_NODE_ID="$(cat /proc/sys/kernel/random/uuid)~$(hostname -i)" export BOOTSTRAP_TEMPLATE="${ENVOY_USER_HOME}/bootstrap_template.yaml" export GCE_METADATA_SERVER="169.254.169.254/32" export INTERCEPTED_CIDRS="*" export GCE_ZONE=$(curl -sS -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/zone | cut -d"/" -f4) # Create system user account for Envoy binary sudo groupadd ${ENVOY_USER} \ --gid=${ENVOY_USER_GID} \ --system sudo adduser ${ENVOY_USER} \ --uid=${ENVOY_USER_UID} \ --gid=${ENVOY_USER_GID} \ --home=${ENVOY_USER_HOME} \ --disabled-login \ --system # Download and extract the Cloud Service Mesh tar.gz file cd ${ENVOY_USER_HOME} sudo curl -sL https://storage.googleapis.com/traffic-director/traffic-director-xdsv3.tar.gz -o traffic-director-xdsv3.tar.gz sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/bootstrap_template.yaml \ -C bootstrap_template.yaml \ --strip-components 1 sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/iptables.sh \ -C iptables.sh \ --strip-components 1 sudo rm traffic-director-xdsv3.tar.gz # Generate Envoy bootstrap configuration cat "${BOOTSTRAP_TEMPLATE}" \ | sed -e "s|ENVOY_NODE_ID|${ENVOY_NODE_ID}|g" \ | sed -e "s|ENVOY_ZONE|${GCE_ZONE}|g" \ | sed -e "s|VPC_NETWORK_NAME|${VPC_NETWORK_NAME}|g" \ | sed -e "s|CONFIG_PROJECT_NUMBER|${GCP_PROJECT_NUMBER}|g" \ | sed -e "s|ENVOY_PORT|${ENVOY_PORT}|g" \ | sed -e "s|ENVOY_ADMIN_PORT|${ENVOY_ADMIN_PORT}|g" \ | sed -e "s|XDS_SERVER_CERT|${ENVOY_XDS_SERVER_CERT}|g" \ | sed -e "s|TRACING_ENABLED|${ENVOY_TRACING_ENABLED}|g" \ | sed -e "s|ACCESSLOG_PATH|${ENVOY_ACCESS_LOG}|g" \ | sed -e "s|BACKEND_INBOUND_PORTS|${BACKEND_INBOUND_PORTS}|g" \ | sed -e "s|trafficdirector.googleapis.com|trafficdirector.${ENVOY_CONTROL_PLANE_REGION}.rep.googleapis.com|g" \ | sudo tee "${ENVOY_CONFIG}" # Install Envoy binary wget -O envoy_key https://apt.envoyproxy.io/signing.key cat envoy_key | sudo gpg --dearmor > $(pwd)/envoy-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=$(pwd)/envoy-keyring.gpg] https://apt.envoyproxy.io bullseye main" | sudo tee /etc/apt/sources.list.d/envoy.list sudo apt-get update sudo apt-get install envoy # Run Envoy as systemd service sudo systemd-run --uid=${ENVOY_USER_UID} --gid=${ENVOY_USER_GID} \ --working-directory=${ENVOY_USER_HOME} --unit=envoy.service \ bash -c "/usr/bin/envoy --config-path ${ENVOY_CONFIG} | tee" # Configure iptables for traffic interception and redirection sudo ${ENVOY_USER_HOME}/iptables.sh \ -p "${ENVOY_PORT}" \ -u "${ENVOY_USER_UID}" \ -g "${ENVOY_USER_GID}" \ -m "REDIRECT" \ -i "${INTERCEPTED_CIDRS}" \ -x "${GCE_METADATA_SERVER}" '通过实例模板创建区域级代管式实例组:
gcloud compute instance-groups managed create gateway-proxy \ --region=${REGION} \ --size=1 \ --template=gateway-proxy设置托管式实例组的服务端口名称:
gcloud compute instance-groups managed set-named-ports gateway-proxy \ --named-ports=https:8443 \ --region=${REGION}
设置区域级外部直通网络负载均衡器
创建静态外部区域级 IP 地址:
gcloud compute addresses create xnlb-${REGION} \ --region=${REGION}获取为外部负载均衡器预留的 IP 地址:
gcloud compute addresses describe xnlb-${REGION} \ --region=${REGION} --format='value(address)'为网关代理创建健康检查:
gcloud compute health-checks create tcp xnlb-${REGION} \ --region=${REGION} \ --use-serving-port为网关代理创建后端服务:
gcloud compute backend-services create xnlb-${REGION} \ --health-checks=xnlb-${REGION} \ --health-checks-region=${REGION} \ --load-balancing-scheme=EXTERNAL \ --protocol=TCP \ --region=${REGION} \ --port-name=https将托管式实例组添加为后端:
gcloud compute backend-services add-backend xnlb-${REGION} \ --instance-group=gateway-proxy \ --instance-group-region=${REGION} \ --region=${REGION}创建转发规则以将流量路由到网关代理:
gcloud compute forwarding-rules create xnlb-${REGION} \ --region=${REGION} \ --load-balancing-scheme=EXTERNAL \ --address=${IP_ADDRESS} \ --ip-protocol=TCP \ --ports=8443 \ --backend-service=xnlb-${REGION} \ --backend-service-region=${REGION}
配置运行 HTTPS 服务的代管式实例组
使用在端口 8443 上公开的 HTTPS 服务创建实例模板:
gcloud compute instance-templates create td-https-vm-template \ --scopes=https://www.googleapis.com/auth/cloud-platform \ --tags=https-td-server \ --image-family=debian-11 \ --image-project=debian-cloud \ --metadata=startup-script='#! /bin/bash sudo rm -rf /var/lib/apt/lists/* sudo apt-get -y clean sudo apt-get -y update sudo apt-get -y install apt-transport-https ca-certificates curl gnupg2 software-properties-common sudo curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add - sudo add-apt-repository -y "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" sudo apt-get -y update sudo apt-get -y install docker-ce sudo which docker echo "{ \"registry-mirrors\": [\"https://mirror.gcr.io\"] }" | sudo tee -a /etc/docker/daemon.json sudo service docker restart sudo docker run -e HTTPS_PORT=9999 -p 8443:9999 --rm -dt mendhak/http-https-echo:22'基于实例模板创建托管式实例组:
gcloud compute instance-groups managed create https-td-mig-us-${REGION} \ --zone=${ZONE} \ --size=2 \ --template=td-https-vm-template设置托管式实例组的服务端口的名称:
gcloud compute instance-groups managed set-named-ports https-td-mig-us-${REGION} \ --named-ports=https:8443 \ --zone=${ZONE}创建运行状况检查:
gcloud compute health-checks create https https-helloworld-health-check \ --port=8443 --region=${REGION}创建防火墙规则以允许传入的健康检查关联到您网络中的实例:
gcloud compute firewall-rules create https-vm-allow-health-checks \ --network ${NETWORK_NAME} --action allow --direction INGRESS \ --source-ranges 35.191.0.0/16,130.211.0.0/22 \ --target-tags https-td-server \ --rules tcp:8443创建负载均衡方案为
INTERNAL_SELF_MANAGED的区域性后端服务,并添加健康检查:gcloud compute backend-services create https-helloworld-service \ --region=${REGION} \ --load-balancing-scheme=INTERNAL_SELF_MANAGED \ --port-name=https \ --health-checks="https://www.googleapis.com/compute/v1/projects/${PROJECT}/regions/${REGION}/healthChecks/https-helloworld-health-check"将托管式实例组作为后端添加到后端服务:
gcloud compute backend-services add-backend https-helloworld-service \ --instance-group=https-td-mig-us-${REGION} \ --instance-group-zone=${ZONE} \ --region=${REGION}
使用 TLSRoute 资源设置路由
在名为 tls_route.yaml 的文件中,创建 TLSRoute 规范:
cat <<EOF > tls_route.yaml name: helloworld-tls-route gateways: - projects/${PROJECT_NUMBER}/locations/${REGION}/gateways/gateway8443 rules: - matches: - sniHost: - example.com alpn: - h2 action: destinations: - serviceName: projects/${PROJECT_NUMBER}/locations/${REGION}/backendServices/https-helloworld-service EOF在上一个指令中,TLSRoute 将 example.com 作为 SNI 匹配,并将 h2 作为 ALPN 匹配。如果匹配项按如下方式更改,则 TLSRoute 会匹配 SNI 或 ALPN:
- matches: - sniHost: - example.com - alpn: - h2使用 tls_route.yaml 规范创建 TLSRoute 资源:
gcloud network-services tls-routes import helloworld-tls-route \ --source=tls_route.yaml \ --location=${REGION}
验证部署
运行以下 curl 命令以验证与您创建的测试服务之间的 HTTP 连接:
curl https://example.com:8443 --resolve example.com:8443:${IP_ADDRESS} -k该命令会返回托管式实例组中某个虚拟机的响应。输出类似于以下内容:
{ "path": "/", "headers": { "host": "example.com:8443", "user-agent": "curl/8.16.0", "accept": "*/*" }, "method": "GET", "body": "", "fresh": false, "hostname": "example.com", "ip": "::ffff:10.128.0.59", "ips": [], "protocol": "https", "query": {}, "subdomains": [], "xhr": false, "os": { "hostname": "19cd7812e792" }, "connection": { "servername": "example.com" }
使用否定验证方法进行验证
在以下命令中,SNI 与 example.com 不匹配,因此网关会拒绝连接:
curl https://invalid-server.com:8443 --resolve invalid-server.com:8443:${IP_ADDRESS} -k在以下命令中,ALPN 与 h2(HTTP2 协议)不匹配,因此网关会拒绝连接:
curl https://example.com:8443 --resolve example.com:8443:${IP_ADDRESS} -k --http1.1上述命令均会返回以下错误:
curl: (35) OpenSSL SSL_connect: Connection reset by peer in connection.在以下命令中,客户端将创建一个纯文本(未加密)连接,因此网关会拒绝该连接,并显示“404 Not Found”错误:
curl example.com:8443 --resolve example.com:8443:${IP_ADDRESS} -k