設定 Google Kubernetes Engine 和無 Proxy 的 gRPC 服務

本指南說明如何設定 Google Kubernetes Engine、gRPC 應用程式,以及 Cloud Service Mesh 所需的負載平衡元件。

在按照本指南中的說明操作之前,請先參閱「準備設定使用無 Proxy gRPC 服務的 Cloud Service Mesh」。

總覽

使用 GKE 和無 Proxy gRPC 服務設定 Cloud Service Mesh 時,請務必完成下列步驟:

  1. 準備 GKE 叢集。
  2. 將 gRPC 伺服器應用程式部署為 Kubernetes 服務。為 GKE 部署規格加上註解,自動為服務建立網路端點群組 (NEG)。
  3. 使用 NEG 和其他 Google Cloud 負載平衡元件設定 Cloud Service Mesh。
  4. 使用無 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 主控台建立叢集,請執行下列步驟:

  1. 前往 Google Cloud 控制台的「Kubernetes Engine」選單。

    前往 Google Kubernetes Engine 選單

  2. 按一下 [Create cluster] (建立叢集)

  3. 選擇 [Standard cluster] (標準叢集) 範本,或者為您的工作負載選擇適當的範本

  4. 視需要自訂範本。以下均為必填欄位:

    • 名稱:輸入 grpc-td-cluster
    • 位置類型: Zonal
    • 可用區: us-central1-a
    • 節點集區:
  5. 在左側選單中,按一下「default-pool」

  6. 將「Name」變更為 grpc-td-cluster

  7. 在「Size」下方輸入要建立的節點數量。您必須要有可用於節點及其資源 (例如防火牆路徑) 的資源配額

  8. 在左側選單中,按一下「節點」

  9. 在「Machine Configuration」(機器設定) 下方的「Machine family」(機器系列) 中,按一下「Compute Optimized」(運算最佳化)

  10. 選取機器類型。如需機器類型的定價資訊,請參閱 Compute Engine 定價頁面

  11. 在「Networking」(網路) 下方,新增「Network tag」(網路標記) allow-health-checks

  12. 在左側選單中,按一下「節點安全性」

  13. 在 [Access scopes] (存取權範圍) 下,選取 [Allow full access to all Cloud APIs] (允許所有 Cloud API 的完整存取權)

  14. 按一下 [建立]。

在 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 上要求傳送的通訊埠。通常,porttargetPort 會設為相同的值,以方便使用,但這個範例使用不同的值,指出 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

  1. 建立健康狀態檢查。

    gcloud compute health-checks create grpc grpc-gke-helloworld-hc \
     --use-serving-port
    
  2. 建立防火牆規則。

    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
    
  3. 建立後端服務。

    gcloud compute backend-services create grpc-gke-helloworld-service \
       --global \
       --load-balancing-scheme=INTERNAL_SELF_MANAGED \
       --protocol=GRPC \
       --health-checks grpc-gke-helloworld-hc
    
  4. 將後端 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 服務規格中的 porttargetPort 通訊埠都會設為相同值,但這個範例使用不同的值,以顯示 Cloud Service Mesh 不會使用服務規格中的 port

gcloud

  1. 建立網址對應。

    gcloud compute url-maps create grpc-gke-url-map \
    --default-service grpc-gke-helloworld-service
    
  2. 建立路徑比對器。

    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
    
  3. 建立目標 gRPC Proxy。

    gcloud compute target-grpc-proxies create grpc-gke-proxy \
    --url-map grpc-gke-url-map \
    --validate-for-proxyless
    
  4. 建立轉寄規則。

    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 用戶端驗證服務,請按照下列步驟操作:

  1. 下載最新版的 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
     

  2. 請以 "world" 做為名稱,以 "xds:///helloworld-gke:8000" 做為服務 URI 和通訊埠,執行用戶端。

    ./build/install/example-xds/bin/xds-hello-world-client "world" \
    xds:///helloworld-gke:8000
    

Go

如要使用 gRPC Go 用戶端驗證服務,請按照下列步驟操作:

  1. 下載最新版的 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 .
    
  2. 請以 "world" 做為名稱,以 "xds:///helloworld-gke:8000" 做為服務 URI 和通訊埠,執行用戶端。

    ./client "world" xds:///helloworld-gke:8000
    

C++

如要使用 gRPC C++ 用戶端驗證服務,請按照下列步驟操作:

  1. 下載最新版的 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
    
  2. 使用「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 工具驗證設定,請按照下列步驟操作:

  1. 下載並安裝 grpcurl 工具。

    curl -L https://github.com/fullstorydev/grpcurl/releases/download/v1.8.1/grpcurl_1.8.1_linux_x86_64.tar.gz | tar -xz
    
  2. 請使用「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 解析。

後續步驟