可擴充服務 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-Type和X-Endpoint-API-Consumer-Number) 傳送必要詳細資料。如要進一步瞭解這些標頭傳送的Consumer-Type和Consumer-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_port、http2_port和/或--ssl_port標記指定多個連接埠。 SSL、DNS、Client 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 後,部分標記已淘汰或取代,並新增了標記。本節將使用三個表格說明變更內容:
已取代的旗標
| 新旗標 | 已更換旗標 | 說明 | |
|---|---|---|---|
--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.key 和 server.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.key 和 client.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_address 和 xff_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,可以採取下列做法:
- 在 openAPI 檔案中設定 x-google-jwt-locations (適用於 HTTP 後端使用者):
x-google-jwt-locations: - header: "Authorization"
- 在 gRPC yaml 檔案中設定 Authentication.providers.jwt_locations (適用於 gRPC 後端使用者):
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 會將 id、issuer、email 和 audiences 欄位新增至 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: { "iss": "https://accounts.google.com", "email": "abcdefg123456@gmail.com", "sub": "1234567890123456789", "aud": "xyz1.example.com,xyz2.example.com", "foo": "foo.foo.foo.foo", "bar": "bar.bar.bar.bar", "azp": "98765432109876543210", "exp": "1642809446", "iat": "1642805846" } # This is an example of the `X-Endpoint-API-UserInfo` header from ESPv2 # extracted from above JWT payload. { "iss": "https://accounts.google.com", "email": "abcdefg123456@gmail.com", "sub": "1234567890123456789", "aud": "xyz1.example.com,xyz2.example.com", "foo": "foo.foo.foo.foo", "bar": "bar.bar.bar.bar", "azp": "98765432109876543210", "exp": "1642809446", "iat": "1642805846" } # This is an example of the `X-Endpoint-API-UserInfo` header from ESP # extracted from above JWT payload. { "id":"1234567890123456789", "issuer": "https://accounts.google.com", "email": "abcdefg123456@gmail.com", "audiences": [ "xyz1.example.com" "xyz2.example.com" ], "claims": { "iss": "https://accounts.google.com", "email": "abcdefg123456@gmail.com", "sub": "1234567890123456789", "aud": "xyz1.example.com,xyz2.example.com", "foo": "foo.foo.foo.foo", "bar": "bar.bar.bar.bar", "azp": "98765432109876543210", "exp": "1642809446", "iat": "1642805846" } }
如要進一步瞭解如何搭配驗證功能使用 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欄位。
後續步驟
瞭解下列內容: