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

本頁面說明如何設定 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. 部署範例 Knative serving 服務。

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

  5. 部署 OpenAPI 文件以建立代管服務。請參閱部署 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. 下載並安裝 Google Cloud SDK
  8. 如果您要將要求傳送到已部署的範例服務,請安裝 cURL
  9. 設定 gcloud 指令列

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

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

      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 \ 
      --enable-stackdriver-kubernetes

    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

部署 Knative 服務容器範例

如要將「hello」Knative serving 範例容器部署至您剛才建立的叢集:

  1. 前往 Cloud Run

  2. 按一下「Create service」(建立服務)

  3. 選取「Knative serving」做為開發平台。

  4. 在可用叢集下拉式選單中,選取剛剛建立的叢集。

  5. 使用「hello」做為服務名稱。您可以使用其他名稱,但請記下該名稱,因為您之後會用到。此處的操作說明假設您使用的是「hello」

  6. 在「連線」下方選取「內部」,這樣外部就無法存取該服務。

  7. 點選「下一步」即可繼續前往服務建立表單的第二頁。

  8. gcr.io/cloudrun/hello 指定為容器映像檔網址

  9. 按一下「建立」,將映像檔部署到 Knative 服務,然後等待部署作業完成。

    完成後,畫面上會顯示「修訂版本」畫面。請注意,部署的服務網址為:

    http://hello.default.svc.cluster.local

    建立內部服務時,GKE 會建立 DNS 名稱,但只能解析來自叢集內的請求,無法解析外部請求。您無法從叢集外部存取這個連結。詳情請參閱「Cloud Run 服務」。

  10. 如要驗證服務是否能使用 cURL 正常運作,請建立從電腦到叢集的通道。如要查看這些操作說明,請在「修訂」畫面上按一下網址右側的 圖示:

    「修訂版本」畫面。

  11. 系統會開啟一個面板,顯示用於存取內部服務的兩個指令。您必須在兩個不同的終端機視窗中執行這些指令,因為第一個指令會設定第二個指令使用的通訊埠轉送。

    執行 cURL 指令時,您應該會看到服務的輸出內容,格式如下:

    <!doctype html>
    <html lang=en> 
    <head> 
    <meta charset=utf-8> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <title>Congratulations | Cloud Run</title> 
    ...

設定 Endpoints

您必須提供符合 OpenAPI 規範 v2.0 的 OpenAPI 文件,此文件須說明您後端服務的介面以及所有驗證需求。此外,您也必須加入內含各服務網址的 Google 專用欄位,這樣 ESPv2 才能取得叫用服務所需的資訊。如果您還不熟悉 OpenAPI,請參閱 OpenAPI 總覽瞭解詳情。

關於設定 OpenAPI 規格的主機欄位

在 OpenAPI 規格檔案的 host 欄位中,您可以指定用於存取 Knative 服務服務的 Endpoints 服務名稱。Endpoints 服務名稱的格式為網域名稱:

API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog

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

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

例如:

hello-api.endpoints.ESP_PROJECT_ID.cloud.goog

建立 OpenAPI 規格

  1. 建立名為 openapi-run-anthos.yaml 的文字檔案。

  2. 您的 Knative 服務後端服務會定義於 openapi-run-anthos.yaml 檔案最上方的 x-google-backend 定義之中,例如:

    swagger: '2.0' 
    info:
      title: Cloud Endpoints + Cloud Run
      description: Sample API on Cloud Endpoints with a Cloud Run backend
      version: 1.0.0 
    host: API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog
    x-google-endpoints:
    - name: API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog
      target: "INGRESS-IP"
    schemes:
      - https
    produces:
      - application/json
    x-google-backend:
      address: http://hello.default.svc.cluster.local
      disable_auth: true
    paths:
      /hello:
        get:
          summary: Greet a user
          operationId: hello
          responses:
            '200':
              description: A successful response
              schema:
                type: string

    縮排對 YAML 格式來說很重要。例如,host 欄位必須與 info 位於相同層級。

  3. host 欄位中,指定用於存取 Knative 服務的 Endpoints API 網域名稱,格式如下:

    API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog

    例如:

    hello-api.endpoints.ESP_PROJECT_ID.cloud.goog
  4. x-google-endpoints 擴充功能會在 cloud.goog 網域上為 Endpoints 服務註冊 DNS 項目,格式如下:

    x-google-endpoints: 
      - name: "API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog"
      target: "IP_ADDRESS"

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

    1. 前往 Google 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 位址。

  5. x-google-backend 部分的 address 欄位中,指定後端 Knative 服務「hello」的內部 DNS 名稱,並停用對此服務的驗證。這是必要的,因為 ESPv2 對 Knative 服務器服務的呼叫是從叢集內部發出的內部呼叫,因此不需要驗證。

  6. 請注意 openapi-run-anthos.yaml 檔案中的 title 屬性值:

    title: Cloud Endpoints + Cloud Run 
  7. 部署設定後,title 屬性的值就會成為 Endpoints 服務的名稱。

  8. 儲存 OpenAPI 文件。

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

部署 Endpoints 設定

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

如何部署 Endpoints 設定:

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

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

    gcloud endpoints services deploy openapi-run-anthos.yaml \ 
      --project ESP_PROJECT_ID

    完成後,系統會建立新的 Endpoints 服務,並命名為您在 openapi-run-anthos.yaml 檔案的 host 欄位中指定的名稱。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 [hello-api.endpoints.ESP_PROJECT_ID.cloud.goog] 

    服務設定 ID 是由一個日期戳記和一個修訂版本編號所組成。如果您在同一天再次部署 openapi-run-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:ESP_VERSION-API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog-CONFIG_ID" \ 
      --platform gke \ 
      --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:ESP_VERSION-API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog-CONFIG_ID" \ 
      --set-env-vars=ESPv2_ARGS=--cors_preset=basic \ 
      --platform gke \ 
      --project ESP_PROJECT_ID

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

ESPv2 服務會以外部服務的形式部署,也就是說,您可以使用以下格式的 cURL 指令存取這項服務:

curl -H "Host: espv2.default.example.com" http://IP_ADDRESS

其中 IP_ADDRESS 是叢集的 istio-ingress 服務 IP 位址。

如要查看這個 cURL 指令,請在已部署的 ESPv2 Knative 服務服務的「Revisions」畫面中,按一下 ESPv2 網址右側的「IMAGE」圖示。

您現在可以透過 ESPv2 服務,對 Endpoints 服務發出 API 呼叫。舉例來說,如要向路徑為 /hello 的 Endpoints 服務提出要求,您可以使用以下格式提出要求:

curl -H "Host: espv2.default.example.com" http://IP_ADDRESS/hello

不過,在每個 Endpoints 服務要求中指定 host 標頭並不方便使用者。在下一節中,您將設定網域對應,方便透過 ESPv2 呼叫端點服務。

建立 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」:

    hello-api.endpoints.ESP_PROJECT_ID.cloud.goog

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

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

傳送要求至 API

使用 cURL 將 HTTP 要求傳送至 API:

curl -X GET "http://hello-api.endpoints.ESP_PROJECT_ID.cloud.goog/hello"

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

設定 Endpoints API 以使用 HTTPS

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

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

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

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

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

    如果您是透過 Cloud Domains 取得網域,請使用 Cloud DNS 或自選的 DNS 伺服器。使用 Cloud Domains 中的網域是最簡單的做法。

  3. 在 Endpoints OpenAPI 規格中:

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

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

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

追蹤 API 活動

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

    查看 Endpoints 活動圖表

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

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

清除所用資源

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

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

後續步驟