Migre para o proxy de serviço extensível V2

O Extensible Service Proxy V2 (ESPv2) é um proxy baseado no Envoy que permite que os Cloud Endpoints ofereçam funcionalidades de gestão de APIs. O ESPv2 substitui o proxy de serviço extensível (ESP) baseado no NGINX.

Este documento descreve como migrar uma implementação da API Endpoints existente do ESP para o ESPv2.

Antes de começar

Antes de iniciar a migração, considere os exemplos de utilização não suportados e as alterações à API que podem causar problemas, descritos abaixo.

Exemplos de utilização não suportados do ESPv2

  • O ambiente flexível do App Engine não é suportado

    O ambiente flexível do App Engine tem suporte de Endpoints incorporado que é ativado ao definir endpoints_api_service no ficheiro app.yaml da aplicação. Esta implementação dos Endpoints incorporada só suporta o ESP e não pode ser migrada para o ESPv2.

    Se quiser usar o ESPv2 com o ambiente flexível do App Engine, desative endpoints_api_service em app.yaml. Pode implementar o ESPv2 como um serviço do Cloud Run separado usado para gerir a sua aplicação no ambiente flexível do App Engine. A implementação funciona da mesma forma que o ESPv2 é usado para suportar o ambiente padrão do App Engine.

  • A configuração NGINX personalizada não é suportada

    O ESPv2 é um proxy baseado no Envoy. Não pode suportar a configuração de proxy NGINX personalizada. Se a configuração do ESP usar as flags -n ou --nginx_config, a sua implementação pode depender de uma configuração NGINX personalizada que não pode ser migrada facilmente para o ESPv2.

Alterações interruptivas

  • O formato de dados do cabeçalho X-Endpoint-API-UserInfo é alterado. Se a sua aplicação usar este cabeçalho, tem de o alterar para usar o novo formato. Consulte o artigo Processar JWTs no serviço de back-end para ver mais detalhes.
  • Se for necessária uma chave da API para um pedido, o ESP envia o cabeçalho X-Endpoint-API-Project-ID com o ID do projeto do consumidor para a aplicação de back-end. O ESPv2 usa dois cabeçalhos diferentes,X-Endpoint-API-Consumer-Type e X-Endpoint-API-Consumer-Number, para enviar os detalhes necessários. Consulte a documentação de referência da infraestrutura de serviços para ver mais detalhes sobre os valores Consumer-Type e Consumer-Number enviados com estes cabeçalhos.

  • O formato do corpo da resposta de erro HTTP foi alterado. Quando o ESPv2 rejeita um pedido HTTP, gera um corpo de resposta de erro num novo formato. Se a sua implementação usar código do cliente para processar o corpo da resposta JSON de erro HTTP, o código do cliente tem de ser atualizado. Consulte o corpo da resposta JSON de erro HTTP para ver mais detalhes.

  • Estão disponíveis novas flags de arranque e algumas flags de ESP foram descontinuadas ou substituídas no ESPv2. Consulte as alterações da flag de arranque entre o ESP e o ESPv2.

Migrar as suas APIs Endpoints para usar o ESPv2

Os passos de migração necessários para usar o ESPv2 com plataformas sem servidor (Cloud Run, funções do Cloud Run e App Engine) diferem dos passos necessários para plataformas sem servidor (Google Kubernetes Engine, Compute Engine e Kubernetes).

Os passos de migração necessários para cada tipo de plataforma são descritos abaixo:

Plataformas sem servidor: GKE, Compute Engine, Kubernetes

O ESPv2 é um substituto direto do ESP. Para a maioria das configurações, só tem de fazer a atualização para a etiqueta da imagem do Docker.

No entanto, pode ter de ajustar as flags de arranque se tiver configurado o ESP com:

  • Mais do que uma porta através das flags --http_port, http2_port e/ou --ssl_port.
  • O SSL, o DNS, o Client IP ou outro sinalizador raramente usado.

Estão disponíveis novas flags de arranque para o ESPv2 e algumas flags do ESP foram descontinuadas ou substituídas. Consulte o artigo Alterações das flags de arranque entre o ESP e o ESPv2 para ver mais detalhes.

GKE e Kubernetes

