Extensible Service Proxy V2 (ESPv2) 是一个基于 Envoy 的代理,通过该代理,Cloud Endpoints 可以提供 API 管理功能。ESPv2 取代了基于 NGINX 的 Extensible Service Proxy (ESP)。
本文档介绍如何将现有 Endpoints API 部署从 ESP 迁移到 ESPv2。
准备工作
在开始迁移之前,请考虑以下不受支持的用例和重大 API 更改。
ESPv2 不受支持的使用场景
不支持 App Engine 柔性环境
App Engine 柔性环境具有内置的 Endpoints 支持,可通过在应用的
app.yaml
文件中设置endpoints_api_service
来启用。此内置 Endpoints 实现仅支持 ESP;因此无法迁移到 ESPv2。如果要将 ESPv2 与 App Engine 柔性环境一起使用,请在
app.yaml
中停用endpoints_api_service
。您可以将 ESPv2 部署为单独的 Cloud Run 服务,用于在 App Engine 柔性环境中管理您的应用。部署的运作方式与 ESPv2 用于支持 App Engine 标准环境的方式相同。不支持自定义 NGINX 配置
ESPv2 是一种基于 Envoy 的代理。它无法支持自定义 NGINX 代理配置。如果您的 ESP 配置使用
-n
或--nginx_config
标志,您的实现可能依赖于无法轻易迁移到 ESPv2 的自定义 NGINX 配置。
重大更改
- 更改了
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
将 ESPv2 与无服务器平台(Cloud Run、Cloud Run Functions、App Engine)搭配使用所需的迁移步骤与非无服务器平台(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 Functions 或 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
和可用的启动标志,请参阅 Extensible Service Proxy V2 启动选项。
ESP 和 ESPv2 之间的启动标志更改
与 Extensible Service 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.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.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 调用除外)的超时,以秒为单位。 |
--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 查找系列的 Envoy 特定配置。 |
--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 启动标志,请参阅 Extensible Service 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 会向后端 API 发送 X-Endpoint-API-UserInfo
标头中的身份验证结果。我们建议您使用此标头,而不是原始 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 响应正文格式
如果 ESP 或 ESPv2 拒绝 HTTP 请求,则响应正文将包含状态代码和 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
字段。
后续步骤
了解: