El proxy de servicios extensible V2 (ESPv2) es un proxy basado en Envoy que permite a Cloud Endpoints proporcionar funciones de gestión de APIs. ESPv2 sustituye al proxy de servicios extensible (ESP) basado en NGINX.
En este documento se describe cómo migrar una implementación de API de Endpoints de ESP a ESPv2.
Antes de empezar
Antes de empezar la migración, ten en cuenta los casos prácticos no admitidos y los cambios de API que suponen un cambio radical que se describen a continuación.
Casos prácticos no admitidos de ESPv2
No se admite el entorno flexible de App Engine
El entorno flexible de App Engine tiene compatibilidad integrada con Endpoints, que se habilita definiendo
endpoints_api_service
en el archivoapp.yaml
de la aplicación. Esta implementación de Endpoints integrada solo admite ESP y no se puede migrar a ESPv2.Si quieres usar ESPv2 con el entorno flexible de App Engine, inhabilita
endpoints_api_service
enapp.yaml
. Puedes desplegar ESPv2 como un servicio de Cloud Run independiente que se usa para gestionar tu aplicación en el entorno flexible de App Engine. El despliegue funciona de la misma forma que ESPv2 se usa para admitir el entorno estándar de App Engine.No se admite la configuración personalizada de NGINX
ESPv2 es un proxy basado en Envoy. No puede admitir configuraciones de proxy NGINX personalizadas. Si tu configuración de ESP usa las marcas
-n
o--nginx_config
, es posible que tu implementación dependa de una configuración de NGINX personalizada que no se pueda migrar fácilmente a ESPv2.
Puntos de ruptura
- Se ha cambiado el formato de los datos del encabezado
X-Endpoint-API-UserInfo
. Si tu aplicación usa este encabezado, debes cambiarlo para que use el nuevo formato. Consulta más información en Gestionar JWTs en el servicio backend. Si se necesita una clave de API para una solicitud, ESP envía el encabezado
X-Endpoint-API-Project-ID
con el ID del proyecto del consumidor a la aplicación backend. ESPv2 usa dos encabezados diferentes,X-Endpoint-API-Consumer-Type
yX-Endpoint-API-Consumer-Number
, para enviar los detalles necesarios. Consulta la documentación de referencia de Service Infrastructure para obtener más información sobre los valores deConsumer-Type
yConsumer-Number
que se envían con estos encabezados.Se ha cambiado el formato del cuerpo de la respuesta de error HTTP. Cuando ESPv2 rechaza una solicitud HTTP, genera un cuerpo de respuesta de error en un nuevo formato. Si tu implementación usa código de cliente para procesar el cuerpo de la respuesta JSON de error HTTP, debes actualizar el código de cliente. Consulta más detalles en el artículo Cuerpo de la respuesta JSON de error HTTP.
Hay nuevas marcas de inicio disponibles y algunas marcas de ESP se han retirado o sustituido en ESPv2. Consulta Cambios en las marcas de inicio entre ESP y ESPv2.
Migrar las APIs de Endpoints para usar ESPv2
Los pasos de migración necesarios para usar ESPv2 con plataformas sin servidor (Cloud Run, funciones de Cloud Run y App Engine) son diferentes de los pasos necesarios para plataformas que no son sin servidor (Google Kubernetes Engine, Compute Engine y Kubernetes).
A continuación se describen los pasos de migración necesarios para cada tipo de plataforma:
Plataformas sin servidor: GKE, Compute Engine y Kubernetes
ESPv2 es un sustituto directo de ESP. En la mayoría de las configuraciones, solo tiene que actualizar la etiqueta de la imagen de Docker.
Sin embargo, es posible que tengas que ajustar las marcas de inicio si has configurado ESP con lo siguiente:
- Más de un puerto mediante las marcas
--http_port
,http2_port
o--ssl_port
. SSL
,DNS
,Client IP
u otra marca que se use con poca frecuencia.
Hay nuevas marcas de inicio disponibles para ESPv2 y algunas marcas de ESP se han retirado o sustituido. Consulta Cambios en las marcas de inicio entre ESP y ESPv2 para obtener más información.
GKE y Kubernetes
Para migrar las configuraciones de Endpoints para GKE y Kubernetes, cambia la etiqueta de imagen de ESP de :1
a :2
en el archivo yaml
de implementación. Por ejemplo:
- 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
Tanto ESP como ESPv2 se implementan en el contenedor de Docker mediante el comando docker run
. Para migrar Endpoints para Compute Engine a ESPv2, actualiza la etiqueta de la imagen de Docker de :1
a :2
en el comando. Por ejemplo:
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
Plataformas sin servidor (Cloud Run, Cloud Functions y App Engine)
En las plataformas sin servidor, ESPv2 se implementa como un servicio de Cloud Run para gestionar la aplicación que se ejecuta en Cloud Run, Cloud Functions o App Engine. Para migrar Endpoints a ESPv2, debes compilar la configuración de tu servicio de Endpoints en una nueva imagen de Docker de ESPv2 y, a continuación, desplegar la imagen en tu servicio de Cloud Run de ESPv2.
Los pasos de implementación de ESP y ESPv2 son idénticos, excepto en los siguientes detalles:
La etiqueta de imagen debe cambiar de
:1
a:2
en ESPv2 cuando implementes ESPv2 en Cloud Run. Por ejemplo:gcloud run deploy CLOUD_RUN_SERVICE_NAME \ --image="gcr.io/endpoints-release/endpoints-runtime-serverless:2" \ --allow-unauthenticated \ --platform managed \ --project=ESP_PROJECT_ID
La
gcloud_build_image
secuencia de comandos se descarga desde otra ubicación. Usagcr.io/endpoints-release/endpoints-runtime-serverless:2
como imagen base.Se usa una variable de entorno para especificar las marcas de inicio. El nombre de la variable del ESP es
ESP_ARGS
. El nombre de ESPv2 esESPv2_ARGS
. Para obtener más información sobre cómo definirESPv2_ARGS
y las marcas de inicio disponibles, consulta Opciones de inicio de Extensible Service Proxy V2.
Cambios en las marcas de inicio entre ESP y ESPv2
Al igual que con Extensible Service Proxy, puedes especificar marcas de configuración al desplegar servicios de ESPv2. Con el cambio del ESP basado en NGINX al ESPv2 basado en Envoy, algunas marcas se han retirado o sustituido, y se han añadido otras nuevas. En esta sección se usan tres tablas para describir los cambios:
- En la tabla 1 se describen las nuevas marcas que sustituyen a las obsoletas.
- En la tabla 2 se describen las nuevas marcas.
- En la tabla 3 se describen las marcas obsoletas.
Banderas sustituidas
Nuevas marcas | Marcas sustituidas | Descripción | |
---|---|---|---|
--listener_port
|
--http_port , --http2_port , --ssl_port
|
Un único puerto de escucha de Envoy admite http, http2 y ssl en ESPv2. No es necesario especificar puertos independientes. | |
--ssl_server_cert_path
|
--ssl_port
|
Cuando se usa --ssl_server_cert_path , ESPv2 usa certificados de server.key y archivos server.crt . Con ESPv2, puede especificar rutas de certificados de servidor distintas de /etc/nginx/ssl . Esta marca sustituye a --ssl_port en ESP, que usa certificados de las rutas de archivo /etc/nginx/ssl/nginx.key y /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
|
Cuando se usa --ssl_backend_client_cert_path , ESPv2 usa certificados de client.key y archivos client.crt . Con ESPv2, puede especificar rutas de certificados de cliente distintas de /etc/nginx/ssl . Esta marca sustituye a --tls_mutual_auth en ESP, que usa certificados de las rutas de archivo /etc/nginx/ssl/backend.key y /etc/nginx/ssl/backend.crt .
|
|
--ssl_backend_client_root_certs_file
|
--grpc_backend_ssl_root_certs_file
|
Con ESPv2, --ssl_backend_client_root_certs_file funciona en todos los back-ends. Esta marca sustituye a --grpc_backend_ssl_root_certs_file en ESP, que solo funciona con back-ends de gRPC.
|
|
--ssl_minimum_protocol ,--ssl_maximum_protocol
|
--ssl_protocols
|
Cuando uses --ssl_protocols en ESP, debes
enumerar todos los protocolos SSL que quieras. En ESPv2, puede especificar
un protocolo mínimo y máximo.
|
|
--envoy_use_remote_address ,--envoy_xff_num_trusted_hops
|
--xff_trusted_proxy_list ,--client_ip_header ,--client_ip_position
|
Envoy requiere use_remote_address y xff_num_trusted_hops
para configurar la extracción de la IP del cliente.
|
|
--dns_resolver_addresses
|
--dns
|
La marca de sustitución tiene el mismo comportamiento, pero un valor predeterminado diferente.
El ESP usa 8.8.8.8 como resolvedor de DNS. ESPv2 usa el resolvedor de DNS configurado en /etc/resolv.conf .
|
|
--service_account_key
|
--non_gcp , --service_account_key
|
En ESP, la marca --service_account_key permite de forma implícita el despliegue en plataformas distintas de GCP.
Evita que el ESP llame al servidor de metadatos de instancias.
|
En ESPv2, este comportamiento implícito se divide en otro indicador. Es posible que tengas que añadir
--non_gcp al migrar. De lo contrario, ESPv2
no se iniciará en plataformas que no sean GCP.
|
Nuevas marcas
Nuevas marcas | Descripción |
---|---|
--http_request_timeout_s
|
Define el tiempo de espera de todas las llamadas remotas http/https, excepto las llamadas de backend y las llamadas de Google Service Control, en segundos. |
--service_control_check_timeout_ms
|
Define el tiempo de espera de las llamadas de comprobación de control de servicio de Google, en milisegundos. |
--service_control_report_timeout_ms
|
Define el tiempo de espera de las llamadas a Google Service Control Report. |
--service_control_quota_timeout_ms
|
Define el tiempo de espera de las llamadas a Google Service Control Quota. |
--service_control_check_retries
|
Especifica el número de reintentos de las llamadas a Google Service Control Check. |
--service_control_report_retries
|
Especifica el número de reintentos de las llamadas a Google Service Control Report. |
--service_control_quota_retries
|
Especifica el número de reintentos de las llamadas a Google Service Control Quota. |
--backend_dns_lookup_family
|
Configuración específica de Envoy que se usa para definir la familia de búsqueda de DNS de todos los back-ends. |
--disable_tracing
|
Una marca general que se usa para inhabilitar todos los rastreos. |
--tracing_project_id
|
Se usa para definir el ID del proyecto propietario de los datos de la traza. |
--tracing_incoming_context
|
Se usa para especificar el contexto de rastreo entrante. |
--tracing_outgoing_context
|
Se usa para especificar el contexto de rastreo saliente. |
Marcas obsoletas
Marcas obsoletas | Descripción |
---|---|
--enable_websocket
|
Websocket está habilitado de forma predeterminada en Envoy. |
--experimental_proxy_backend_host_header
|
No es compatible. |
--allow_invalid_headers
|
No es compatible. Esta es una configuración de NGINX: ignore_invalid_headers . Si una solicitud HTTP tiene nombres de encabezado no válidos, ESPv2 la rechazará.
Los nombres de encabezado válidos se componen de letras del alfabeto inglés, números, guiones y, posiblemente, guiones bajos. En ESPv2, la marca
--underscores_in_headers determina si se permiten guiones bajos en los encabezados.
|
--client_max_body_size
|
Configuración de NGINX no admitida. |
--client_body_buffer_size
|
Configuración de NGINX no admitida. |
--large_client_header_buffers
|
Configuración de NGINX no admitida. |
--keepalive_timeout
|
Configuración de NGINX no admitida. |
--client_body_timeout
|
Configuración de NGINX no admitida. |
--rewrite
|
No es compatible. |
--experimental_enable_multiple_api_configs
|
No es compatible. |
--enable_backend_routing
|
No es necesario. El enrutamiento de backend se habilita automáticamente en las plataformas sin servidor. |
--rollout_fetch_throttle_window_in_s
|
No es necesario. |
--nginx_config
|
No es compatible. |
Consulta más información sobre las marcas de inicio de ESPv2 en Opciones de inicio de Extensible Service Proxy V2. Puedes consultar más ejemplos genéricos y texto de ayuda para las marcas en el repositorio de GitHub.
Ubicaciones predeterminadas de JWT
De forma predeterminada, se envía un JWT en el encabezado Authorization
(con el prefijo "Bearer "), en el encabezado X-Goog-Iap-Jwt-Assertion
o en el parámetro de consulta access_token
. Estas ubicaciones son compatibles con ESP y ESPv2. También puedes enviar un JWT en el encabezado Authorization
(sin prefijo) cuando uses ESP. Sin embargo, esta ubicación no se admite en ESPv2.
Si quieres seguir enviando JWTs mediante el encabezado Authorization
(sin prefijo) después de migrar a ESPv2, puedes hacer lo siguiente:
- Define x-google-jwt-locations en tu archivo OpenAPI (para usuarios de backend HTTP):
x-google-jwt-locations: - header: "Authorization"
- Define Authentication.providers.jwt_locations en tu archivo YAML de gRPC (para usuarios de backend de gRPC):
jwt_locations:
- header: Authorization
Gestionar JWTs en el servicio de backend
Cuando se usan JWTs para realizar la autenticación, ESPv2 y ESP envían el resultado de la autenticación en el encabezado X-Endpoint-API-UserInfo
a la API de backend. Te recomendamos que uses este encabezado en lugar del encabezado original Authorization
, ya que este último puede modificarse en plataformas sin servidor.Authorization
El encabezado X-Endpoint-API-UserInfo
contiene un objeto JSON codificado en Base64Url. Sin embargo, su formato ha cambiado de ESP a ESPv2.
En ESPv2, el encabezado X-Endpoint-API-UserInfo
contiene la carga útil del JWT original, sin ninguna modificación.
En ESP, el encabezado X-Endpoint-API-UserInfo
contiene la carga útil de JWT y algunos campos específicos añadidos por ESP. El proveedor de servicios de cifrado añade los campos id
, issuer
, email
y audiences
al objeto JSON.
También añade el campo claims
para incluir la carga útil del JWT original.
# 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 } }
En el siguiente ejemplo se muestran las diferencias. Todas las cadenas se han decodificado con 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" } }
Consulta Autenticar usuarios mediante un método personalizado y Autenticación entre servicios para obtener más información sobre el uso de JWTs con la autenticación.
Formato del cuerpo de la respuesta JSON de error
Si ESP o ESPv2 rechazan una solicitud HTTP, el cuerpo de la respuesta contiene un código de estado y un mensaje de error en formato JSON. El formato del cuerpo de la respuesta ha cambiado en ESPv2, tal como se muestra en los ejemplos siguientes:
Cuerpo de la respuesta de error de ESP
{ "code": 5, "message": "Method does not exist.", "details": [ { "@type": "type.googleapis.com/google.rpc.DebugInfo", "stackEntries": [], "detail": "service_control" } ] }
Cuerpo de la respuesta de error de ESPv2
{ "code": 400, "message": "Method does not exist.", }
Hay dos diferencias principales:
- En ESPv2, el campo
code
contiene un código de estado HTTP, en lugar del código de estado de RPC que se encuentra en ESP. - El cuerpo de la respuesta de error en ESPv2 no contiene un campo
details
.
Siguientes pasos
Puedes informarte sobre lo siguiente:
- Opciones de inicio de Extensible Service Proxy V2
- Extensiones de OpenAPI
- Repositorio de ESPv2 en GitHub