Para migrar as configurações dos Endpoints para o GKE e o Kubernetes, altere a etiqueta da imagem do ESP de :1 para :2 no ficheiro yaml de implementação. Por 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 implementados no contentor Docker através do comando docker run. Para migrar os Endpoints para o Compute Engine para o ESPv2, atualize a etiqueta da imagem 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 é implementado como um serviço do Cloud Run para gerir a sua aplicação em execução no Cloud Run, no Cloud Functions ou no App Engine. Para migrar os Endpoints para o ESPv2, tem de criar a configuração do serviço Endpoints existente numa nova imagem Docker do ESPv2 e, em seguida, implementar a imagem no serviço do Cloud Run do ESPv2.

Os passos de implementação do ESP e do ESPv2 são idênticos, exceto nos seguintes detalhes:

  • A etiqueta de imagem deve ser alterada de :1 para :2 no ESPv2 quando implementa o ESPv2 no Cloud Run. Por 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 gcloud_build_image script é transferido a partir de uma localização diferente. Usa gcr.io/endpoints-release/endpoints-runtime-serverless:2 como imagem base.

  • É usada uma variável de ambiente para especificar as flags de arranque. O nome da variável para o ESP é ESP_ARGS. O nome do ESPv2 é ESPv2_ARGS. Consulte as opções de arranque do proxy de serviço extensível V2 para mais informações sobre a definição de ESPv2_ARGS e as flags de arranque disponíveis.

As flags de arranque mudam entre o ESP e o ESPv2

Tal como com o proxy de serviço extensível, pode especificar flags de configuração ao implementar serviços ESPv2. Com a mudança do ESP baseado no NGINX para o ESPv2 baseado no Envoy, algumas flags foram descontinuadas ou substituídas, e foram adicionadas novas flags. Esta secção usa três tabelas para descrever as alterações:

  • A Tabela 1 descreve as novas flags que substituem as flags descontinuadas.
  • A Tabela 2 descreve as novas flags.
  • A tabela 3 descreve as flags descontinuadas.

Sinalizações substituídas

Novas sinalizações Sinalizações substituídas Descrição
--listener_port --http_port, --http2_port, --ssl_port Uma única porta de ouvinte do Envoy suporta 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 dos ficheiros server.key e server.crt. Com o ESPv2, pode especificar caminhos de certificados de servidor diferentes de /etc/nginx/ssl. Esta flag substitui --ssl_port no ESP, que usa certificados dos caminhos dos ficheiros /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 dos ficheiros client.key e client.crt. Com o ESPv2, pode especificar caminhos de certificados de cliente diferentes de /etc/nginx/ssl. Esta flag substitui --tls_mutual_auth no ESP, que usa certificados dos caminhos dos ficheiros /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, o --ssl_backend_client_root_certs_file funciona para todos os back-ends. Esta flag substitui --grpc_backend_ssl_root_certs_file no ESP, que só funciona para back-ends gRPC.
--ssl_minimum_protocol,--ssl_maximum_protocol --ssl_protocols Quando usar --ssl_protocols no ESP, tem de listar todos os protocolos SSL pretendidos. No ESPv2, pode 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 requer use_remote_address e xff_num_trusted_hops para configurar a extração de IP do cliente.
--dns_resolver_addresses --dns A flag de substituição tem o mesmo comportamento, mas um valor predefinido diferente. O ESP usa 8.8.8.8 como um resolvedor de DNS. O ESPv2 usa o resolvedor de DNS configurado no /etc/resolv.conf.
--service_account_key --non_gcp, --service_account_key No ESP, a flag --service_account_key permite implicitamente a implementação em plataformas que não sejam a GCP. Impede que o ESP chame o servidor de metadados de instâncias. No ESPv2, este comportamento implícito é dividido noutra flag. Pode ter de adicionar --non_gcp durante a migração. Caso contrário, o ESPv2 não é iniciado em plataformas que não sejam a GCP.

Novos sinalizadores

