Esegui la migrazione a Extensible Service Proxy V2

Extensible Service Proxy V2 (ESPv2) è un proxy basato su Envoy che consente a Cloud Endpoints di fornire funzionalità di gestione delle API. ESPv2 sostituisce l'Extensible Service Proxy (ESP) basato su NGINX.

Questo documento descrive come eseguire la migrazione di un deployment esistente dell'API Endpoints da ESP a ESPv2.

Prima di iniziare

Prima di iniziare la migrazione, prendi in considerazione i casi d'uso non supportati e le modifiche non riuscite alle API descritte di seguito.

Casi d'uso non supportati da ESPv2

  • L'ambiente flessibile di App Engine non è supportato

    L'ambiente flessibile di App Engine dispone di supporto per endpoint integrato che si attiva impostando endpoints_api_service nel file app.yaml dell'applicazione. Questa implementazione di endpoint integrata supporta solo ESP; non è possibile eseguirne la migrazione a ESPv2.

    Se vuoi utilizzare ESPv2 con l'ambiente flessibile di App Engine, disabilita endpoints_api_service in app.yaml. Puoi eseguire il deployment di ESPv2 come servizio Cloud Run separato utilizzato per gestire l'applicazione nell'ambiente flessibile di App Engine. Il deployment funziona nello stesso modo in cui viene utilizzato ESPv2 per supportare l'ambiente standard di App Engine.

  • Configurazione NGINX personalizzata non supportata

    ESPv2 è un proxy basato su Envoy. Non può supportare la configurazione proxy NGINX personalizzata. Se la tua configurazione ESP utilizza i flag -n o --nginx_config, la tua implementazione potrebbe basarsi su una configurazione NGINX personalizzata di cui non è facile eseguire la migrazione a ESPv2.

Modifiche che provocano un errore

  • Il formato dei dati dell'intestazione X-Endpoint-API-UserInfo è stato modificato. Se l'applicazione utilizza questa intestazione, devi modificarla per utilizzare il nuovo formato. Per maggiori dettagli, vedi Gestire i JWT nel servizio di backend.
  • Se per una richiesta è necessaria una chiave API, ESP invia l'intestazione X-Endpoint-API-Project-ID con l'ID progetto consumer all'applicazione di backend. ESPv2 utilizza due intestazioni diverse,X-Endpoint-API-Consumer-Type e X-Endpoint-API-Consumer-Number, per inviare i dettagli richiesti. Consulta la documentazione di riferimento per l'infrastruttura di servizi per ulteriori dettagli sugli elementi Consumer-Type e Consumer-Number inviati con queste intestazioni.

  • Il formato del corpo della risposta dell'errore HTTP è stato modificato. Quando ESPv2 rifiuta una richiesta HTTP, genera un corpo della risposta di errore in un nuovo formato. Se l'implementazione utilizza il codice client per elaborare il corpo della risposta JSON dell'errore HTTP, il codice client deve essere aggiornato. Per ulteriori dettagli, vedi Corpo della risposta JSON dell'errore HTTP.

  • Sono disponibili nuovi flag di avvio e alcuni flag ESP sono stati ritirati o sostituiti in ESPv2. Vedi Modifiche ai flag di avvio tra ESP ed ESPv2.

Migrazione delle API Endpoints per utilizzare ESPv2

I passaggi di migrazione richiesti per utilizzare ESPv2 con piattaforme serverless (Cloud Run, Cloud Functions, App Engine) sono diversi da quelli richiesti per le piattaforme non serverless (Google Kubernetes Engine, Compute Engine e Kubernetes).

Di seguito sono descritti i passaggi di migrazione richiesti per ogni tipo di piattaforma:

Piattaforme non serverless: GKE, Compute Engine, Kubernetes

ESPv2 è un sostituto di ESP. Per la maggior parte delle configurazioni, devi solo eseguire l'aggiornamento al tag immagine Docker.

Tuttavia, potresti dover modificare i flag di avvio se hai configurato ESP con:

  • Più di una porta tramite i flag --http_port, http2_port e/o --ssl_port.
  • SSL, DNS, Client IP o un altro flag utilizzato raramente.

Sono disponibili nuovi flag di avvio per ESPv2 e alcuni flag ESP sono stati deprecati o sostituiti. Per maggiori dettagli, vedi Modifiche ai flag di avvio tra ESP ed ESPv2.

GKE e Kubernetes

Per eseguire la migrazione delle configurazioni di endpoint per GKE e Kubernetes, modifica il tag immagine ESP da :1 a :2 nel file yaml di deployment. Ad esempio:

- 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

Viene eseguito il deployment di ESP ed ESPv2 nel container Docker tramite il comando docker run. Per eseguire la migrazione di Endpoints per Compute Engine a ESPv2, aggiorna il tag dell'immagine Docker da :1 a :2 nel comando. Ad esempio:

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

Piattaforme serverless (Cloud Run, Cloud Functions, App Engine)

Per le piattaforme serverless, viene eseguito il deployment di ESPv2 come servizio Cloud Run per gestire l'applicazione in esecuzione su Cloud Run, Cloud Function o App Engine. Per eseguire la migrazione di Endpoints a ESPv2, devi creare la configurazione del servizio Endpoints esistente in una nuova immagine Docker ESPv2, quindi eseguire il deployment dell'immagine nel servizio ESPv2 Cloud Run.

I passaggi di deployment per ESP ed ESPv2 sono identici, tranne per i seguenti dettagli:

  • Il tag immagine deve essere modificato da :1 a :2 in ESPv2 quando esegui il deployment di ESPv2 in Cloud Run. Ad esempio:

    gcloud run deploy CLOUD_RUN_SERVICE_NAME \
    --image="gcr.io/endpoints-release/endpoints-runtime-serverless:2" \
    --allow-unauthenticated \
    --platform managed \
    --project=ESP_PROJECT_ID
    
  • Lo script gcloud_build_image è stato scaricato da una posizione diversa. Utilizza gcr.io/endpoints-release/endpoints-runtime-serverless:2 come immagine di base.

  • Una variabile di ambiente viene utilizzata per specificare i flag di avvio. Il nome della variabile per ESP è ESP_ARGS. Il nome di ESPv2 è ESPv2_ARGS. Vedi Opzioni di avvio di Extensible Service Proxy V2 per ulteriori informazioni sull'impostazione di ESPv2_ARGS e sui flag di avvio disponibili.

Modifiche ai flag di avvio tra ESP ed ESPv2

Come con Extensible Service Proxy, puoi specificare i flag di configurazione durante il deployment dei servizi ESPv2. Con il passaggio dall'ESP basato su NGINX all'ESPv2 basato su Envoy, alcuni flag sono stati deprecati o sostituiti e sono stati aggiunti nuovi flag. In questa sezione vengono utilizzate tre tabelle per descrivere le modifiche:

  • La tabella 1 descrive i nuovi flag che sostituiscono quelli ritirati.
  • La tabella 2 descrive i nuovi flag.
  • La tabella 3 descrive i flag obsoleti.

Flag sostituiti

Nuovi flag Flag sostituiti Descrizione
--listener_port --http_port, --http2_port, --ssl_port Una singola porta listener di Envoy supporta http, http2 e ssl in ESPv2. Non è necessario specificare porte separate.
--ssl_server_cert_path --ssl_port Quando viene utilizzato --ssl_server_cert_path, ESPv2 utilizza i certificati dei file server.key e server.crt. Con ESPv2 puoi specificare percorsi del certificato del server diversi da /etc/nginx/ssl. Questo flag sostituisce --ssl_port in ESP, che utilizza i certificati dei percorsi file /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 viene utilizzato --ssl_backend_client_cert_path, ESPv2 utilizza i certificati dei file client.key e client.crt. Con ESPv2, puoi specificare percorsi del certificato client diversi da /etc/nginx/ssl. Questo flag sostituisce --tls_mutual_auth in ESP, che utilizza i certificati dei percorsi file /etc/nginx/ssl/backend.key e /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 funziona per tutti i backend. Questo flag sostituisce --grpc_backend_ssl_root_certs_file in ESP, che funziona solo per i backend gRPC.
--ssl_minimum_protocol,--ssl_maximum_protocol --ssl_protocols Quando utilizzi --ssl_protocols in ESP, devi elencare tutti i protocolli SSL desiderati. In ESPv2, puoi specificare un protocollo minimo e massimo.
--envoy_use_remote_address,--envoy_xff_num_trusted_hops --xff_trusted_proxy_list,--client_ip_header,--client_ip_position Envoy richiede use_remote_address e xff_num_trusted_hops per configurare l'estrazione dell'IP client.
--dns_resolver_addresses --dns Il flag di sostituzione ha lo stesso comportamento, ma un valore predefinito diverso. ESP usa 8.8.8.8 come resolver DNS. ESPv2 utilizza il resolver DNS configurato in /etc/resolv.conf.
--service_account_key --non_gcp, --service_account_key In ESP, il flag --service_account_key consente implicitamente il deployment su piattaforme diverse da Google Cloud. Impedisce a ESP di chiamare il server metadati istanza. In ESPv2, questo comportamento implicito è suddiviso in un altro flag. Potrebbe essere necessario aggiungere --non_gcp durante la migrazione, altrimenti ESPv2 non verrà avviato su piattaforme diverse da Google Cloud.

Nuovi flag

