遷移至可擴充服務 Proxy 第 2 版

可擴充服務 Proxy V2 (ESPv2) 是一種Envoy 型 Proxy,可讓 Cloud Endpoints 提供 API 管理功能。ESPv2 會取代以 NGINX 為基礎的可擴充服務 Proxy (ESP)

本文說明如何將現有的 Endpoints API 部署作業從 ESP 遷移至 ESPv2。

事前準備

開始遷移前,請先瞭解以下不支援的使用案例和 API 重大變更。

ESPv2 不支援的用途

  • 不支援 App Engine 彈性環境

    App Engine 彈性環境內建 Endpoints 支援功能,只要在應用程式的 app.yaml 檔案中設定 endpoints_api_service,即可啟用這項功能。這個內建的 Endpoints 實作方式僅支援 ESP,無法遷移至 ESPv2。

    如要在 App Engine 彈性環境中使用 ESPv2,請在 app.yaml 中停用 endpoints_api_service。您可以將 ESPv2 部署為獨立的 Cloud Run 服務,用於管理 App Engine 彈性環境中的應用程式。部署方式與使用 ESPv2 支援 App Engine 標準環境相同。

  • 不支援自訂 NGINX 設定

    ESPv2 是以 Envoy 為基礎的 Proxy。無法支援自訂 NGINX Proxy 設定。如果 ESP 設定使用 -n--nginx_config 標記,實作方式可能依賴自訂 NGINX 設定,無法輕鬆遷移至 ESPv2。

破壞性變更

  • X-Endpoint-API-UserInfo 標頭資料格式已變更。如果您的應用程式使用這個標頭,就必須改用新格式。詳情請參閱「在後端服務中處理 JWT」。
  • 如果要求需要 API 金鑰,ESP 會將含有消費者專案 ID 的 X-Endpoint-API-Project-ID 標頭傳送至後端應用程式。ESPv2 會使用兩個不同的標頭 (X-Endpoint-API-Consumer-TypeX-Endpoint-API-Consumer-Number) 傳送必要詳細資料。如要進一步瞭解這些標頭傳送的 Consumer-TypeConsumer-Number,請參閱 Service Infrastructure 參考說明文件

  • HTTP 錯誤回應主體格式已變更。當 ESPv2 拒絕 HTTP 要求時,會以新格式產生錯誤回應主體。如果您的實作項目使用用戶端程式碼處理 HTTP 錯誤 JSON 回應主體,請務必更新用戶端程式碼。詳情請參閱「HTTP 錯誤 JSON 回應內容」。

  • ESPv2 提供新的啟動標記,並已淘汰或取代部分 ESP 標記。請參閱「ESP 和 ESPv2 之間的啟動標記變更」。

將 Endpoints API 遷移至 ESPv2

搭配無伺服器平台 (Cloud Run、Cloud Run 函式、App Engine) 使用 ESPv2 時,所需的遷移步驟與非無伺服器平台 (Google Kubernetes Engine、Compute Engine 和 Kubernetes) 不同。

以下說明各平台類型所需的遷移步驟:

非無伺服器平台:GKE、Compute Engine、Kubernetes

ESPv2 是 ESP 的替代方案,在大多數設定中,您只需要更新 Docker 映像檔標記。

不過,如果您使用下列項目設定 ESP,可能需要調整啟動標記:

  • 透過 --http_porthttp2_port 和/或 --ssl_port 標記指定多個連接埠。
  • SSLDNSClient IP 或其他不常用的旗標。

ESPv2 提供新的啟動標記,部分 ESP 標記已淘汰或取代。詳情請參閱「ESP 和 ESPv2 之間的啟動標記異動」。

GKE 和 Kubernetes

如要遷移 GKE 和 Kubernetes 的 Endpoints 設定,請在部署 yaml 檔案中,將 ESP 映像檔標記從 :1 變更為 :2。例如:

- name: esp
  image: gcr.io/endpoints-release/endpoints-runtime:2
  args: [
    "--http_port=8081",
    "--backend=127.0.0.1:8080",
    "--service=SERVICE_NAME",
    "--rollout_strategy=managed",
  ]

Compute Engine

ESP 和 ESPv2 都是使用 docker run 指令部署至 Docker 容器。如要將 Compute Engine 適用的 Endpoints 遷移至 ESPv2,請在指令中將 Docker 映像檔標記從 :1 更新為 :2。例如:

sudo docker run \
    --detach \
    DOCKER_ARGUMENTS \
    gcr.io/endpoints-release/endpoints-runtime:2 \
    --service=SERVICE_NAME \
    --rollout_strategy=managed \
    --backend=YOUR_API_CONTAINER_NAME:8080

無伺服器平台 (Cloud Run、Cloud Functions、App Engine)

對於無伺服器平台,ESPv2 會部署為 Cloud Run 服務,管理在 Cloud Run、Cloud Function 或 App Engine 上執行的應用程式。如要將 Endpoints 遷移至 ESPv2,您必須將現有的 Endpoints 服務設定建構為新的 ESPv2 Docker 映像檔,然後將該映像檔部署至 ESPv2 Cloud Run 服務。

ESP 和 ESPv2 的部署步驟相同,但下列詳細資料除外:

  • 將 ESPv2 部署至 Cloud Run 時,ESPv2 中的圖片標記應從 :1 變更為 :2。例如:

    gcloud run deploy CLOUD_RUN_SERVICE_NAME \
    --image="gcr.io/endpoints-release/endpoints-runtime-serverless:2" \
    --allow-unauthenticated \
    --platform managed \
    --project=ESP_PROJECT_ID  
  • gcloud_build_image 指令碼是從其他位置下載。 並以 gcr.io/endpoints-release/endpoints-runtime-serverless:2 做為基本映像檔。

  • 環境變數用於指定啟動旗標。ESP 的變數名稱為 ESP_ARGS。ESPv2 的名稱為 ESPv2_ARGS。 如要進一步瞭解如何設定 ESPv2_ARGS 和可用的啟動標記,請參閱「可擴充服務 Proxy V2 啟動選項」。

ESP 和 ESPv2 之間的啟動標記變更

與可擴充服務 Proxy 相同,部署 ESPv2 服務時,您可以指定設定標記。從以 NGINX 為基礎的 ESP 變更為以 Envoy 為基礎的 ESPv2 後,部分標記已淘汰或取代,並新增了標記。本節將使用三個表格說明變更內容:

  • 表 1 說明取代已淘汰旗標的新旗標。
  • 表 2 說明瞭新旗標。
  • 表 3 說明已淘汰的旗標。

已取代的旗標

新旗標 已更換旗標 說明
--listener_port --http_port--http2_port--ssl_port 在 ESPv2 中,單一 Envoy 接聽埠支援 http、http2 和 SSL。不需要指定個別通訊埠。
--ssl_server_cert_path --ssl_port 使用 --ssl_server_cert_path 時,ESPv2 會使用 server.keyserver.key 檔案中的憑證。server.crt使用 ESPv2 時,您可以指定 /etc/nginx/ssl 以外的伺服器憑證路徑。這個旗標會取代 ESP 中的 --ssl_port,後者會使用 /etc/nginx/ssl/nginx.key/etc/nginx/ssl/nginx.crt 檔案路徑中的憑證。
--ssl_backend_client_cert_path --tls_mutual_auth--enable_grpc_backend_ssl--grpc_backend_ssl_private_key_file--grpc_backend_ssl_cert_chain_file 使用 --ssl_backend_client_cert_path 時,ESPv2 會使用 client.keyclient.key 檔案中的憑證。client.crt使用 ESPv2 時,您可以指定 /etc/nginx/ssl 以外的用戶端憑證路徑。這個旗標會取代 ESP 中的 --tls_mutual_auth,後者會使用 /etc/nginx/ssl/backend.key/etc/nginx/ssl/backend.crt 檔案路徑中的憑證。
--ssl_backend_client_root_certs_file --grpc_backend_ssl_root_certs_file 使用 ESPv2 時,--ssl_backend_client_root_certs_file 適用於所有後端。這個旗標會取代 ESP 中的 --grpc_backend_ssl_root_certs_file,後者僅適用於 gRPC 後端。
--ssl_minimum_protocol--ssl_maximum_protocol --ssl_protocols 在 ESP 中使用 --ssl_protocols 時,您必須列出所有所需的 SSL 通訊協定。在 ESPv2 中,您可以指定通訊協定的最小值和最大值。
--envoy_use_remote_address--envoy_xff_num_trusted_hops --xff_trusted_proxy_list--client_ip_header--client_ip_position Envoy 需要 use_remote_addressxff_num_trusted_hops,才能設定用戶端 IP 位址擷取
--dns_resolver_addresses --dns 替換標記的行為相同,但預設值不同。 ESP 會使用 8.8.8.8 做為 DNS 解析器。ESPv2 會使用 /etc/resolv.conf 中設定的 DNS 解析器。
--service_account_key --non_gcp--service_account_key 在 ESP 中,--service_account_key 旗標會隱含允許部署至 GCP 以外的平台。這可防止 ESP 呼叫執行個體中繼資料伺服器 在 ESPv2 中,這項隱含行為會拆分成另一個旗標。遷移時可能需要新增 --non_gcp,否則 ESPv2 無法在 GCP 以外的平台啟動。

新旗標

新旗標 說明
--http_request_timeout_s 以秒為單位,為所有 http/https 遠端呼叫設定逾時時間,後端呼叫和 Google 服務控制呼叫除外。
--service_control_check_timeout_ms 以毫秒為單位,設定 Google Service Control Check 呼叫的逾時時間。
--service_control_report_timeout_ms 設定 Google Service Control Report 呼叫的逾時時間。
--service_control_quota_timeout_ms 設定 Google Service Control Quota 呼叫的逾時時間。
--service_control_check_retries 指定 Google Service Control Check 呼叫的重試次數。
--service_control_report_retries 指定 Google Service Control Report 呼叫的重試次數。
--service_control_quota_retries 指定 Google Service Control Quota 呼叫的重試次數。
--backend_dns_lookup_family 用於定義所有後端的 DNS 查閱系列。
--disable_tracing 用於停用所有追蹤記錄的整體旗標。
--tracing_project_id 用於設定擁有追蹤記錄資料的專案 ID。
--tracing_incoming_context 用於指定傳入的追蹤記錄情境。
--tracing_outgoing_context 用於指定外送追蹤記錄內容。

已淘汰的旗標

已淘汰的旗標 說明
--enable_websocket Envoy 預設會啟用 WebSocket。
--experimental_proxy_backend_host_header 不支援。
--allow_invalid_headers 不支援。這是 NGINX 設定:ignore_invalid_headers。如果 HTTP 要求含有無效的標頭名稱,ESPv2 會拒絕該要求。有效的標頭名稱由英文字母、數字、連字號和底線 (可能) 組成。在 ESPv2 中,旗標 --underscores_in_headers 可決定標頭中是否允許使用底線。
--client_max_body_size NGINX 設定,不支援。
--client_body_buffer_size NGINX 設定,不支援。
--large_client_header_buffers NGINX 設定,不支援。
--keepalive_timeout NGINX 設定,不支援。
--client_body_timeout NGINX 設定,不支援。
--rewrite 不支援。
--experimental_enable_multiple_api_configs 不支援。
--enable_backend_routing 不需要,無伺服器平台會自動啟用後端路由。
--rollout_fetch_throttle_window_in_s 不需要。
--nginx_config 不支援。

如要進一步瞭解 ESPv2 啟動標記,請參閱「可擴充服務 Proxy V2 啟動選項」。如需其他一般範例和旗標的說明文字,請參閱 GitHub 存放區

預設 JWT 位置

根據預設,JWT 會透過 Authorization 標頭 (以「Bearer 」為前置字元)、X-Goog-Iap-Jwt-Assertion 標頭或 access_token 查詢參數傳遞。ESP 和 ESPv2 都支援這些位置。使用 ESP 時,您也可以在 Authorization 標頭中傳遞 JWT (不含前置字元)。不過,ESPv2 不支援這個位置。

如要在遷移至 ESPv2 後,繼續使用 Authorization 標頭 (不含前置字元) 傳遞 JWT,可以採取下列做法:

x-google-jwt-locations:
- header: "Authorization"
jwt_locations:
- header: Authorization

在後端服務中處理 JWT

使用 JWT 進行驗證時,ESPv2 和 ESP 會將 X-Endpoint-API-UserInfo 標頭中的驗證結果傳送至後端 API。建議您使用這個標頭,不要使用原始的 Authorization 標頭,因為原始的 Authorization 標頭可能會在無伺服器平台中遭到修改。

X-Endpoint-API-UserInfo 標頭包含 Base64Url 編碼的 JSON 物件。不過,格式已從 ESP 變更為 ESPv2。

如果是 ESPv2,X-Endpoint-API-UserInfo 標頭會包含原始 JWT 酬載,不會經過任何修改

在 ESP 中,X-Endpoint-API-UserInfo 標頭包含 JWT 酬載,以及 ESP 新增的幾個特定欄位。ESP 會將 idissueremailaudiences 欄位新增至 JSON 物件。此外,還會新增 claims 欄位,納入原始 JWT 酬載。

# ESPv1 X-Endpoint-API-UserInfo header value
{
  "id": "extracted from 'sub' field",
  "issuer": "extracted from 'iss' field",
  "email": "extracted from 'email' field",
  # The following "audiences" is extracted from 'aud' field.
  # The 'aud' field may have multiple audiences delimited by coma. e.g. "aud: aud1,aud2".
  # but the following "audiences" is always a JSON array.
  "audiences": ["aud1", "aud2"],
  "claims": {
     Original JWT payload
   }
}

以下範例說明差異,所有內容都經過 base64url 解碼。

# This is an example of the original JWT payload:
{
  &quotiss&quot: &quothttps://accounts.google.com&quot,
  &quotemail&quot: &quotabcdefg123456@gmail.com&quot,
  &quotsub&quot: &quot1234567890123456789&quot,
  &quotaud&quot: &quotxyz1.example.com,xyz2.example.com&quot,
  &quotfoo&quot: &quotfoo.foo.foo.foo&quot,
  &quotbar&quot: &quotbar.bar.bar.bar&quot,
  &quotazp&quot: &quot98765432109876543210&quot,
  &quotexp&quot: &quot1642809446&quot,
  &quotiat&quot: &quot1642805846&quot
}

# This is an example of the `X-Endpoint-API-UserInfo` header from ESPv2
# extracted from above JWT payload.
{
  &quotiss&quot: &quothttps://accounts.google.com&quot,
  &quotemail&quot: &quotabcdefg123456@gmail.com&quot,
  &quotsub&quot: &quot1234567890123456789&quot,
  &quotaud&quot: &quotxyz1.example.com,xyz2.example.com&quot,
  &quotfoo&quot: &quotfoo.foo.foo.foo&quot,
  &quotbar&quot: &quotbar.bar.bar.bar&quot,
  &quotazp&quot: &quot98765432109876543210&quot,
  &quotexp&quot: &quot1642809446&quot,
  &quotiat&quot: &quot1642805846&quot
}

# This is an example of the `X-Endpoint-API-UserInfo` header from ESP
# extracted from above JWT payload.
{
  &quotid&quot:&quot1234567890123456789&quot,
  &quotissuer&quot: &quothttps://accounts.google.com&quot,
  &quotemail&quot: &quotabcdefg123456@gmail.com&quot,
  &quotaudiences&quot: [
    &quotxyz1.example.com&quot
    &quotxyz2.example.com&quot
  ],
  &quotclaims&quot: {
    &quotiss&quot: &quothttps://accounts.google.com&quot,
    &quotemail&quot: &quotabcdefg123456@gmail.com&quot,
    &quotsub&quot: &quot1234567890123456789&quot,
    &quotaud&quot: &quotxyz1.example.com,xyz2.example.com&quot,
    &quotfoo&quot: &quotfoo.foo.foo.foo&quot,
    &quotbar&quot: &quotbar.bar.bar.bar&quot,
    &quotazp&quot: &quot98765432109876543210&quot,
    &quotexp&quot: &quot1642809446&quot,
    &quotiat&quot: &quot1642805846&quot
  }
}

如要進一步瞭解如何搭配驗證功能使用 JWT,請參閱「使用自訂方法來驗證使用者」和「服務之間的驗證」。

錯誤 JSON 回應主體格式

如果 HTTP 要求遭到 ESP 或 ESPv2 拒絕,回應主體會包含 JSON 格式的狀態碼和錯誤訊息。ESPv2 的回應內容格式已變更,如下列範例所示:

ESP 傳回的錯誤回應內文

{
 "code": 5,
 "message": "Method does not exist.",
 "details": [
  {
   "@type": "type.googleapis.com/google.rpc.DebugInfo",
   "stackEntries": [],
   "detail": "service_control"
  }
 ]
}

ESPv2 傳回的錯誤回應主體

{
 "code": 400,
 "message": "Method does not exist.",
}

主要有兩點不同:

  • 在 ESPv2 中,code 欄位包含的是 HTTP 狀態碼,而不是 ESP 中的 RPC 狀態碼
  • ESPv2 中的錯誤回應主體不含 details 欄位。

後續步驟

瞭解下列內容: