遷移至可擴充服務 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 標記,您的實作可能會依賴無法輕鬆遷移至 ESPv2 的自訂 NGINX 設定。

破壞性變更

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

  • 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) 中使用 ESPv2 所需的步驟不同。

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

非無伺服器平台: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

系統會使用 docker run 指令,將 ESP 和 ESPv2 部署至 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 單一 Envoy 事件監聽器連接埠可在 ESPv2 中支援 HTTP、HTTP2 和 SSL。您不需要指定不同的通訊埠。
--ssl_server_cert_path --ssl_port 使用 --ssl_server_cert_path 時,ESPv2 會使用 server.keyserver.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.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_report_timeout_ms 設定 Google Service Control Report 呼叫的逾時時間。
--service_control_quota_timeout_ms 設定 Google Service Control 配額呼叫的逾時時間。
--service_control_check_retries 指定 Google 服務控制檢查呼叫的重試次數。
--service_control_report_retries 指定 Google Service Control Report 呼叫的重試次數。
--service_control_quota_retries 指定 Google Service Control 配額呼叫的重試次數。
--backend_dns_lookup_family Envoy 專屬設定,用於定義所有後端的 DNS 查詢系列。
--disable_tracing 用於停用所有追蹤記錄的整體標記。
--tracing_project_id 用於設定擁有追蹤記錄資料的專案 ID。
--tracing_incoming_context 用於指定傳入的追蹤記錄內容。
--tracing_outgoing_context 用於指定 outgoingtrace 內容。

已淘汰的旗標

已淘汰的旗標 說明
--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 欄位。

後續步驟

瞭解下列內容: