Risolvi i problemi del bilanciamento del carico in GKE


Questa pagina mostra come risolvere i problemi relativi al bilanciamento del carico nei cluster Google Kubernetes Engine (GKE) utilizzando le risorse Service, Ingress o Gateway.

Se hai bisogno di ulteriore aiuto, contatta l'assistenza clienti Google Cloud.

BackendConfig non trovato

Questo errore si verifica quando nell'annotazione di servizio viene specificato un BackendConfig per una porta del servizio, ma non è stato possibile trovare la risorsa BackendConfig effettiva.

Per valutare un evento Kubernetes, esegui questo comando:

kubectl get event

Il seguente output di esempio indica che BackendConfig non è stato trovato:

KIND    ... SOURCE
Ingress ... loadbalancer-controller

MESSAGE
Error during sync: error getting BackendConfig for port 80 on service "default/my-service":
no BackendConfig for service port exists

Per risolvere questo problema, assicurati di non aver creato la risorsa BackendConfig nello spazio dei nomi sbagliato o di non aver scritto correttamente il relativo riferimento nell'annotazione Service.

Criterio di sicurezza in entrata non trovato

Dopo aver creato l'oggetto Ingress, se il criterio di sicurezza non è associato correttamente al servizio LoadBalancer, valuta l'evento Kubernetes per verificare se è presente un errore di configurazione. Se il tuo BackendConfig specifica un criterio di sicurezza che non esiste, periodicamente viene emesso un evento di avviso.

Per valutare un evento Kubernetes, esegui questo comando:

kubectl get event

Il seguente output di esempio indica che il criterio di sicurezza non è stato trovato:

KIND    ... SOURCE
Ingress ... loadbalancer-controller

MESSAGE
Error during sync: The given security policy "my-policy" does not exist.

Per risolvere questo problema, specifica il nome corretto del criterio di sicurezza in BackendConfig.

Affrontare gli errori della serie 500 con i NEG durante la scalabilità dei carichi di lavoro in GKE

Sintomo:

Quando utilizzi i NEG di cui è stato eseguito il provisioning di GKE per il bilanciamento del carico, potresti riscontrare errori 502 o 503 per i servizi durante lo fare lo scale down del carico di lavoro. Gli errori 502 si verificano quando i pod vengono terminati prima della chiusura delle connessioni esistenti, mentre gli errori 503 si verificano quando il traffico viene indirizzato ai pod eliminati.

Questo problema può interessare i cluster se utilizzi prodotti di bilanciamento del carico gestiti da GKE che utilizzano NEG, tra cui gateway, Ingress e NEG autonomi. Se scali frequentemente i tuoi carichi di lavoro, il rischio del cluster è maggiore di essere interessato.

Diagnosi:

La rimozione di un pod in Kubernetes senza svuotare l'endpoint e la sua rimozione dal NEG genera prima errori di tipo 500. Per evitare problemi durante la terminazione del pod, devi considerare l'ordine delle operazioni. Nelle immagini seguenti vengono visualizzati scenari quando il criterio BackendService Drain Timeout non viene configurato e BackendService Drain Timeout è impostato su BackendConfig.

Scenario 1: l'impostazione BackendService Drain Timeout non è attiva.

L'immagine seguente mostra uno scenario in cui BackendService Drain Timeout non è impostato.

Il timeout di svuotamento BackendService non è impostato

Scenario 2: BackendService Drain Timeout impostato.

L'immagine seguente mostra uno scenario in cui è impostato BackendService Drain Timeout.

Il timeout di svuotamento del servizio BackendService è impostato

Il momento esatto in cui si verificano gli errori della serie 500 dipende dai seguenti fattori:

  • Latenza di scollegamento API NEG: la latenza di scollegamento dell'API NEG rappresenta il tempo attuale necessario per finalizzare l'operazione di scollegamento in Google Cloud. Ciò è influenzato da una serie di fattori esterni a Kubernetes, tra cui il tipo di bilanciatore del carico e la zona specifica.

  • Latenza di svuotamento: la latenza di svuotamento rappresenta il tempo impiegato dal bilanciatore del carico per iniziare a indirizzare il traffico da una determinata parte del sistema. Una volta avviato il download, il bilanciatore del carico smette di inviare nuove richieste all'endpoint, ma è ancora presente una latenza nell'attivazione dello svuotamento (Latenza di svuotamento), che può causare errori 503 temporanei se il pod non esiste più.

  • Configurazione del controllo di integrità: soglie più sensibili del controllo di integrità riducono la durata degli errori 503, in quanto possono indicare al bilanciatore del carico di interrompere l'invio di richieste agli endpoint anche se l'operazione di scollegamento non è terminata.

  • Periodo di tolleranza per la risoluzione: il periodo di tolleranza per la terminazione determina il periodo di tempo massimo concesso per uscire da un pod. Tuttavia, un pod può uscire prima del completamento del periodo di tolleranza per la terminazione. Se un pod impiega più tempo di questo periodo, viene forzata l'uscita dal pod alla fine di questo periodo. Questa è un'impostazione sul pod e deve essere configurata nella definizione del carico di lavoro.

Potenziale risoluzione:

Per evitare questi errori 5XX, applica le seguenti impostazioni. I valori di timeout sono indicativi e potresti dover modificarli per la tua applicazione specifica. La seguente sezione illustra il processo di personalizzazione.

L'immagine seguente mostra come mantenere attivo il pod con preStopHook:

Il timeout di svuotamento del servizio BackendService è impostato

Per evitare errori della serie 500, segui questi passaggi:

  1. Imposta BackendService Drain Timeout per il tuo servizio su 1 minuto.

  2. Estendi terminationGracePeriod nel pod.

    Imposta terminationGracePeriodSeconds sul pod su 3,5 minuti. Se combinata con le impostazioni consigliate, ciò consente ai pod una finestra di 30-45 secondi per un arresto controllato dopo che l'endpoint del pod è stato rimosso dal NEG. Se hai bisogno di più tempo per l'arresto controllato, puoi estendere il periodo di tolleranza o seguire le istruzioni indicate nella sezione Personalizzare i timeout.

    Il seguente manifest BackendConfig specifica un timeout per lo svuotamento della connessione di 210 secondi (3,5 minuti):

    apiVersion: v1
    kind: BackendConfig
    metadata:
      name: my-backendconfig
    spec:
      terminationGracePeriodSeconds: 210
      containers:
      - name: my-app
        image: my-app-image:latest
        ports:
        - containerPort: 80
    
  3. Applica un'istruzione preStopHook a tutti i contenitori.

    Applica un valore preStopHook per garantire che il pod rimanga attivo per 120 secondi in più, mentre l'endpoint del pod viene svuotato nel bilanciatore del carico e l'endpoint viene rimosso dal NEG.

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
    spec:
      containers:
      - name: my-app
        # Container configuration details...
        lifecycle:
          preStop:
            exec:
              command: ["/bin/sh", "-c", "sleep 120s"]
    

Personalizza i timeout

Per garantire la continuità del pod ed evitare errori della serie 500, il pod deve essere attivo fino a quando l'endpoint non viene rimosso dal NEG. Per evitare errori di tipo 502 e 503, ti consigliamo di implementare una combinazione di timeout e preStopHook.

Per mantenere attivo il pod più a lungo durante il processo di arresto, aggiungi un preStopHook al pod. Esegui preStopHook prima che venga indicato l'uscita di un pod, in modo che preStopHook possa essere utilizzato per mantenere il pod a disposizione fino a quando l'endpoint corrispondente non viene rimosso dal NEG.

Per estendere il periodo di tempo in cui un pod rimane attivo durante il processo di arresto, inserisci un valore preStopHook nella configurazione del pod in questo modo:

spec:
  containers:
  - name: my-app
    ...
    lifecycle:
      preStopHook:
        exec:
          command: ["/bin/sh", "-c", "sleep <latency time>"]

Puoi configurare i timeout e le relative impostazioni per gestire l'arresto controllato dei pod durante lo scale down dei carichi di lavoro. Puoi regolare i timeout in base a casi d'uso specifici. Ti consigliamo di iniziare con timeout più lunghi e di ridurre la durata in base alle necessità. Puoi personalizzare i timeout configurando i parametri correlati al timeout e preStopHook nei seguenti modi:

Timeout dello svuotamento del servizio di backend

Il parametro Backend Service Drain Timeout non è impostato per impostazione predefinita e non ha alcun effetto. Se imposti il parametro Backend Service Drain Timeout e lo attivi, il bilanciatore del carico interrompe il routing delle nuove richieste all'endpoint e attende il timeout prima di terminare le connessioni esistenti.

Puoi impostare il parametro Backend Service Drain Timeout utilizzando BackendConfig con Ingress, GCPBackendPolicy con il gateway o manualmente su BackendService con NEG autonomi. Il timeout dovrebbe essere da 1,5 a 2 volte più lungo del tempo necessario per elaborare una richiesta. Ciò garantisce che se una richiesta venga inviata poco prima dell'avvio dello svuotamento, verrà completata prima del completamento del timeout. L'impostazione del parametro Backend Service Drain Timeout su un valore maggiore di 0 consente di mitigare gli errori 503 perché non vengono inviate nuove richieste agli endpoint di cui è stata pianificata la rimozione. Affinché questo timeout sia effettivo, devi utilizzarlo insieme a preStopHook per assicurarti che il pod rimanga attivo durante lo svuotamento. Senza questa combinazione, le richieste esistenti non completate riceveranno un errore 502.

preStopHook volta

preStopHook deve ritardare l'arresto del pod a sufficienza affinché la latenza di svuotamento e il timeout dello svuotamento del servizio di backend vengano completati, garantendo un corretto svuotamento della connessione e la rimozione degli endpoint dal NEG prima dell'arresto del pod.

Per risultati ottimali, assicurati che il tempo di esecuzione di preStopHook sia inferiore o uguale alla somma di Backend Service Drain Timeout e della latenza di svuotamento.

Può essere calcolato utilizzando la formula:

preStopHook >= Backend Service Drain Timeout + Drain Latency

Ti consigliamo di impostare la latenza di svuotamento su 1 minuto. Se persistono 500 errori, stima la durata totale dell'occorrenza e aggiungi il doppio di questo tempo alla latenza. Ciò garantisce che il pod abbia tempo a sufficienza per essere scaricato prima di essere rimosso dal servizio. Puoi modificare questo valore se è troppo lungo per il tuo caso d'uso specifico.

In alternativa, puoi stimare i tempi esaminando il timestamp di eliminazione dal pod e il timestamp in cui l'endpoint è stato rimosso dal NEG in Cloud Audit Logs.

Parametro del periodo di tolleranza per la risoluzione

Devi configurare il parametro terminationGracePeriod per concedere tempo sufficiente per il completamento di preStopHook e per il completamento di un arresto controllato dal pod.

Per impostazione predefinita, se non è impostata esplicitamente, terminationGracePeriod è di 30 secondi. Puoi calcolare il valore ottimale di terminationGracePeriod utilizzando la formula:

terminationGracePeriod >= preStopHook Time + Pod shutdown time

Per definire terminationGracePeriod all'interno della configurazione del pod come segue:

  spec:
    terminationGracePeriodSeconds: <terminationGracePeriod>
    containers:
    - name: my-app
      ...
    ...

NEG non trovato durante la creazione di una risorsa Ingress interna

Quando crei un Ingress interno in GKE, potrebbe verificarsi il seguente errore:

Error syncing: error running backend syncing routine: googleapi: Error 404: The resource 'projects/PROJECT_ID/zones/ZONE/networkEndpointGroups/NEG' was not found, notFound

Questo errore si verifica perché il traffico in entrata per i bilanciatori del carico delle applicazioni interni richiede gruppi di endpoint di rete (NEG) come backend.

Negli ambienti o nei cluster VPC condivisi con criteri di rete abilitati, aggiungi l'annotazione cloud.google.com/neg: '{"ingress": true}' al manifest del servizio.

504 Timeout gateway: timeout della richiesta upstream

Quando accedi a un servizio da un ingresso interno in GKE, potrebbe verificarsi il seguente errore:

HTTP/1.1 504 Gateway Timeout
content-length: 24
content-type: text/plain

upsteam request timeout

Questo errore si verifica perché il traffico inviato agli Application Load Balancer interni viene inviato tramite proxy dai proxy proxy nell'intervallo di subnet solo proxy.

Per consentire il traffico dall'intervallo di subnet solo proxy, crea una regola firewall su targetPort del servizio.

Errore 400: valore non valido per il campo "resource.target"

Quando accedi a un servizio da un ingresso interno in GKE, potrebbe verificarsi il seguente errore:

Error syncing:LB_NAME does not exist: googleapi: Error 400: Invalid value for field 'resource.target': 'https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION_NAME/targetHttpProxies/LB_NAME. A reserved and active subnetwork is required in the same region and VPC as the forwarding rule.

Per risolvere il problema, crea una subnet solo proxy.

Errore durante la sincronizzazione: errore durante l'esecuzione della routine di sincronizzazione del bilanciatore del carico: il bilanciatore del carico non esiste

Potrebbe verificarsi uno dei seguenti errori quando il piano di controllo GKE esegue l'upgrade o quando modifichi un oggetto Ingress:

"Error during sync: error running load balancer syncing routine: loadbalancer
INGRESS_NAME does not exist: invalid ingress frontend configuration, please
check your usage of the 'kubernetes.io/ingress.allow-http' annotation."

Oppure:

Error during sync: error running load balancer syncing routine: loadbalancer LOAD_BALANCER_NAME does not exist:
googleapi: Error 400: Invalid value for field 'resource.IPAddress':'INGRESS_VIP'. Specified IP address is in-use and would result in a conflict., invalid

Per risolvere questi problemi, prova a procedere nel seguente modo:

  • Aggiungi il campo hosts nella sezione tls del manifest Ingress, quindi elimina il file Ingress. Attendi cinque minuti affinché GKE elimini le risorse Ingress inutilizzate. Quindi, ricrea l'Ingress. Per ulteriori informazioni, consulta Il campo hosts di un oggetto Ingress.
  • Ripristina le modifiche apportate a Ingress. Quindi, aggiungi un certificato utilizzando un'annotazione o un secret di Kubernetes.

L'ingresso esterno genera errori HTTP 502

Segui queste indicazioni per risolvere gli errori HTTP 502 con risorse in entrata esterne:

  1. Abilita i log per ogni servizio di backend associato a ogni servizio GKE a cui fa riferimento l'oggetto Ingress.
  2. Utilizza i dettagli sullo stato per identificare le cause delle risposte HTTP 502. I dettagli dello stato che indicano la risposta HTTP 502 proveniente dal backend richiedono la risoluzione dei problemi all'interno dei pod di gestione, non nel bilanciatore del carico.

Gruppi di istanze non gestite

Potresti riscontrare errori HTTP 502 con risorse Ingress esterne se il tuo Ingress esterno utilizza backend di gruppi di istanze non gestiti. Questo problema si verifica quando vengono soddisfatte tutte le seguenti condizioni:

  • Il cluster ha un numero totale elevato di nodi in tutti i pool di nodi.
  • I pod di gestione di uno o più servizi a cui fa riferimento l'oggetto Ingress si trovano solo su pochi nodi.
  • I servizi a cui fa riferimento l'oggetto Ingress utilizzano externalTrafficPolicy: Local.

Per determinare se il tuo Ingress esterno utilizza backend di gruppi di istanze non gestiti:

  1. Vai alla pagina Ingress nella console Google Cloud.

    Vai a Ingress

  2. Fai clic sul nome del tuo Ingress esterno.

  3. Fai clic sul nome del Bilanciatore del carico. Viene visualizzata la pagina Dettagli bilanciamento del carico.

  4. Controlla la tabella nella sezione Servizi di backend per determinare se il tuo Ingress esterno utilizza NEG o gruppi di istanze.

Per risolvere il problema, utilizza una delle seguenti soluzioni:

  • Utilizza un cluster nativo di VPC.
  • Utilizza externalTrafficPolicy: Cluster per ogni servizio a cui fa riferimento l'oggetto Ingress esterno. Questa soluzione fa perdere l'indirizzo IP client originale nelle origini del pacchetto.
  • Utilizza l'annotazione node.kubernetes.io/exclude-from-external-load-balancers=true. Aggiungi l'annotazione ai nodi o ai pool di nodi che non eseguono pod di pubblicazione per alcun servizio a cui fa riferimento un servizio Ingress o LoadBalancer esterno nel tuo cluster.

Utilizzare i log del bilanciatore del carico per la risoluzione dei problemi

Puoi utilizzare i log del bilanciatore del carico di rete passthrough interno e i log del bilanciatore del carico di rete passthrough esterno per risolvere i problemi relativi ai bilanciatori del carico e correlare il traffico dai bilanciatori del carico alle risorse GKE.

I log vengono aggregati per connessione ed esportati quasi in tempo reale. I log vengono generati per ciascun nodo GKE coinvolto nel percorso dati di un servizio LoadBalancer, sia per il traffico in entrata che in uscita. Le voci di log includono campi aggiuntivi per le risorse GKE, tra cui: - Nome cluster - Località cluster - Nome servizio - Spazio dei nomi servizio - Nome pod - Spazio dei nomi pod

Prezzi

Non sono previsti costi aggiuntivi per l'utilizzo dei log. In base a come importi i log, si applicano i prezzi standard per Cloud Logging, BigQuery o Pub/Sub. L'abilitazione dei log non ha alcun effetto sulle prestazioni del bilanciatore del carico.

Utilizzare gli strumenti di diagnostica per risolvere i problemi

Lo strumento di diagnostica check-gke-ingress ispeziona le risorse Ingress per individuare gli errori di configurazione più comuni. Puoi utilizzare lo strumento check-gke-ingress nei seguenti modi:

  • Esegui lo strumento a riga di comando di gcpdiag sul tuo cluster. I risultati in entrata vengono visualizzati nella sezione della regola di controllo gke/ERR/2023_004.
  • Usa lo strumento check-gke-ingress da solo o come plug-in kubectl seguendo le istruzioni in check-gke-ingress.

Passaggi successivi

Se hai bisogno di ulteriore aiuto, contatta l'assistenza clienti Google Cloud.