O Extensible Service Proxy V2 (ESPv2) é um proxy baseado em Envoy que permite que o Cloud Endpoints forneça recursos de gerenciamento de APIs. O ESPv2 substitui o Extensible Service Proxy (ESP) baseado em NGINX.
Neste documento, descrevemos como migrar uma implantação atual da API Endpoints do ESP para o ESPv2.
Antes de começar
Antes de iniciar a migração, considere os casos de uso não compatíveis e as alterações interruptivas da API descritas abaixo.
Casos de uso do ESPv2 não compatíveis
O ambiente flexível do App Engine não é compatível
O ambiente flexível do App Engine conta com suporte integrado do Endpoints, que é ativado ao configurar
endpoints_api_serviceno arquivoapp.yamldo aplicativo. Esta implementação integrada do Endpoints aceita apenas o ESP. Não é possível migrá-lo para o ESPv2.Se você quiser usar o ESPv2 com o ambiente flexível do App Engine, desative
endpoints_api_serviceemapp.yaml. Implante o ESPv2 como um serviço separado do Cloud Run usado para gerenciar seu aplicativo no ambiente flexível do App Engine. Ela funciona da mesma forma que o ESPv2 é usado para suportar o ambiente padrão do App Engine.A configuração personalizada do NGINX não é compatível
O ESPv2 é um proxy baseado em Envoy. Ele não é compatível com a configuração personalizada do proxy NGINX. Se sua configuração do ESP usa as sinalizações
-nou--nginx_config, sua implementação pode depender de uma configuração personalizada do NGINX que não pode ser migrada facilmente para o ESPv2.
Alterações importantes
- O formato de dados do cabeçalho
X-Endpoint-API-UserInfofoi alterado. Se o aplicativo usar esse cabeçalho, ele deverá ser alterado para usar o novo formato. Consulte Como lidar com JWTs no serviço de back-end para mais detalhes. Se uma chave de API for necessária para uma solicitação, o ESP enviará o cabeçalho do
X-Endpoint-API-Project-IDcom o ID do projeto do consumidor ao aplicativo de back-end. O ESPv2 usa dois cabeçalhos diferentes,X-Endpoint-API-Consumer-TypeeX-Endpoint-API-Consumer-Number, para enviar os detalhes necessários. Consulte a documentação de referência do Service Infrastructure para mais detalhes sobre osConsumer-TypeeConsumer-Numberenviados com esses cabeçalhos.Alteração no formato do corpo da resposta de erro HTTP. Quando o ESPv2 rejeita uma solicitação HTTP, ele gera um corpo de resposta de erro em um novo formato. Se sua implementação usar o código do cliente para processar o corpo da resposta JSON de erro HTTP, o código do cliente precisará ser atualizado. Consulte o corpo da resposta JSON de erro HTTP para mais detalhes.
Novas sinalizações de inicialização estão disponíveis e algumas sinalizações do ESP estão obsoletas ou foram substituídas no ESPv2. Consulte Alterações na sinalização de inicialização entre o ESP e o ESPv2.
Como migrar as APIs do Endpoints para usar o ESPv2
As etapas de migração necessárias para usar o ESPv2 com plataformas sem servidor (Cloud Run, Cloud Functions, App Engine) são diferentes das etapas necessárias para plataformas sem servidor (Google Kubernetes Engine, Compute Engine e Kubernetes).
Veja abaixo as etapas de migração necessárias para cada tipo de plataforma:
Plataformas sem servidor: GKE, Compute Engine e Kubernetes
O ESPv2 é uma substituição de drop-in para o ESP. Para a maioria das configurações, você só precisa atualizar para a tag de imagem do Docker.
No entanto, talvez seja necessário ajustar as sinalizações de inicialização se você tiver configurado o ESP com o seguinte:
- Mais de uma porta por meio das sinalizações
--http_port,http2_porte/ou--ssl_port. SSL,DNS,Client IPou outra sinalização raramente usada.
Novas sinalizações de inicialização estão disponíveis para o ESPv2 e algumas sinalizações do ESP estão obsoletas ou foram substituídas. Consulte Mudanças na sinalização de inicialização entre o ESP e o ESPv2 para mais detalhes.
GKE e Kubernetes
Para migrar as configurações do Endpoints para GKE e Kubernetes, altere a tag de imagem
do ESP de :1 para :2 no arquivo yaml da implantação. Exemplo:
- 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
O ESP e o ESPv2 são implantados
no contêiner do Docker usando o comando docker run. Para migrar o Endpoints do Compute Engine para o ESPv2, atualize a tag da imagem do Docker de :1 para :2 no comando. Por exemplo:
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 sem servidor (Cloud Run, Cloud Functions e App Engine)
Para plataformas sem servidor, o ESPv2 é implantado como um serviço do Cloud Run para gerenciar o aplicativo em execução no Cloud Run, Cloud Function ou App Engine. Para migrar o Endpoints para o ESPv2, você precisa criar a configuração do serviço do Endpoints em uma nova imagem do Docker do ESPv2 e, em seguida, implantar a imagem no serviço Cloud Run do ESPv2.
As etapas de implantação para ESP e ESPv2 são idênticas, exceto pelos seguintes detalhes:
Ao implantar o ESPv2 no Cloud Run, a tag de imagem precisa ser alterada de
:1para:2no ESPv2. Exemplo:gcloud run deploy CLOUD_RUN_SERVICE_NAME \ --image="gcr.io/endpoints-release/endpoints-runtime-serverless:2" \ --allow-unauthenticated \ --platform managed \ --project=ESP_PROJECT_ID
O download do script
gcloud_build_imageé feito em um local diferente. Ele usagcr.io/endpoints-release/endpoints-runtime-serverless:2como a imagem base.Uma variável de ambiente é usada para especificar sinalizações de inicialização. O nome da variável do ESP é
ESP_ARGS. O nome do ESPv2 éESPv2_ARGS. Consulte Opções de inicialização do Extensible Service Proxy V2 para mais informações sobre como definirESPv2_ARGSe as sinalizações de inicialização disponíveis.
Mudanças na sinalização de inicialização entre o ESP e o ESPv2
Assim como o Extensible Service Proxy, é possível especificar sinalizações de configuração ao implantar serviços de ESPv2. Com a mudança do ESP baseado em NGINX para o ESPv2 baseado em Envoy, algumas sinalizações foram suspensas ou substituídas, e novas sinalizações foram adicionadas. Esta seção usa três tabelas para descrever as alterações:
- A Tabela 1 descreve novas sinalizações que substituem as sinalizações obsoletas.
- A Tabela 2 descreve novos sinalizadores.
- A Tabela 3 descreve as sinalizações obsoletas.
Sinalizações substituídas
| Novas sinalizações | Sinalizações substituídas | Descrição | |
|---|---|---|---|
--listener_port
|
--http_port, --http2_port, --ssl_port |
Uma única porta do listener Envoy é compatível com http, http2 e ssl no ESPv2. Não é necessário especificar portas separadas. | |
--ssl_server_cert_path
|
--ssl_port
|
Quando --ssl_server_cert_path é usado, o ESPv2 usa certificados de arquivos server.key e
server.crt. Com o ESPv2, é possível especificar caminhos de certificado do servidor diferentes de /etc/nginx/ssl. Essa sinalização substitui --ssl_port no ESP, que usa certificados dos caminhos de arquivo /etc/nginx/ssl/nginx.key e /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 |
Quando --ssl_backend_client_cert_path é usado, o ESPv2 usa certificados de arquivos client.key e
client.crt. Com o ESPv2, é possível especificar caminhos de certificado do cliente diferentes de /etc/nginx/ssl. Essa sinalização substitui --tls_mutual_auth no ESP, que usa certificados dos caminhos de arquivo /etc/nginx/ssl/backend.key e /etc/nginx/ssl/backend.crt.
|
|
--ssl_backend_client_root_certs_file
|
--grpc_backend_ssl_root_certs_file
|
Com o ESPv2, --ssl_backend_client_root_certs_file funciona para todos os back-ends. Essa sinalização substitui --grpc_backend_ssl_root_certs_file no ESP, que só funciona para back-ends do gRPC.
|
|
--ssl_minimum_protocol,--ssl_maximum_protocol
|
--ssl_protocols
|
Ao usar --ssl_protocols no ESP, você precisa
listar todos os protocolos ssl desejados. No ESPv2, é possível especificar um protocolo
mínimo e máximo.
|
|
--envoy_use_remote_address,--envoy_xff_num_trusted_hops
|
--xff_trusted_proxy_list,--client_ip_header,--client_ip_position
|
O Envoy exige que use_remote_address e xff_num_trusted_hops
configurem a extração de IP do cliente.
|
|
--dns_resolver_addresses
|
--dns
|
A sinalização de substituição tem o mesmo comportamento, mas um valor padrão diferente.
O ESP usa 8.8.8.8 como um resolvedor de DNS. O ESPv2 usa o resolvedor de DNS
configurado em /etc/resolv.conf.
|
|
--service_account_key
|
--non_gcp, --service_account_key
|
No ESP, a sinalização --service_account_key
permite implicitamente a implantação em plataformas diferentes do GCP.
Ela impede que o ESP chame o servidor de metadados da instância.
|
No ESPv2, esse comportamento implícito é dividido em outra sinalização. Talvez seja necessário adicionar
--non_gcp ao migrar. Caso contrário, o ESPv2
não será iniciado em plataformas diferentes do GCP.
|
Novas sinalizações
| Novas sinalizações | Descrição |
|---|---|
--http_request_timeout_s
|
Define o tempo limite para todas as chamadas remotas http/https, exceto para chamadas de back-end e chamadas do Google Service Control, em segundos. |
--service_control_check_timeout_ms
|
Define o tempo limite para as chamadas de Verificação de controle dos Serviços do Google em milissegundos. |
--service_control_report_timeout_ms
|
Define o tempo limite para chamadas de Relatório de controle dos Serviços do Google. |
--service_control_quota_timeout_ms
|
Define o tempo limite para chamadas de Cota de controle dos Serviços do Google. |
--service_control_check_retries
|
Especifica o número de repetição de chamadas de Verificação de controle dos Serviços do Google. |
--service_control_report_retries
|
Especifica o número de repetição de chamadas do Relatório de controle dos Serviços do Google. |
--service_control_quota_retries
|
Especifica o número de repetição de chamadas de Cota de controle dos Serviços do Google. |
--backend_dns_lookup_family
|
Configuração específica do Envoy usada para definir a família da busca DNS de todos os back-ends. |
--disable_tracing
|
Uma sinalização geral usada para desativar todos os traces. |
--tracing_project_id
|
Usado para definir o ID do projeto que tem os dados de rastreamento. |
--tracing_incoming_context
|
Usado para especificar o contexto de trace de entrada. |
--tracing_outgoing_context
|
Usado para especificar o contexto de saída. |
Sinalizações obsoletas
| Sinalizações obsoletas | Descrição |
|---|---|
--enable_websocket
|
O Websocket é ativado por padrão no Envoy. |
--experimental_proxy_backend_host_header
|
Incompatível. |
--allow_invalid_headers
|
Incompatível. Esta é uma configuração do NGINX: ignore_invalid_headers. Se uma solicitação HTTP tiver nomes de cabeçalho inválidos,
ela será rejeitada pelo ESPv2.
Nomes de cabeçalho válidos são compostos de letras em inglês, dígitos, hífens e
possivelmente sublinhados. No ESPv2, a sinalização
--underscores_in_headers determina se sublinhados são permitidos em cabeçalhos.
|
--client_max_body_size
|
A configuração do NGINX é incompatível. |
--client_body_buffer_size
|
A configuração do NGINX é incompatível. |
--large_client_header_buffers
|
A configuração do NGINX é incompatível. |
--keepalive_timeout
|
A configuração do NGINX é incompatível. |
--client_body_timeout
|
A configuração do NGINX é incompatível. |
--rewrite
|
Incompatível. |
--experimental_enable_multiple_api_configs
|
Incompatível. |
--enable_backend_routing
|
Desnecessário. O roteamento de back-end é ativado automaticamente nas plataformas sem servidor. |
--rollout_fetch_throttle_window_in_s
|
Desnecessário. |
--nginx_config
|
Incompatível. |
Consulte as opções de inicialização do Extensible Service Proxy V2 para saber mais detalhes sobre as sinalizações de inicialização do ESPv2. Outros exemplos genéricos e textos de ajuda para sinalizações podem ser encontrados no repositório do GitHub.
Locais padrão do JWT
Por padrão, um JWT é transmitido no cabeçalho Authorization (prefixado por "Bearer "), no cabeçalho X-Goog-Iap-Jwt-Assertion ou no parâmetro de consulta access_token. Esses locais são aceitos pelo ESP e pelo ESPv2. Também é possível transmitir um JWT no cabeçalho Authorization (sem prefixo) ao usar o ESP. No entanto, esse local não é compatível com ESPv2.
Se você quiser continuar transmitindo JWTs usando o cabeçalho Authorization (sem prefixo) depois de migrar para o ESPv2, poderá:
- Definir x-google-jwt-locations no arquivo openAPI (para usuários de back-end HTTP):
x-google-jwt-locations: - header: "Authorization"
- Definir Authentication.providers.jwt_locations no arquivo yaml do gRPC (para usuários de back-end do gRPC):
jwt_locations:
- header: AuthorizationGerenciar os JWTs no serviço de back-end
Ao usar JWTs para realizar a autenticação, o ESPv2 e o ESP
enviam o resultado da autenticação no cabeçalho X-Endpoint-API-UserInfo para a
API de back-end. Recomendamos usar esse cabeçalho em vez do cabeçalho
Authorization original, porque o Authorization
pode ser modificado em plataformas sem servidor.
O cabeçalho X-Endpoint-API-UserInfo contém um objeto JSON codificado em Base64Url. No entanto, o formato foi alterado de ESP para
ESPv2.
Para o ESPv2, o cabeçalho X-Endpoint-API-UserInfo contém o
payload original do JWT, sem nenhuma modificação.
No ESP, o cabeçalho X-Endpoint-API-UserInfo contém o payload
do JWT e alguns campos específicos adicionados pelo ESP. O ESP
adiciona os campos id, issuer, email e audiences ao objeto JSON.
Ele também adiciona o campo claims para incluir o payload original do 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
}
}
O exemplo a seguir ilustra as diferenças. Todos eles foram decodificados em 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" } }
Consulte Como usar um método personalizado para autenticar usuários e Como autenticar entre serviços, para saber mais sobre como usar JWTs com uma autenticação.
Formato de corpo de resposta JSON de erro
Quando uma solicitação HTTP é rejeitada pelo ESP ou ESPv2, o corpo da resposta contém um código de status e uma mensagem de erro no formato JSON. O formato do corpo da resposta foi alterado no ESPv2, conforme mostrado nos exemplos abaixo:
Corpo da resposta de erro do ESP
{ "code": 5, "message": "Method does not exist.", "details": [ { "@type": "type.googleapis.com/google.rpc.DebugInfo", "stackEntries": [], "detail": "service_control" } ] }
O corpo da resposta de erro do ESPv2
{
"code": 400,
"message": "Method does not exist.",
}Há duas diferenças principais:
- No ESPv2, o campo
codecontém um código de status HTTP, em vez do código de status RPC encontrado no ESP. - O corpo da resposta de erro no ESPv2 não contém um campo
details.
A seguir
Saiba mais sobre:
- Opções de inicialização do Extensible Service Proxy V2
- Extensões da OpenAPI
- O repositório do ESPv2 no GitHub