透過 ESPv2 設定 Knative 服務適用的 Cloud Endpoints gRPC

本頁面說明如何設定 Knative 服務專用的 Cloud Endpoints。Endpoints 使用可擴充服務 Proxy V2 (ESPv2) 做為 API 閘道。如要為 Knative serving 提供 API 管理,您需要先在 GKE 叢集上執行的 Knative serving 部署預先建構的 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 serving 映像檔。請參閱部署 ESPv2 Cloud Run 映像檔

  8. 建立網域對應至 ESPv2 Knative serving 服務。

  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 指令列

    如要設定 gcloud CLI,以便使用 Knative Serving for Anthos:

    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 serving 使用:

  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. 修改目前工作目錄中的 api_config_anthos.yaml 檔案 (與 bookstore.proto 所在的目錄相同),在檔案中加入下列內容:

    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」(服務與 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 欄位會指定 Cloud Run「grpc-bookstore」服務的內部 DNS 名稱 (使用 proto 結構 grpc://),並停用對這項服務的驗證:

    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 欄位中指定的名稱。系統會根據您的 OpenAPI 文件設定 Endpoints 服務。

    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」頁面。「服務名稱」欄下方會顯示可能的 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 serving 服務:

    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. 在「輸入網域名稱」欄位中,指定要透過 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. 如要查看 API 活動圖表,請前往 Google Cloud 主控台的「Endpoints」 >「Service」(服務) 頁面。

    查看 Endpoints 活動圖表

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

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

    查看 Endpoints 要求記錄

清除所用資源

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

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

後續步驟