Nuovi flag Descrizione
--http_request_timeout_s Imposta il timeout in secondi per tutte le chiamate remote http/https, ad eccezione delle chiamate di backend e Google Service Control.
--service_control_check_timeout_ms Imposta il timeout in millisecondi per le chiamate Google Service Control Check.
--service_control_report_timeout_ms Imposta il timeout per le chiamate Google Service Control Report.
--service_control_quota_timeout_ms Imposta il timeout per le chiamate Google Service Control Quota.
--service_control_check_retries Specifica il numero di nuovo tentativo per le chiamate Google Service Control Check.
--service_control_report_retries Specifica il numero di nuovo tentativo per le chiamate Google Service Control Report.
--service_control_quota_retries Specifica il numero di nuovo tentativo per le chiamate Quota di Google Service Control.
--backend_dns_lookup_family Configurazione specifica di Envoy utilizzata per definire la famiglia di ricerca DNS per tutti i backend.
--disable_tracing Un flag generale utilizzato per disabilitare tutte le tracce.
--tracing_project_id Utilizzato per impostare l'ID del progetto proprietario dei dati di traccia.
--tracing_incoming_context utilizzato per specificare il contesto della traccia in entrata.
--tracing_outgoing_context Utilizzato per specificare il contesto di outgoingtrace.

Flag obsoleti

Flag obsoleti Descrizione
--enable_websocket Websocket è abilitato per impostazione predefinita in Envoy.
--experimental_proxy_backend_host_header Non supportati.
--allow_invalid_headers Non supportati. Questa è una configurazione NGINX: ignore_invalid_headers. Se una richiesta HTTP ha nomi di intestazione non validi, verrà rifiutata da ESPv2. I nomi di intestazione validi sono composti da lettere dell'alfabeto latino, cifre, trattini ed eventualmente trattini bassi. In ESPv2, il flag --underscores_in_headers determina se i trattini bassi sono consentiti nelle intestazioni.
--client_max_body_size Configurazione NGINX, non supportata.
--client_body_buffer_size Configurazione NGINX, non supportata.
--large_client_header_buffers Configurazione NGINX, non supportata.
--keepalive_timeout Configurazione NGINX, non supportata.
--client_body_timeout Configurazione NGINX, non supportata.
--rewrite Non supportati.
--experimental_enable_multiple_api_configs Non supportati.
--enable_backend_routing Non è necessario. Il routing di backend è abilitato automaticamente per le piattaforme serverless.
--rollout_fetch_throttle_window_in_s Non è necessario.
--nginx_config Non supportati.

Per ulteriori dettagli sui flag di avvio ESPv2, vedi Opzioni di avvio di Extensible Service Proxy V2. Ulteriori esempi generici e testo della guida per i flag sono disponibili nel repository GitHub.

Località JWT predefinite

Per impostazione predefinita, un JWT viene passato nell'intestazione Authorization (preceduta da "Bearer"), nell'intestazione X-Goog-Iap-Jwt-Assertion o nel parametro di query access_token. Queste località sono supportate sia da ESP che da ESPv2. Puoi anche passare un JWT nell'intestazione Authorization (senza prefisso) quando utilizzi ESP. Tuttavia, questa località non è supportata in ESPv2.

Se vuoi continuare a passare i JWT utilizzando l'intestazione Authorization (senza prefisso) dopo la migrazione a ESPv2, puoi:

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

Gestire i JWT nel servizio di backend.

Quando si utilizzano JWT per eseguire l'autenticazione, ESPv2 ed ESP inviano il risultato dell'autenticazione nell'intestazione X-Endpoint-API-UserInfo all'API di backend. Ti consigliamo di utilizzare questa intestazione anziché quella Authorization originale, in quanto l'intestazione Authorization originale potrebbe essere modificata nelle piattaforme serverless.

L'intestazione X-Endpoint-API-UserInfo contiene un oggetto JSON codificato in Base64Url. Tuttavia, il suo formato è stato modificato da ESP a ESPv2.

Per ESPv2, l'intestazione X-Endpoint-API-UserInfo contiene il payload JWT originale, senza alcuna modifica.

In ESP, l'intestazione X-Endpoint-API-UserInfo contiene il payload JWT e alcuni campi specifici aggiunti da ESP. ESP aggiunge i campi id, issuer, email e audiences all'oggetto JSON. Inoltre, aggiunge il campo claims per includere il payload JWT originale.

# 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
   }
}

L'esempio seguente illustra le differenze. Tutte sono state decodificate in 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"
  }
}

Per saperne di più sull'utilizzo di JWT con autenticazione, consulta Utilizzo di un metodo personalizzato per autenticare gli utenti e Autenticazione tra i servizi.

Formato del corpo della risposta JSON dell'errore

Se una richiesta HTTP viene rifiutata da ESP o ESPv2, il corpo della risposta contiene un codice di stato e un messaggio di errore in formato JSON. Il formato del corpo della risposta è cambiato in ESPv2, come mostrato negli esempi riportati di seguito:

Corpo della risposta all'errore da ESP

{
 "code": 5,
 "message": "Method does not exist.",
 "details": [
  {
   "@type": "type.googleapis.com/google.rpc.DebugInfo",
   "stackEntries": [],
   "detail": "service_control"
  }
 ]
}

Corpo della risposta all'errore da ESPv2

{
 "code": 400,
 "message": "Method does not exist.",
}

Esistono due differenze principali:

  • In ESPv2, il campo code contiene un codice di stato http anziché un codice di stato RPC trovato in ESP.
  • Il corpo della risposta di errore in ESPv2 non contiene un campo details.

Passaggi successivi

Scopri di più su: