设置 Google Kubernetes Engine 和无代理 gRPC 服务
本指南介绍如何配置 Google Kubernetes Engine、gRPC 应用以及 Cloud Service Mesh 所需的负载均衡组件。
在按照本指南中的说明执行操作之前,请参阅准备使用无代理 gRPC 服务设置 Cloud Service Mesh。
概览
使用 GKE 和无代理 gRPC 服务设置 Cloud Service Mesh 涉及以下内容:
- 准备 GKE 集群。
- 将 gRPC 服务器应用部署为 Kubernetes 服务。为 GKE 部署规范添加注释,以自动为服务创建网络端点组 (NEG)。
- 使用 NEG 和其他 Google Cloud 负载平衡组件配置 Cloud Service Mesh。
- 使用无代理 gRPC 客户端应用向 gRPC 服务器应用发送流量,以验证部署是否正常运行。
为 Cloud Service Mesh 配置 GKE 集群
本部分介绍如何将 GKE 集群与 Cloud Service Mesh 搭配使用。
GKE 集群要求
GKE 集群必须满足以下要求:
- 必须启用网络端点组支持。如需了解详情和示例,请参阅独立网络端点组。独立的 NEG 功能现已面向 Cloud Service Mesh 推出正式版。
- 集群节点实例的服务账号必须有权访问 Cloud Service Mesh API。如需详细了解所需权限,请参阅启用服务账号以访问 Cloud Service Mesh API。
- 容器必须有权访问受 OAuth 身份验证保护的 Cloud Service Mesh API。如需了解详情,请参阅主机配置。
创建 GKE 集群
以下示例展示了如何在 us-central1-a zone
中创建名为 grpc-td-cluster
的 GKE 集群。
控制台
如需使用 Google Cloud 控制台创建集群,请执行以下步骤:
转到 Google Cloud 控制台中的 Kubernetes Engine 菜单。
点击创建集群。
选择标准集群模板,或者为您的工作负载选择一个合适的模板。
自定义模板(如有必要)。以下字段是必填字段:
- 名称:输入
grpc-td-cluster
。 - 位置类型:
Zonal
。 - 区域:
us-central1-a
。 - 节点池:
- 名称:输入
在左侧菜单中,点击 default-pool。
将名称更改为
grpc-td-cluster
。在大小下,输入要创建的节点数。您必须具有节点及其资源(例如防火墙路由)的可用资源配额。
在左侧菜单中,点击节点。
在机器配置下的机器系列中,点击计算优化。
选择机器类型。如需了解机器类型价格信息,请参阅 Compute Engine 价格页面。
在网络下,添加网络标记
allow-health-checks
。在左侧菜单中,点击节点安全。
在访问权限范围下方,选择允许所有 Cloud API 的全面访问权限。
点击创建。
在 Google Cloud 控制台中创建集群后,您需要配置 kubectl
以与该集群进行交互。如需了解详情,请参阅生成 kubeconfig
条目。
gcloud
创建集群。
gcloud container clusters create grpc-td-cluster \ --zone us-central1-a \ --scopes=https://www.googleapis.com/auth/cloud-platform \ --tags=allow-health-checks \ --enable-ip-alias
获取所需的 GKE 集群权限
通过发出以下命令切换到刚创建的集群。这会将 kubectl
指向正确的集群。
gcloud
gcloud container clusters get-credentials grpc-td-cluster \ --zone us-central1-a
配置 GKE 服务
本部分介绍如何准备 GKE 部署规范以使用 Cloud Service Mesh。这包括使用 NEG 注释配置 GKE helloworld
示例服务。
helloworld
示例服务是一个 gRPC 服务器应用,会返回消息来响应 gRPC 客户端的请求。请注意,helloworld
服务没有特殊要求。它不是无代理 gRPC 服务,并且可以响应来自任何 gRPC 客户端的请求。
仅当 gRPC 客户端应用连接到 Cloud Service Mesh、了解 helloworld
服务,然后可以将流量发送到与 helloworld
关联的 Pod,而无需依赖 IP 地址或基于 DNS 的名称解析时,“无代理”部分才会发挥作用。
使用 NEG 配置 GKE 服务
配置 GKE 服务以与 Cloud Service Mesh 搭配使用的第一步是通过 NEG 公开服务。要通过 NEG 公开,每项规范都必须具有以下注释,并与要公开的端口匹配。
... metadata: annotations: cloud.google.com/neg: '{"exposed_ports":{"8080":{"name": "example-grpc-server"}}}'
此注释会在您首次部署服务时创建独立的 NEG。此 NEG 包含 Pod 的 IP 地址和端口。如需了解详情和示例,请参阅独立网络端点组。
在以下示例中,您将部署一个在端口 8080
上公开的 helloworld
Kubernetes 服务。这是服务在集群中可见的端口。Pod 中的 gRPC 服务正在侦听 targetPort
50051
。这是将请求发送到的 Pod 上的端口。通常,为方便起见,port
和 targetPort
设置为相同的值,但此示例使用不同的值来指示要在 NEG 注释中使用的正确值。
cat << EOF > grpc-td-helloworld.yaml apiVersion: v1 kind: Service metadata: name: helloworld annotations: cloud.google.com/neg: '{"exposed_ports":{"8080":{"name": "example-grpc-server"}}}' spec: ports: - port: 8080 name: helloworld protocol: TCP targetPort: 50051 selector: run: app1 type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: labels: run: app1 name: app1 spec: selector: matchLabels: run: app1 replicas: 2 template: metadata: labels: run: app1 spec: containers: - image: grpc/java-example-hostname:1.50.2 name: app1 ports: - protocol: TCP containerPort: 50051 EOF
kubectl apply -f grpc-td-helloworld.yaml
验证是否已创建新的 helloworld
服务:
kubectl get svc
kubectl get svc
的输出应如下所示:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE helloworld ClusterIP 10.71.9.71 <none> 8080/TCP 41m [..skip..]
验证应用 Pod 是否正在运行:
kubectl get pods
kubectl get pods
的输出应如下所示:
NAME READY STATUS RESTARTS AGE app1-6db459dcb9-zvfg2 1/1 Running 0 6m app1-6db459dcb9-hlvhj 1/1 Running 0 6m [..skip..]
验证 NEG 名称是否正确。
控制台
如需查看网络端点组的列表,请转到 Google Cloud Console 中的“网络端点组”页面。您会看到一个名为 example-grpc-server
的 NEG。
转到“网络端点组”页面
gcloud
# List the NEGs gcloud compute network-endpoint-groups list \ --filter "name=example-grpc-server" --format "value(name)" # Optionally examine the NEG gcloud compute network-endpoint-groups describe example-grpc-server \ --zone us-central1-a # Optionally examine the endpoint(s) contained gcloud compute network-endpoint-groups list-network-endpoints example-grpc-server \ --zone us-central1-a
使用负载均衡组件配置 Cloud Service Mesh
本部分介绍如何为服务配置 Google Cloud 负载均衡组件。这些组件包含配置信息,无代理 (gRPC) 客户端可利用此类信息与 GKE 服务通信。
下面的 Cloud Service Mesh 配置示例做出了以下假设:
- NEG 和所有其他资源是在区域
us-central1-a
的自动模式默认网络中创建发。 - 使用 Google Cloud CLI 时,集群的 NEG 名称为
example-grpc-server
。
创建健康检查、防火墙规则和后端服务
在本部分中,您将创建健康检查以及健康检查的防火墙规则。健康检查必须使用 gRPC 健康检查协议。防火墙规则允许健康检查探测连接到部署中的虚拟机。--use-serving-port
指令由健康检查用于为每个端点获取配置的侦听端口。
防火墙规则允许与您网络中的实例建立传入健康检查连接。
在本部分中,您将创建负载均衡方案为 INTERNAL_SELF_MANAGED
且协议为 GRPC
的全局后端服务,然后将健康检查与后端服务相关联。
如需了解详情,请参阅创建健康检查。
gcloud
创建健康检查。
gcloud compute health-checks create grpc grpc-gke-helloworld-hc \ --use-serving-port
创建防火墙规则。
gcloud compute firewall-rules create grpc-gke-allow-health-checks \ --network default --action allow --direction INGRESS \ --source-ranges 35.191.0.0/16,130.211.0.0/22 \ --target-tags allow-health-checks \ --rules tcp:50051
创建后端服务。
gcloud compute backend-services create grpc-gke-helloworld-service \ --global \ --load-balancing-scheme=INTERNAL_SELF_MANAGED \ --protocol=GRPC \ --health-checks grpc-gke-helloworld-hc
将后端 NEG 添加到后端服务。
gcloud compute backend-services add-backend grpc-gke-helloworld-service \ --global \ --network-endpoint-group example-grpc-server \ --network-endpoint-group-zone us-central1-a \ --balancing-mode RATE \ --max-rate-per-endpoint 5
创建路由规则映射
在本部分中,您将创建网址映射、路径匹配器和主机规则,以根据主机名和路径路由服务的流量。以下示例使用 helloworld-gke
作为服务名称。gRPC 客户端在连接到 helloworld
服务时会在目标 URI 中使用此服务名称。您还将创建目标 gRPC 代理和转发规则。
如需了解详情,请参阅路由规则映射。
以下示例使用服务名称 helloworld-gke
和端口 8000
。这意味着 gRPC 客户端必须使用 xds:///helloworld-gke:8000
连接到此服务,并且必须在网址映射中配置主机规则 helloworld-gke:8000
。请注意,Cloud Service Mesh 不使用上一部分中 Kubernetes 服务规范中显示的服务端口 8080
,因为 helloworld-gke:8000
直接解析为侦听 targetPort
50051
的 NEG 端点。通常,为方便起见,网址映射主机规则中的端口以及 Kubernetes 服务规范 port
和 targetPort
都设置为相同的值,但此示例使用不同的值来表明服务中的 port
规范不由 Cloud Service Mesh 使用。
gcloud
创建网址映射。
gcloud compute url-maps create grpc-gke-url-map \ --default-service grpc-gke-helloworld-service
创建路径匹配器。
gcloud compute url-maps add-path-matcher grpc-gke-url-map \ --default-service grpc-gke-helloworld-service \ --path-matcher-name grpc-gke-path-matcher \ --new-hosts helloworld-gke:8000
创建目标 gRPC 代理。
gcloud compute target-grpc-proxies create grpc-gke-proxy \ --url-map grpc-gke-url-map \ --validate-for-proxyless
创建转发规则。
gcloud compute forwarding-rules create grpc-gke-forwarding-rule \ --global \ --load-balancing-scheme=INTERNAL_SELF_MANAGED \ --address=0.0.0.0 \ --target-grpc-proxy=grpc-gke-proxy \ --ports 8000 \ --network default
现在,已将 Cloud Service Mesh 配置为针对网址映射中指定的服务,跨 NEG 中的端点进行流量负载均衡。
验证配置
配置过程完成后,验证是否可以使用无代理 gRPC 客户端访问 helloworld
gRPC 服务器。此客户端连接到 Cloud Service Mesh,获取有关 helloworld
服务的信息(使用 grpc-gke-helloworld-service
后端服务通过 Cloud Service Mesh 配置),并使用此信息将流量发送到服务的后端。
您还可以检查 Google Cloud 控制台中的 Cloud Service Mesh 部分,获取已配置服务 helloworld-gke
的相关信息,并查看后端是否被报告为运行状况良好。
使用无代理 gRPC 客户端进行验证
在以下示例中,您以不同语言使用 gRPC 客户端,或使用 grpcurl
工具验证 Cloud Service Mesh 是否在网格中正确路由流量。您创建一个客户端 Pod,然后打开 shell 并从 shell 运行验证命令。
设置环境变量和引导文件
客户端应用需要引导配置文件。通过添加生成引导文件的 initContainer
和传输文件所需的卷来修改 Kubernetes 应用部署规范。更新现有容器以查找该文件。
将以下 initContainer
添加到应用部署规范:
initContainers: - args: - --output - "/tmp/bootstrap/td-grpc-bootstrap.json" image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0 imagePullPolicy: IfNotPresent name: grpc-td-init resources: limits: cpu: 100m memory: 100Mi requests: cpu: 10m memory: 100Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/bootstrap/ volumes: - name: grpc-td-conf emptyDir: medium: Memory
更新应用容器的 env
部分,使其包含以下内容:
env: - name: GRPC_XDS_BOOTSTRAP value: "/tmp/grpc-xds/td-grpc-bootstrap.json" volumeMounts: - name: grpc-td-conf mountPath: /tmp/grpc-xds/
这是客户端 Kubernetes 规范的完整示例:
cat << EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: labels: run: client name: sleeper spec: selector: matchLabels: run: client template: metadata: labels: run: client spec: containers: - image: openjdk:8-jdk imagePullPolicy: IfNotPresent name: sleeper command: - sleep - 365d env: - name: GRPC_XDS_BOOTSTRAP value: "/tmp/grpc-xds/td-grpc-bootstrap.json" resources: limits: cpu: "2" memory: 2000Mi requests: cpu: 300m memory: 1500Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/grpc-xds/ initContainers: - args: - --output - "/tmp/bootstrap/td-grpc-bootstrap.json" image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0 imagePullPolicy: IfNotPresent name: grpc-td-init resources: limits: cpu: 100m memory: 100Mi requests: cpu: 10m memory: 100Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/bootstrap/ volumes: - name: grpc-td-conf emptyDir: medium: Memory EOF
部署准备就绪后,打开客户端 Pod 的 shell。
kubectl exec -it $(kubectl get pods -o custom-columns=:.metadata.name \ --selector=run=client) -- /bin/bash
如需验证配置,请在 Pod shell 中运行相应的示例。
Java
如需使用 gRPC Java 客户端验证服务,请执行以下操作:
下载最新版本的 gRPC Java,然后使用最新的补丁程序并构建
xds-hello-world
客户端应用。curl -L https://github.com/grpc/grpc-java/archive/v1.37.0.tar.gz | tar -xz cd grpc-java-1.37.0/examples/example-xds ../gradlew --no-daemon installDist
运行客户端,其中
"world"
作为客户端名称,"xds:///helloworld-gke:8000"
作为服务 URI 和端口。./build/install/example-xds/bin/xds-hello-world-client "world" \ xds:///helloworld-gke:8000
Go
如需使用 gRPC Go 客户端验证服务,请执行以下操作:
下载最新版本的 gRPC Go,然后使用最新的补丁程序并构建
xds-hello-world
客户端应用。apt-get update -y apt-get install -y golang git curl -L https://github.com/grpc/grpc-go/archive/v1.37.0.tar.gz | tar -xz cd grpc-go-1.37.0/examples/features/xds/client go get google.golang.org/grpc@v1.37.0 go build .
运行客户端,其中
"world"
作为客户端名称,"xds:///helloworld-gke:8000"
作为服务 URI 和端口。./client "world" xds:///helloworld-gke:8000
C++
如需使用 gRPC C++ 客户端验证服务,请执行以下操作:
下载最新版本的 gRPC C++ 以及最近的补丁程序,然后构建
helloworld
客户端示例。apt-get update -y apt-get install -y build-essential cmake git git clone --recurse-submodules -b v1.37.1 https://github.com/grpc/grpc cd grpc mkdir -p cmake/build pushd cmake/build cmake ../.. make make install popd mkdir -p third_party/abseil-cpp/cmake/build pushd third_party/abseil-cpp/cmake/build cmake ../.. make make install popd cd examples/cpp/helloworld mkdir -p cmake/build cd cmake/build/ cmake ../.. make
运行客户端,其中将“xds:///helloworld-gke:8000”作为服务 URI 和端口。
./greeter_client --target=xds:///helloworld-gke:8000
grpcurl
grpcurl
工具也可以充当无代理 gRPC 客户端。在这种情况下,grpcurl
使用环境变量和引导信息来连接到 Cloud Service Mesh。接着,它会了解 helloworld
服务,该服务通过 grpc-gke-helloworld-service
后端服务使用 Cloud Service Mesh 配置。
如需使用 grpcurl
工具验证您的配置,请执行以下操作:
下载并安装
grpcurl
工具。curl -L https://github.com/fullstorydev/grpcurl/releases/download/v1.8.1/grpcurl_1.8.1_linux_x86_64.tar.gz | tar -xz
运行
grpcurl
工具,其中“xds:///helloworld-gke:8000”作为服务 URI,helloworld.Greeter/SayHello
作为服务名称和要调用的方法。使用-d
选项传递SayHello
方法的参数。./grpcurl --plaintext \ -d '{"name": "world"}' \ xds:///helloworld-gke:8000 helloworld.Greeter/SayHello
Python
如需使用 gRPC Python 客户端验证服务,请运行以下命令。使用包含最新补丁程序的最新版 gRPC。
apt-get update -y apt-get install python3-pip -y pip3 install virtualenv curl -L https://github.com/grpc/grpc/archive/v1.37.1.tar.gz | tar -xz cd grpc-1.37.1/examples/python/xds virtualenv venv -p python3 source venv/bin/activate pip install -r requirements.txt python client.py xds:///helloworld-gke:8000
Ruby
如需使用 gRPC Ruby 客户端验证服务,请运行以下命令。使用包含最新补丁程序的最新版 gRPC。
apt-get update -y apt-get install -y ruby-full gem install grpc curl -L https://github.com/grpc/grpc/archive/v1.37.1.tar.gz | tar -xz cd grpc-1.37.1/examples/ruby ruby greeter_client.rb john xds:///helloworld-gke:8000
PHP
如需使用 gRPC PHP 客户端验证服务,请运行以下命令。使用包含最新补丁程序的最新版 gRPC。
apt-get update -y apt-get install -y php7.3 php7.3-dev php-pear phpunit python-all zlib1g-dev git pecl install grpc curl -sS https://getcomposer.org/installer | php mv composer.phar /usr/local/bin/composer curl -L https://github.com/grpc/grpc/archive/v1.37.1.tar.gz | tar -xz cd grpc-1.37.1 export CC=/usr/bin/gcc ./tools/bazel build @com_google_protobuf//:protoc ./tools/bazel build src/compiler:grpc_php_plugin cd examples/php composer install ../../bazel-bin/external/com_google_protobuf/protoc --proto_path=../protos \ --php_out=. --grpc_out=. \ --plugin=protoc-gen-grpc=../../bazel-bin/src/compiler/grpc_php_plugin \ ../protos/helloworld.proto php -d extension=grpc.so greeter_client.php john xds:///helloworld-gke:8000
Node.js
如需使用 gRPC Node.js 客户端验证服务,请运行以下命令。使用包含最新补丁程序的最新版 gRPC。
apt-get update -y apt-get install -y nodejs npm curl -L https://github.com/grpc/grpc/archive/v1.34.0.tar.gz | tar -xz cd grpc-1.34.0/examples/node/xds npm install node ./greeter_client.js --target=xds:///helloworld-gke:8000
您应该会看到如下所示的输出,其中 INSTANCE_HOST_NAME
是虚拟机实例的主机名:
Greetings: Hello world, from INSTANCE_HOST_NAME
这将验证无代理 gRPC 客户端是否已成功连接到 Cloud Service Mesh,并使用 xds 名称解析器了解 helloworld-gke
服务的后端。客户端向服务的其中一个后端发送请求,无需了解 IP 地址或执行 DNS 解析。
后续步骤
- 了解 Cloud Service Mesh 服务安全。
- 了解高级流量管理。
- 了解如何设置可观测性。
- 了解如何排查无代理 Cloud Service Mesh 部署的问题。