Novas sinalizações Descrição
--http_request_timeout_s Define o limite de tempo 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 limite de tempo para chamadas de verificação de controlo de serviços Google, em milissegundos.
--service_control_report_timeout_ms Define o limite de tempo para chamadas do relatório de controlo de serviços Google.
--service_control_quota_timeout_ms Define o limite de tempo para chamadas da quota de controlo de serviços Google.
--service_control_check_retries Especifica o número de repetições para chamadas de verificação de controlo de serviços Google.
--service_control_report_retries Especifica o número de repetições para chamadas do relatório de controlo de serviços Google.
--service_control_quota_retries Especifica o número de repetições para chamadas da quota de controlo de serviços Google.
--backend_dns_lookup_family Configuração específica do Envoy usada para definir a família de pesquisas de DNS para todos os back-ends.
--disable_tracing Um indicador geral usado para desativar todos os rastreios.
--tracing_project_id Usado para definir o ID do projeto proprietário dos dados de rastreio.
--tracing_incoming_context usado para especificar o contexto do rastreio de entrada.
--tracing_outgoing_context Usado para especificar o contexto de rastreio de saída.

Sinalizadores descontinuados

Sinalizações descontinuadas Descrição
--enable_websocket O Websocket está ativado por predefinição no Envoy.
--experimental_proxy_backend_host_header Não suportado.
--allow_invalid_headers Não suportado. Esta é uma configuração do NGINX: ignore_invalid_headers. Se um pedido HTTP tiver nomes de cabeçalhos inválidos, é rejeitado pelo ESPv2. Os nomes de cabeçalhos válidos são compostos por letras do alfabeto inglês, dígitos, hífenes e possivelmente sublinhados. No ESPv2, a flag --underscores_in_headers determina se são permitidos carateres de sublinhado nos cabeçalhos.
--client_max_body_size Configuração do NGINX não suportada.
--client_body_buffer_size Configuração do NGINX não suportada.
--large_client_header_buffers Configuração do NGINX não suportada.
--keepalive_timeout Configuração do NGINX não suportada.
--client_body_timeout Configuração do NGINX não suportada.
--rewrite Não suportado.
--experimental_enable_multiple_api_configs Não suportado.
--enable_backend_routing Não é preciso. O encaminhamento de back-end é ativado automaticamente para plataformas sem servidor.
--rollout_fetch_throttle_window_in_s Não é preciso.
--nginx_config Não suportado.

Consulte o artigo Opções de arranque do proxy de serviço extensível V2 para obter mais detalhes acerca das flags de arranque do ESPv2. Pode encontrar exemplos genéricos adicionais e texto de ajuda para flags no repositório do GitHub.

Localizações JWT predefinidas

Por predefinição, um JWT é transmitido no cabeçalho Authorization (precedido por "Bearer "), no cabeçalho X-Goog-Iap-Jwt-Assertion ou no parâmetro de consulta access_token. Estas localizações são suportadas pelo ESP e ESPv2. Também pode transmitir um JWT no cabeçalho Authorization (sem prefixo) quando usar o ESP. No entanto, esta localização não é suportada no ESPv2.

Se quiser continuar a transmitir JWTs através do cabeçalho Authorization (sem prefixo) após a migração para o ESPv2, pode:

x-google-jwt-locations:
- header: "Authorization"
jwt_locations:
- header: Authorization

Processe JWTs no serviço de back-end

Quando usa JWTs para fazer 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 que use este cabeçalho em vez do cabeçalho Authorization original, uma vez que o cabeçalho Authorization original 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 respetivo formato foi alterado de ESP para ESPv2.

Para o ESPv2, o cabeçalho X-Endpoint-API-UserInfo contém o payload JWT original, sem qualquer modificação.

No ESP, o cabeçalho X-Endpoint-API-UserInfo contém a carga útil do JWT e alguns campos específicos adicionados pelo ESP. O ESP adiciona os campos id, issuer, email e audiences ao objeto JSON. Também adiciona o campo claims para incluir a carga útil 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
   }
}

O exemplo seguinte ilustra as diferenças. Todos foram descodificados em 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
  }
}

Consulte os artigos Usar um método personalizado para autenticar utilizadores e Autenticação entre serviços para saber mais sobre a utilização de JWTs com a autenticação.

Formato do corpo da resposta JSON de erro

Se um pedido HTTP for rejeitado pelo ESP ou ESPv2, o corpo da resposta contém um código de estado e uma mensagem de erro no formato JSON. O formato do corpo da resposta foi alterado no ESPv2, conforme mostrado nos exemplos abaixo:

O 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.",
}

Existem duas diferenças principais:

  • No ESPv2, o campo code contém um código de estado HTTP, em vez do código de estado RPC encontrado no ESP.
  • O corpo da resposta de erro no ESPv2 não contém um campo details.

O que se segue?

Saiba mais acerca do: