設定 Google Kubernetes Engine 和無 Proxy 的 gRPC 服務
本指南說明如何設定 Google Kubernetes Engine、gRPC 應用程式,以及 Cloud Service Mesh 所需的負載平衡元件。
在按照本指南中的說明操作之前,請先參閱「準備設定使用無 Proxy gRPC 服務的 Cloud Service Mesh」。
總覽
使用 GKE 和無 Proxy gRPC 服務設定 Cloud Service Mesh 時,請務必完成下列步驟:
- 準備 GKE 叢集。
- 將 gRPC 伺服器應用程式部署為 Kubernetes 服務。為 GKE 部署規格加上註解,自動為服務建立網路端點群組 (NEG)。
- 使用 NEG 和其他 Google Cloud 負載平衡元件設定 Cloud Service Mesh。
- 使用無 Proxy gRPC 用戶端應用程式,將流量傳送至 gRPC 伺服器應用程式,驗證部署作業是否正常運作。
為 Cloud Service Mesh 設定 GKE 叢集
本節說明如何讓 GKE 叢集與 Cloud Service Mesh 搭配運作。
GKE 叢集需求
GKE 叢集必須符合下列要求:
- 您必須啟用網路端點群組支援功能。如需詳細資訊和範例,請參閱「獨立網路端點群組」。獨立 NEG 功能已在 Cloud Service Mesh 正式版中推出。
- 叢集節點執行個體服務帳戶必須具有存取 Cloud Service Mesh API 的權限。如要進一步瞭解所需權限,請參閱「啟用服務帳戶以存取 Cloud Service Mesh API」。
- 容器必須具備 Cloud Service Mesh API 的存取權,且受 OAuth 驗證保護。詳情請參閱主機設定。
建立 GKE 叢集
下列範例示範如何在 us-central1-a zone
中建立名為 grpc-td-cluster
的 GKE 叢集。
控制台
如要使用 Google Cloud 主控台建立叢集,請執行下列步驟:
前往 Google Cloud 控制台的「Kubernetes Engine」選單。
按一下 [Create cluster] (建立叢集)。
選擇 [Standard cluster] (標準叢集) 範本,或者為您的工作負載選擇適當的範本。
視需要自訂範本。以下均為必填欄位:
- 名稱:輸入
grpc-td-cluster
。 - 位置類型:
Zonal
。 - 可用區:
us-central1-a
。 - 節點集區:
- 名稱:輸入
在左側選單中,按一下「default-pool」。
將「Name」變更為
grpc-td-cluster
。在「Size」下方輸入要建立的節點數量。您必須要有可用於節點及其資源 (例如防火牆路徑) 的資源配額。
在左側選單中,按一下「節點」。
在「Machine Configuration」(機器設定) 下方的「Machine family」(機器系列) 中,按一下「Compute Optimized」(運算最佳化)。
選取機器類型。如需機器類型的定價資訊,請參閱 Compute Engine 定價頁面。
在「Networking」(網路) 下方,新增「Network tag」(網路標記)
allow-health-checks
。在左側選單中,按一下「節點安全性」。
在 [Access scopes] (存取權範圍) 下,選取 [Allow full access to all Cloud APIs] (允許所有 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
服務並無任何特別之處。這不是無 Proxy 的 gRPC 服務,但可以回應任何 gRPC 用戶端的要求。
只有在 gRPC 用戶端應用程式連線至 Cloud Service Mesh、瞭解 helloworld
服務,並且能夠將流量傳送至與 helloworld
相關聯的 Pod 時,才會使用「無 Proxy」部分,而不需要依賴 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 控制台的「Network Endpoint Groups」(網路端點群組) 頁面。您會看到名為 example-grpc-server
的 NEG。
前往「Network Endpoint Groups」(網路端點群組) 頁面
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 負載平衡元件。這些元件包含設定資訊,可讓無 Proxy 的 gRPC 用戶端與 GKE 服務通訊。
以下 Cloud Service Mesh 設定範例假設如下:
- NEG 和其他所有的資源都在在
us-central1-a
區域中以自動模式建立在預設網路。 - 使用 Google Cloud CLI 時,叢集的 NEG 名稱為
example-grpc-server
。
建立健康狀態檢查、防火牆規則和後端服務
在本節中,您將建立健康狀態檢查和健康狀態檢查的防火牆規則。健康狀態檢查必須使用 gRPC 健康狀態檢查通訊協定。防火牆規則可讓健康狀態檢查探測器連線至部署中的 VM。健康狀態檢查會使用 --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 Proxy 和轉送規則。
詳情請參閱「轉送規則對應」。
以下範例使用服務名稱 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
通訊埠都會設為相同值,但這個範例使用不同的值,以顯示 Cloud Service Mesh 不會使用服務規格中的 port
。
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 Proxy。
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 的端點間負載平衡流量。
驗證設定
設定程序完成後,請確認您可以使用無 Proxy gRPC 用戶端存取 helloworld
gRPC 伺服器。這個用戶端會連線至 Cloud Service Mesh,取得 helloworld
服務的相關資訊 (使用 grpc-gke-helloworld-service
後端服務設定 Cloud Service Mesh),並利用這些資訊將流量傳送至服務的後端。
您也可以查看 Google Cloud 控制台中的「Cloud Service Mesh」專區,瞭解已設定服務 helloworld-gke
的相關資訊,並檢查後端是否已回報為健康狀態。
使用無 Proxy gRPC 用戶端進行驗證
在以下範例中,您將使用不同語言的 gRPC 用戶端或 grpcurl
工具,驗證 Cloud Service Mesh 是否正確在網格中轉送流量。您需要建立用戶端 Pod,然後開啟殼層並在殼層中執行驗證指令。
設定環境變數和啟動檔案
用戶端應用程式需要使用引導設定檔。修改 Kubernetes 應用程式部署規格,方法是新增可產生啟動檔案的 initContainer
,以及用於傳輸檔案的磁碟區。更新現有容器即可找到檔案。
將下列 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 的殼層。
kubectl exec -it $(kubectl get pods -o custom-columns=:.metadata.name \ --selector=run=client) -- /bin/bash
如要驗證設定,請在 Pod 殼層中執行適當的範例。
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
工具也可以做為無 Proxy gRPC 用戶端。在這種情況下,grpcurl
會使用環境變數和 Bootstrap 資訊,連線至 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
請使用「xds:///helloworld-gke:8000」做為服務 URI,並使用
helloworld.Greeter/SayHello
做為要叫用的服務名稱和方法,執行grpcurl
工具。SayHello
方法的參數會透過-d
選項傳遞。./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
是 VM 執行個體的主機名稱:
Greetings: Hello world, from INSTANCE_HOST_NAME
這會驗證無 Proxy gRPC 用戶端是否成功連線至 Cloud Service Mesh,並使用 xds 名稱解析工具瞭解 helloworld-gke
服務的後端。用戶端向服務的其中一個後端傳送要求,不必瞭解 IP 位址或執行 DNS 解析。
後續步驟
- 瞭解 Cloud Service Mesh 服務安全性。
- 瞭解進階流量管理。
- 瞭解如何設定可觀測性。
- 瞭解如何排解無 Proxy 的 Cloud Service Mesh 部署問題。