使用 ESPv2 為 Knative 服務設定 Cloud Endpoints gRPC

本頁面說明如何設定 Knative 放送專用的 Cloud Endpoints。Endpoints 使用可擴充服務 Proxy V2 (ESPv2) 做為 API 閘道。如要為 Knative 服務提供 API 管理,您需要先在 GKE 叢集上執行 Knative 服務,然後部署預先建構的 ESPv2 容器。

此設定完成後,ESPv2 會先攔截所有向您服務發出的要求並執行必要的檢查 (例如驗證),然後才叫用服務。當服務回應時,ESPv2 會收集並回報遙測資料。

如需 Endpoints 的總覽,請參閱「關於 Endpoints」和「Endpoints 架構」。

工作清單

在逐步進行本教學課程時,請使用以下工作清單。您必須完成所有工作,才能完成本教學課程。

  1. 建立 Google Cloud 專案,如果尚未部署您自己的 Knative 服務,請部署範例服務。請參閱「事前準備」。

  2. 建立啟用 Knative serving 的 GKE 叢集

  3. 部署 gRPC 範例 Knative 服務服務。

  4. 建立說明 Endpoints API 的 gRPC API 設定文件,並設定連至 Knative 服務的路徑。請參閱設定 Endpoints 一節。

  5. 部署 gRPC API 設定文件,以建立代管服務。請參閱部署 Endpoints 設定一節。

  6. 使用 Endpoints 服務設定建構新的 ESPv2 Docker 映像檔。請參閱「建構新的 ESPv2 映像檔」一文。

  7. 部署新的 ESPv2 Knative 服務映像檔。請參閱「部署 ESPv2 Cloud Run 映像檔」。

  8. 建立 ESPv2 Knative 服務的網域對應

  9. 傳送要求至 API,測試設定。

  10. 追蹤服務的活動。請參閱追蹤 API 活動一節。

  11. 清理

費用

在本文件中,您會使用 Google Cloud的下列計費元件:

您可以使用 Pricing Calculator 根據預測用量產生預估費用。 新 Google Cloud 使用者可能符合申請免費試用的資格。

完成本文件所述工作後,您可以刪除已建立的資源,避免繼續計費。詳情請參閱「清除所用資源」。

事前準備

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  5. Make sure that billing is enabled for your Google Cloud project.

  6. 記下專案 ID,後續步驟將會用到。在本頁其餘部分,這個專案 ID 又稱為 ESP_PROJECT_ID
  7. 下載並安裝 gcloud CLI

    設定 gcloud 指令列

    如要為 Anthos 的 Knative 服務設定 gcloud CLI,請按照下列步驟操作:

    1. 確認 gcloud CLI 已獲授權,可存取您的資料和服務。

      1. 登入。

        gcloud auth login

      2. 在開啟的新瀏覽器分頁中,選擇在用於將 ESPv2 部署至 Knative 服務的 Google Cloud 專案中,具有編輯者擁有者角色的帳戶。

    2. 更新已安裝的 gcloud 元件:

      gcloud components update
    3. 將平台設為 gke,並將 gcloud 的預設專案設定設為您剛才建立的專案:

      gcloud config set run/platform gke 
      gcloud config set project ESP_PROJECT_ID

      ESP_PROJECT_ID 改為您所建立專案的專案 ID。

    4. 為新叢集設定所需的區域。您可以使用所有支援 GKE 的區域,例如:

      gcloud config set compute/zone ZONE

      ZONE 替換成您的區域。例如使用 us-central1-a。您可以使用 GKE 支援的任何區域。

    5. 為專案啟用下列 API。您需要這些 API 來建立叢集、建構容器,並將容器發布到 Artifact Registry:

      gcloud services enable container.googleapis.com artifactregistry.googleapis.com cloudbuild.googleapis.com

建立啟用 Knative serving 的 GKE 叢集

如要建立叢集並啟用叢集,以便在 Google Cloud 上提供 Knative 服務:

  1. 使用以下指令建立新叢集:

    gcloud container clusters create CLUSTER_NAME \ 
      --addons=HttpLoadBalancing,CloudRun \ 
      --machine-type=n1-standard-4 \ 
      --num-nodes=3

    CLUSTER_NAME 替換為您要為叢集命名的名稱。

    雖然這些操作說明並未啟用叢集自動調度資源功能來依需求調整叢集大小,但 Google Cloud 上的 Knative serving 會自動調整叢集內執行個體的資源配置。

  2. 等待叢集建立完成。在建立期間,您應該會看到類似下方的訊息:

    Creating cluster CLUSTER_NAME...done. 
    Created [https://container.googleapis.com/v1/projects/ESP_PROJECT_ID/zones/ZONE/clusters/CLUSTER_NAME].

    輸出結果也會在輸出的 NODE_VERSION 欄下方顯示叢集版本。例如 1.15.11-gke.11.14.10-gke.27。請記下叢集版本,以便在本文件稍後的部分使用。

  3. gcloud 預設值設為使用您的新叢集和叢集位置,這樣您在使用 gcloud CLI 時就不需要指定這些值:

    gcloud config set run/cluster CLUSTER_NAME
    gcloud config set run/cluster_location ZONE
  4. 使用下列指令查看新叢集的詳細資料:

    gcloud container clusters describe CLUSTER_NAME
  5. 使用下列指令擷取叢集的憑證:

    gcloud container clusters get-credentials CLUSTER_NAME

部署 gRPC Cloud Run 服務範例

如要將「grpc-bookstore」Cloud Run for Anthos 範例容器部署至您剛才建立的叢集:

  1. 按照 gRPC Python 快速入門導覽課程中的步驟安裝 gRPC 和 gRPC 工具。

  2. 這個 gRPC 伺服器範例包含 Python「grpc-bookstore 服務」的預先建構 Docker 映像檔:gcr.io/endpointsv2/python-grpc-bookstore-server:2。使用下列指令,將「grpc-bookstore」部署至叢集:

    gcloud run deploy GRPC_SERVICE \
      --image=gcr.io/endpointsv2/python-grpc-bookstore-server:2 \
      --platform=gke \
     --connectivity=internal \
      --use-http2

    請注意,您必須將此服務指定為內部服務,才能避免外部存取該服務。

    GRPC_SERVICE 替換為您想要用於該服務的名稱。例如:

    gcloud run deploy grpc-bookstore \
      --image=gcr.io/endpointsv2/python-grpc-bookstore-server:2 \
      --platform=gke \
      --connectivity=internal \
      --use-http2

    完成後,系統會顯示以下訊息:

    Service [grpc-bookstore] revision [grpc-bookstore-00001-nuk] has been deployed and is serving 100 percent of traffic at http://grpc-bookstore.default.svc.cluster.local

    建立內部服務時,GKE 會建立 DNS 名稱 (本例為 grpc-bookstore.default.svc.cluster.local),該名稱只能解析來自叢集內的請求,無法解析外部請求。您無法從叢集外部存取這個 DNS。詳情請參閱「Cloud Run 服務」。

  3. 如要確認服務是否正常運作,請將具有相同 Docker 映像檔的 Pod 部署至叢集。這張圖片包含「grpc-bookstore」的 gRPC 用戶端程式碼,可用來測試內部服務。

    1. 使用下列 kubectl 指令,將 Pod 部署至與上方部署相同的叢集:

      kubectl run grpc --generator=run-pod/v1 \
        --image=gcr.io/endpointsv2/python-grpc-bookstore-server:2

      這張圖片包含 bookstore_client.py 指令碼,可用於在叢集中提出用戶端要求。

      注意:對於較新的 kubectl 版本,指令可能會發出以下警告:

      Flag --generator has been deprecated, has no effect and will be removed in the future".

      您可以忽略這則警告。

    2. 在先前步驟中部署 Docker 映像檔時,取得在叢集上建立的「grpc-bookstore」Pod 名稱:

      kubectl get pods

      您應該會看到以下輸出內容:

      NAME   READY    STATUS    RESTARTS   AGE
      grpc   1/1      Running   0          23h

      其中 grp 是「grpc-bookstore」Pod 的名稱。請先確認 Pod 的「狀態」為「執行中」,再繼續操作。

    3. 使用下列指令,向「grpc-bookstore」服務提出用戶端要求:

      kubectl exec grpc -ti -- python3 bookstore_client.py \
        --host grpc-bookstore.default.svc.cluster.local --port=80

      這個指令會在叢集內部執行 bookstore_client.py 指令碼,向主機名稱 grpc-bookstore.default.svc.cluster.local 上的「grpc-bookstore」服務提出 gRPC 要求。

      如果一切運作正常,您應該會在表單中看到回應:

      ListShelves: shelves {
        id: 1
        theme: "Fiction"
      }
      shelves {
        id: 2
        theme: "Fantasy"
      }

設定 Endpoints

您必須提供 gRPC API 規範,說明後端服務的介面以及任何驗證需求。

關於設定 gRPC API 規格的名稱欄位

在 gRPC API 規格檔的 name 欄位中,您可以指定用於存取 Cloud Run for Anthos 服務的 Endpoints 服務名稱。Endpoints 服務名稱的格式為網域名稱:

API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog

Endpoints 服務名稱會對應至網域名稱,因此必須遵循下列規則:

  • 只能使用小寫英文字母、數字、半形句號或破折號。
  • 開頭不得為破折號。
  • 不得包含底線。

例如:

grpc-boostore-api.endpoints.ESP_PROJECT_ID.cloud.goog

建立 gRPC API 規格

bookstore-grpc 範例包含了需要在本機複製及設定的檔案。

  1. 為 gRPC API 規格建立新的目錄,例如 my-anthos-grpc。然後 cd 至該目錄。

  2. 請複製代管 gRPC 用戶端程式碼的 git 存放區到新目錄:

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
  3. 變更您的工作目錄:

    cd python-docs-samples/endpoints/bookstore-grpc/

    請注意,這個目錄包含 bookstore.proto 檔案。這個檔案定義了 Bookstore 服務的 API。

  4. 從您的服務 .proto 檔案中建立獨立的 protobuf 描述元檔案:

    1. 在工作目錄下建立 generated_pb2 目錄。

    2. 使用 protoc 通訊協定緩衝區編譯器建立描述元檔案 api_descriptor.pb。在包含 bookstore.proto 的目錄中執行下列指令:

      python3 -m grpc_tools.protoc \
      --include_imports \
      --include_source_info \
      --proto_path=. \
      --descriptor_set_out=api_descriptor.pb \
      --python_out=generated_pb2 \
      --grpc_python_out=generated_pb2 \
      bookstore.proto

    在上述指令中,--proto_path 會設為目前的工作目錄。在您的 gRPC 建構環境中,如果您為 .proto 輸入檔案使用不同的目錄,請變更 --proto_path 以讓編譯器能夠搜尋您儲存 bookstore.proto 的目錄。

  5. 修改目前工作目錄 (含有 bookstore.proto 的相同目錄) 中的 api_config_anthos.yaml 檔案,將下列內容加入檔案:

    type: google.api.Service
    config_version: 3
    #
    # Name of the service configuration.
    #
    name: API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog
    #
    # API title to appear in the user interface (Google Cloud console).
    #
    title: Bookstore gRPC API In Cloud Run Anthors
    apis:
    - name: endpoints.examples.bookstore.Bookstore
    #
    # Create a DNS record to map your service name to IP address
    #
    endpoints:
      - name: API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog
        target: IP_ADDRESS
    #
    # Specify the backend address to route to
    #
    backend:
      rules:
        - selector: "*"
          address: grpc://GRPC_SERVICE.default.svc.cluster.local
          disable_auth: true
    #
    # API usage restrictions.
    #
    usage:
      rules:
      # ListShelves methods can be called without an API Key.
      - selector: endpoints.examples.bookstore.Bookstore.ListShelves
        allow_unregistered_calls: true

    縮排對 yaml 格式來說很重要。

  6. name 欄位中,指定用於存取 Cloud Run for Anthos 服務的 Endpoints API 網域名稱,格式如下:

    API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog

    例如:

    grpc-bookstore-api.endpoints.ESP_PROJECT_ID.cloud.goog

  7. endpoints 部分會在 cloud.goog 網域上為 Endpoints 服務註冊 DNS 項目,格式如下:

    endpoints:
      - name: API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog
        target: IP_ADDRESS

    IP_ADDRESS 是叢集的 istio-ingress 服務 IP 位址。如要判斷此 IP 位址:

    1. 前往 Cloud 控制台的「Google Kubernetes Engine」頁面:

      前往 Google Kubernetes Engine

    2. 按一下左側導覽面板中的「Services & Ingress」,即可顯示服務清單。

    3. 如果叢集版本為 1.15.3-gke.19 以上、1.14.3-gke.12 以上或 1.13.10-gke.8 以上,請向下捲動至 istio-ingress 服務。如要查看其他所有叢集版本,請向下捲動至 istio-ingressgateway 服務。

    4. 複製負載平衡器旁顯示的外部 IP 位址,但不包含通訊埠設定 (如有)。舉例來說,如果 IP 為 XX.XXX.XX.XXX:15020,請省略 :15020。請忽略列出的其他 IP 位址。

  8. backend 部分中的 address 欄位會使用 proto 配置 grpc:// 指定 Cloud Run「grpc-bookstore」服務的內部 DNS 名稱,並停用此服務的驗證機制:

    address: grpc://GRPC_SERVICE.default.svc.cluster.local
    disable_auth: true

    例如:

    address: grpc://grpc-bookstore.default.svc.cluster.local
    disable_auth: true

    這是必要的,因為從 ESPv2 對 Cloud Run for Anthos 服務的呼叫,是從叢集內部發出的內部呼叫,因此不需要驗證。

  9. 請注意 api_config_authos.yaml 檔案中的 title 屬性值:

    title: Bookstore gRPC API In Cloud Run Anthos

    部署設定後,title 屬性的值就會成為 Endpoints 服務的名稱。

  10. 儲存 gRPC API 文件。

如要瞭解 Endpoints 所需的 OpenAPI 文件欄位,請參閱「設定 Endpoints」一文。

部署 Endpoints 設定

如要部署 Endpoints 設定,請使用 gcloud endpoints services deploy 指令。這個指令會使用 Service Management 建立代管服務。

如何部署 Endpoints 設定:

  1. 確認您位於內含 gRPC 文件的目錄。

  2. 上傳設定並建立代管服務。

    gcloud endpoints services deploy api_descriptor.pb api_config_anthos.yaml \ 
      --project ESP_PROJECT_ID

    完成後,系統會建立新的 Endpoints 服務,並命名為您在 api_config_anthos.yaml 檔案的 name 欄位中指定的名稱。Endpoints 服務會根據您的 OpenAPI 文件進行設定。

    Service Management 在建立及設定 Endpoints 服務時,會將資訊輸出至終端機。部署完成後,您會看到類似以下的訊息:

    Service Configuration [CONFIG_ID] uploaded for service [API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog]

    CONFIG_ID 是部署作業建立的 Endpoints 服務設定 ID。例如:

    Service Configuration [2019-02-01r0] uploaded for service [grpc-bookstore-api.endpoints.ESP_PROJECT_ID.cloud.goog] 

    服務設定 ID 是由一個日期戳記和一個修訂版本編號所組成。如果您在同一天再次部署 api_config_anthos.yaml,服務設定 ID 中的修訂版本編號就會遞增。您可以在 Google Cloud 控制台的「Endpoints」>「Services」頁面中查看服務設定和部署記錄

    如果您收到錯誤訊息,請參閱排解 Endpoints 設定部署問題

檢查必要服務

Endpoints 和 ESP 至少需要啟用下列 Google 服務:
名稱 標題
servicemanagement.googleapis.com Service Management API
servicecontrol.googleapis.com Service Control API

在大多數情況下,gcloud endpoints services deploy 指令會啟用這些必要服務。不過在以下情況中,即便您成功執行 gcloud 指令,還是無法啟用必要服務:

  • 您使用 Terraform 之類的第三方應用程式,而其中未包含這些服務。

  • 您已將 Endpoints 設定部署至現有Google Cloud 專案,但在專案中已明確停用這些服務。

使用下列指令確認已啟用必要服務:

gcloud services list

如果必要的服務並未列出,請執行下列指令加以啟用:

gcloud services enable servicemanagement.googleapis.com
gcloud services enable servicecontrol.googleapis.com

並啟用 Endpoints 服務:

gcloud services enable ENDPOINTS_SERVICE_NAME

如要判斷 ENDPOINTS_SERVICE_NAME,您可以採取下列任一做法:

  • 部署 Endpoints 設定後,請前往 Cloud 控制台的「Endpoints」頁面。Service name 欄下方會列出可能的 ENDPOINTS_SERVICE_NAME 清單。

  • 針對 OpenAPI,ENDPOINTS_SERVICE_NAME 是您在 OpenAPI 規格 host 欄位中指定的值。針對 gRPC,ENDPOINTS_SERVICE_NAME 是您在 gRPC Endpoints 設定的 name 欄位中指定的值。

如要進一步瞭解 gcloud 指令,請參閱 gcloud 服務

建構新的 ESPv2 Knative 供應映像檔

將 Endpoints 服務設定建構至新的 ESPv2 Docker 映像檔。建立這個映像檔後,您就可以將其部署至叢集。

如要將服務設定建構至新的 ESPv2 Docker 映像檔,請按照下列步驟操作:

  1. 將這個指令碼下載到已安裝 gcloud CLI 的本機機器,並以以下方式執行:

    chmod +x gcloud_build_image 
    ./gcloud_build_image -s API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog \ 
    -c CONFIG_ID -p ESP_PROJECT_ID

    這個指令碼會使用 gcloud 指令下載服務設定,將服務設定建構為新的 ESPv2 映像檔,然後將新映像檔上傳至專案容器登錄。指令碼會自動使用最新的 ESPv2 版本,這可從輸出映像檔名稱中的 ESP_VERSION 看出。輸出圖片會上傳至:

    gcr.io/ESP_PROJECT_ID/endpoints-runtime-serverless:ESP_VERSION-API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog-CONFIG_ID

部署 ESPv2 Knative serving 映像檔

將 ESPv2 Knative serving 服務映像檔部署至叢集:

  1. 使用新映像檔部署 ESPv2 Knative 服務:

    gcloud run deploy ESP_V2_SERVICE_NAME \ 
      --image="gcr.io/ESP_PROJECT_ID/endpoints-runtime-serverless:API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog-CONFIG_ID" \ 
      --platform gke \
      --use-http2 \
      --project=ESP_PROJECT_ID

    針對 ESP_PROJECT_ID,請指定要用於 ESPv2 服務的名稱。在本例中,將 ESP_V2_SERVICE_NAME 設為 espv2

  2. 如果您要設定 Endpoints 以使用其他 ESPv2 啟動選項,例如啟用 CORS,您可以傳送 ESPv2_ARGS 環境變數中的引數:

    gcloud run deploy ESP_V2_SERVICE_NAME \
      --image="gcr.io/ESP_PROJECT_ID/endpoints-runtime-serverless:API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog-CONFIG_ID" \ 
      --set-env-vars=ESPv2_ARGS=--cors_preset=basic \ 
      --platform gke --use-http2 \
      --project ESP_PROJECT_ID

    如要進一步瞭解如何設定 ESPv2_ARGS 環境變數,包括可用選項清單和如何指定多個選項的資訊,請參閱「Extensible Service Proxy V2 標記」。

建立 ESPv2 Knative serving 服務的網域對應關係

如要在提出要求時省略 host 標頭,請為 ESPv2 服務新增網域對應:

  1. 前往 Cloud Run

  2. 選取「管理自訂網域」

  3. 選取「新增對應」

  4. 在下拉式選單中,選取「新增服務網域對應關係」

  5. 在「Add mapping」彈出式視窗的「Select a service to map to」欄位中,選取 ESPv2 服務。

  6. 在「Enter domain name」欄位中,指定要用來透過 Endpoints 存取 Knative 服務的網域名稱。例如,指定:

    API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog

    其中 API_NAME 是 Endpoints API 的名稱。在本例中,您可以使用「hello-api」:

    grpc-bookstore-api.endpoints.ESP_PROJECT_ID.cloud.goog

  7. 按一下「繼續」。系統會顯示對應項目的摘要。

  8. 選取「完成」即可儲存對應關係。

傳送要求至 API

如要傳送要求至範例 API,您可以使用以 Python 編寫的範例 gRPC 用戶端。

  1. 確認您位於內含 gRPC 文件的目錄,例如 api_config_anthos.yaml

  2. 安裝依附元件:

    pip3 install virtualenv
    virtualenv env
    source env/bin/activate
    pip3 install -r requirements.txt
  3. 傳送要求至範例 API:

    python3 bookstore_client.py --host API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog --port 80

    例如:

    python3 bookstore_client.py --host grpc-bookstore-api.endpoints.ESP_PROJECT_ID.cloud.goog --port 80

    如果一切運作正常,您應該會在表單中看到回應:

    ListShelves: shelves {
      id: 1
      theme: "Fiction"
    }
    shelves {
      id: 2
      theme: "Fantasy"
    }

如果您未取得成功的回應,請參閱排解回應錯誤一文。

您已在 Endpoints 中部署並測試了 API!

設定 Endpoints API 以使用 HTTPS

根據預設,Google Cloud 上的 Knative serving 會停用自動 TLS 支援功能。因此,在本例中,當您透過 ESPv2 存取 Endpoints API 時,會使用 HTTP 進行呼叫。

您可以設定 ESPv2 以支援使用 HTTPS 的請求。請注意,您必須在外部服務 ESPv2 上設定 HTTPS 支援功能,而非在內部後端服務「hello」上設定。

如要使用 ESPv2 支援 HTTPS,您必須:

  1. 擁有網域。如果沒有網域,可以向 Google 或其他網域供應商購買。

  2. 為 ESPv2 服務建立網域對應,並按照網域對應頁面中的操作說明,更新 DNS 記錄。

    如果您是從 Google Domains 取得網域,請將該網域用作 DNS 伺服器。否則,請使用 Cloud DNS 或您選擇的 DNS 伺服器。使用 Google Domains 的網域是最簡單的做法。

  3. 在 Endpoints OpenAPI 規格中:

    1. name 欄位設為參照您的網域,而非 *.cloud.goog

    2. 移除 endpoints 標記及其兩個子項屬性。

如需完整操作說明和教學課程,請參閱「啟用 HTTPS 和自動傳輸層安全標準 (TLS) 憑證」。

追蹤 API 活動

  1. 在 Google Cloud 主控台的「Endpoints」 >「Service」(服務) 頁面上,查看 API 的活動圖表。

    查看 Endpoints 活動圖表

    要求可能需要一些時間才能反映在圖表中。

  2. 在「Logs Explorer」(記錄檔探索工具) 頁面中查看您的 API 要求記錄。

    查看 Endpoints 要求記錄

清除所用資源

如要避免系統向您的 Google Cloud 帳戶收取您在本頁所用資源的費用,請按照下列步驟操作。

如要瞭解如何停用本教學課程使用的服務,請參閱刪除 API 和 API 執行個體一文。

後續步驟