Bilanciamento del carico nativo del container tramite Ingress

Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.

Questa pagina spiega come utilizzare il bilanciamento del carico nativo del container in Google Kubernetes Engine (GKE). Il bilanciamento del carico nativo del container consente ai bilanciatori del carico di indirizzare direttamente i pod Kubernetes e di distribuire uniformemente il traffico sui pod.

Consulta la pagina relativa al bilanciamento del carico nativo del container per informazioni su vantaggi, requisiti e limitazioni del bilanciamento del carico nativo del container.

Utilizzo del bilanciamento del carico nativo del container

Le seguenti sezioni illustrano una configurazione di bilanciamento del carico nativa del container su GKE. Tieni presente che per i cluster GKE che eseguono la versione 1.17 o successive e in determinate condizioni, il bilanciamento del carico nativo del container è l'impostazione predefinita e non richiede un'annotazione di servizio cloud.google.com/neg: '{"ingress": true}' esplicita.

Creazione di un cluster nativo di VPC

Per utilizzare il bilanciamento del carico nativo del container, devi creare un cluster con IP alias abilitati.

Ad esempio, il comando seguente crea un cluster, neg-demo-cluster, con una subnet di cui è stato eseguito il provisioning automatico nella zona us-central1-a:

gcloud container clusters create neg-demo-cluster \
    --enable-ip-alias \
    --create-subnetwork="" \
    --network=default \
    --zone=us-central1-a

Creazione di un deployment

Quindi, esegui il deployment di un carico di lavoro nel cluster.

Il seguente Deployment di esempio, neg-demo-app, esegue una singola istanza di un server HTTP containerizzato. Ti consigliamo di utilizzare i carichi di lavoro che utilizzano il feedback di idoneità del pod, se disponibile nella versione di GKE che stai utilizzando. Consulta l'idoneità dei pod per saperne di più e per i requisiti sulla versione di GKE. Valuta la possibilità di eseguire l'upgrade del cluster per utilizzare il feedback di preparazione al pod.

Utilizzo del feedback di idoneità del pod

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: neg-demo-app # Label for the Deployment
  name: neg-demo-app # Name of Deployment
spec:
  selector:
    matchLabels:
      run: neg-demo-app
  template: # Pod template
    metadata:
      labels:
        run: neg-demo-app # Labels Pods from this Deployment
    spec: # Pod specification; each Pod created by this Deployment has this specification
      containers:
      - image: k8s.gcr.io/serve_hostname:v1.4 # Application to run in Deployment's Pods
        name: hostname # Container name
        ports:
        - containerPort: 9376
          protocol: TCP
  

Utilizzare il ritardo hardcoded

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: neg-demo-app # Label for the Deployment
  name: neg-demo-app # Name of Deployment
spec:
  minReadySeconds: 60 # Number of seconds to wait after a Pod is created and its status is Ready
  selector:
    matchLabels:
      run: neg-demo-app
  template: # Pod template
    metadata:
      labels:
        run: neg-demo-app # Labels Pods from this Deployment
    spec: # Pod specification; each Pod created by this Deployment has this specification
      containers:
      - image: k8s.gcr.io/serve_hostname:v1.4 # Application to run in Deployment's Pods
        name: hostname # Container name
      # Note: The following line is necessary only on clusters running GKE v1.11 and lower.
      # For details, see https://cloud.google.com/kubernetes-engine/docs/how-to/container-native-load-balancing#align_rollouts
        ports:
        - containerPort: 9376
          protocol: TCP
      terminationGracePeriodSeconds: 60 # Number of seconds to wait for connections to terminate before shutting down Pods
  

In questo deployment, ogni container esegue un server HTTP. Il server HTTP restituisce semplicemente come nome host il nome host del server delle applicazioni (il nome del pod su cui viene eseguito il server).

Salva questo manifest come neg-demo-app.yaml, quindi crea il deployment eseguendo il comando seguente:

kubectl apply -f neg-demo-app.yaml

Creazione di un servizio per un bilanciatore del carico nativo del container

Dopo aver creato un deployment, devi raggruppare i relativi pod in un servizio.

Il seguente servizio di esempio, neg-demo-svc, ha come target il deployment di esempio che hai creato nella sezione precedente:

apiVersion: v1
kind: Service
metadata:
  name: neg-demo-svc # Name of Service
  annotations:
    cloud.google.com/neg: '{"ingress": true}' # Creates a NEG after an Ingress is created
spec: # Service's specification
  type: ClusterIP
  selector:
    run: neg-demo-app # Selects Pods labelled run: neg-demo-app
  ports:
  - name: http
    port: 80 # Service's port
    protocol: TCP
    targetPort: 9376

L'annotazione del servizio, cloud.google.com/neg: '{"ingress": true}', consente il bilanciamento del carico nativo del container. Tuttavia, il bilanciatore del carico non viene creato finché non crei una risorsa Ingress per il servizio.

Salva questo manifest come neg-demo-svc.yaml, quindi crea il servizio eseguendo il comando seguente:

kubectl apply -f neg-demo-svc.yaml

Creazione di una risorsa Ingress per il servizio

Il seguente esempio di Ingress, neg-demo-ing, ha come target il servizio che hai creato:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: neg-demo-ing
spec:
  defaultBackend:
    service:
      name: neg-demo-svc # Name of the Service targeted by the Ingress
      port:
        number: 80 # Should match the port used by the Service

Salva questo manifest come neg-demo-ing.yaml, quindi crea la risorsa Ingress eseguendo il comando seguente:

kubectl apply -f neg-demo-ing.yaml

Al momento della creazione di una risorsa Ingress, nel progetto viene creato un bilanciatore del carico HTTP(S) e NEG in ogni zona in cui viene eseguito il cluster. Gli endpoint nel NEG e gli endpoint del Servizio vengono mantenuti sincronizzati.

Verifica della risorsa Ingress

Dopo aver eseguito il deployment di un carico di lavoro, aver raggruppati i pod in un servizio e creato una risorsa Ingress per il servizio, devi verificare che la risorsa Ingress abbia eseguito il provisioning del bilanciatore del carico nativo del container.

Per recuperare lo stato della risorsa Ingress, esegui questo comando:

kubectl describe ingress neg-demo-ing

Nell'output comando, cerca gli eventi ADD e CREATE:

Events:
Type     Reason   Age                From                     Message
----     ------   ----               ----                     -------
Normal   ADD      16m                loadbalancer-controller  default/neg-demo-ing
Normal   Service  4s                 loadbalancer-controller  default backend set to neg-demo-svc:32524
Normal   CREATE   2s                 loadbalancer-controller  ip: 192.0.2.0

Test della funzionalità del bilanciatore del carico

Le sezioni seguenti spiegano come testare la funzionalità di un bilanciatore del carico nativo del container.

Visita l'indirizzo IP Ingress

Attendi diversi minuti per la configurazione del bilanciatore del carico HTTP(S).

Puoi verificare che il bilanciatore del carico nativo del container funzioni visitando l'indirizzo IP Ingress'.

Per ottenere l'indirizzo IP di Ingress, esegui il comando seguente:

kubectl get ingress neg-demo-ing

Nell'output comando, l'indirizzo IP Ingress' viene visualizzato nella colonna ADDRESS. Visita l'indirizzo IP in un browser web.

Controlla stato di integrità del servizio di backend

Puoi anche ottenere lo stato di integrità del servizio di backend del bilanciatore del carico.

  1. Recupero di un elenco dei servizi di backend in esecuzione nel progetto:

    gcloud compute backend-services list
    
  2. Copia il nome del backend che include il nome del servizio, ad esempio neg-demo-svc.

  3. Conoscere lo stato di integrità del servizio di backend:

    gcloud compute backend-services get-health BACKEND_SERVICE_NAME --global
    

Verifica della funzionalità Ingress

Un altro modo per testare il funzionamento del bilanciatore del carico è scalare il deployment di esempio, inviare richieste di test alla risorsa Ingress e verificare che il numero corretto di repliche risponda.

  1. Il seguente comando scala il deployment neg-demo-app da un'istanza a due istanze:

    kubectl scale deployment neg-demo-app --replicas 2
    
  2. Attendi qualche minuto per il completamento del lancio. Per verificare che l'implementazione sia completa, esegui questo comando:

    kubectl get deployment neg-demo-app
    
  3. Nell'output comando, verifica che siano disponibili due repliche:

    NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    neg-demo-app   2         2         2            2           26m
    
  4. Esegui il comando seguente per conteggiare il numero di risposte distinte dal bilanciatore del carico:

    for i in `seq 1 100`; do \
      curl --connect-timeout 1 -s IP_ADDRESS && echo; \
    done  | sort | uniq -c
    

    Sostituisci IP_ADDRESS con l'indirizzo IP Ingress. Per ottenere l'indirizzo IP di Ingress, esegui questo comando:

    kubectl describe ingress neg-demo-ing
    
  5. Nell'output comando, osserva che il numero di risposte distinte è uguale al numero di repliche, indicando che tutti i pod di backend gestiscono il traffico:

    44 neg-demo-app-7f7dfd7bc6-dcn95
    56 neg-demo-app-7f7dfd7bc6-jrmzf
    

Pulizia

Dopo aver completato le attività in questa pagina, segui questi passaggi per rimuovere le risorse al fine di evitare addebiti indesiderati sul tuo account:

Eliminare il cluster

gcloud

gcloud container clusters delete neg-demo-cluster

Console

  1. Vai alla pagina Google Kubernetes Engine in Google Cloud Console.

    Vai a Google Kubernetes Engine

  2. Seleziona neg-demo-cluster e fai clic su Elimina.

  3. Quando ti viene richiesto di confermare, fai clic su Elimina.

Risolvere i problemi

Utilizza le tecniche riportate di seguito per verificare la configurazione della tua rete. Le seguenti sezioni spiegano come risolvere problemi specifici relativi al bilanciamento del carico nativo del container.

  • Consulta la documentazione sul bilanciamento del carico per informazioni su come elencare i gruppi di endpoint di rete.

  • Puoi trovare il nome e le zone del NEG che corrispondono a un servizio nell'annotazione neg-status del servizio. Ottieni la specifica del servizio con:

    kubectl get svc SVC_NAME -o yaml
    

    L'annotazione metadata:annotations:cloud.google.com/neg-status elenca il nome del NEG corrispondente del servizio e le zone del NEG.

  • Puoi controllare l'integrità del servizio di backend che corrisponde a un NEG con il seguente comando:

    gcloud compute backend-services [--project PROJECT_NAME] \
        get-health BACKEND_SERVICE_NAME --global
    

    Il servizio di backend ha lo stesso nome del NEG.

  • Per stampare i log eventi di un servizio:

    kubectl describe svc SERVICE_NAME
    

    La stringa del nome del servizio include il nome e lo spazio dei nomi del servizio GKE corrispondente.

Impossibile creare un cluster con IP alias

Sintomi

Quando provi a creare un cluster con IP alias, potresti riscontrare il seguente errore:

ResponseError: code=400, message=IP aliases cannot be used with a legacy network.
Potenziali cause

Questo errore si verifica se tenti di creare un cluster con IP alias che utilizzano anche una rete legacy.

Risoluzione

Assicurati di non creare un cluster con IP alias e una rete legacy abilitata contemporaneamente. Per ulteriori informazioni sull'utilizzo degli IP alias, consulta Creazione di cluster nativi VPC mediante IP alias.

Il traffico non raggiunge gli endpoint

Sintomi
Errori 502 o connessioni rifiutate.
Potenziali cause

In genere, i nuovi endpoint diventano raggiungibili dopo il collegamento al bilanciatore del carico, purché rispondano a controlli di integrità. Potresti riscontrare errori 502 o connessioni rifiutate se il traffico non riesce a raggiungere gli endpoint.

Gli errori 502 e le connessioni rifiutate possono essere causati anche da un container che non gestisce SIGTERM. Se un container non gestisce esplicitamente SIGTERM, termina immediatamente e interrompe la gestione delle richieste. Il bilanciatore del carico continua a inviare traffico in entrata al container terminato, causando errori.

Il bilanciatore del carico nativo del container ha un solo endpoint di backend. Durante un aggiornamento in sequenza, il vecchio endpoint viene deprogrammato prima che il nuovo endpoint venga programmato.

Il deployment dei pod di backend viene eseguito in una nuova zona per la prima volta dopo il provisioning di un bilanciatore del carico nativo del container. L'infrastruttura del bilanciatore del carico è programmata in una zona quando è presente almeno un endpoint nella zona. Quando un nuovo endpoint viene aggiunto a una zona, l'infrastruttura del bilanciatore del carico è programmata e causa interruzioni del servizio.

Risoluzione

Configura i container per gestire SIGTERM e continua a rispondere alle richieste durante il periodo di tolleranza per la terminazione (30 secondi per impostazione predefinita). Configura i pod per iniziare a non superare i controlli di integrità quando ricevono SIGTERM. Questo indica al bilanciatore del carico di interrompere l'invio del traffico al pod mentre è in corso la depianificazione degli endpoint.

Se l'applicazione non si arresta in modo controllato e non risponde più alle richieste quando riceve un SIGTERM, può essere utilizzato l'hook prestop per gestire SIGTERM e continuare a gestire il traffico mentre è in corso la depianificazione degli endpoint.

lifecycle:
  preStop:
    exec:
      # if SIGTERM triggers a quick exit; keep serving traffic instead
      command: ["sleep","60"]

Per ulteriori informazioni, consulta la documentazione sulla terminazione dei pode questo post sulle best practice per la terminazione dei pod.

Se il backend del bilanciatore del carico ha una sola istanza, configura la strategia di implementazione per evitare l'eliminazione dell'unica istanza prima che la nuova istanza sia completamente programmata. Per i pod dell'applicazione gestiti dal carico di lavoro Deployment, questa operazione può essere ottenuta configurando la strategia di implementazione con il parametro maxUnavailable uguale a 0.

strategy:
  rollingUpdate:
    maxSurge: 1
    maxUnavailable: 0

Per risolvere i problemi relativi al traffico che non raggiunge gli endpoint, verifica che le regole firewall consentano il traffico TCP in entrata verso i tuoi endpoint negli intervalli 130.211.0.0/22 e 35.191.0.0/16. Per saperne di più, consulta la sezione Aggiungere controlli di integrità nella documentazione di Cloud Load Balancing.

Visualizzare i servizi di backend nel tuo progetto. La stringa del nome del servizio di backend pertinente include il nome e lo spazio dei nomi del servizio GKE corrispondente:

gcloud compute backend-services list

Recupera lo stato di integrità del backend dal servizio di backend:

gcloud compute backend-services get-health BACKEND_SERVICE_NAME

Se tutti i backend sono in stato non integro, il firewall, la risorsa Ingress o il servizio potrebbero essere configurati in modo errato.

Se alcuni backend sono in stato non integro per un breve periodo di tempo, la causa potrebbe essere la latenza della programmazione di rete.

Se alcuni backend non compaiono nell'elenco dei servizi di backend, la causa potrebbe essere la latenza di programmazione. Puoi verificarlo eseguendo questo comando, dove NEG_NAME è il nome del servizio di backend. (NEG e servizi di backend condividono lo stesso nome):

gcloud compute network-endpoint-groups list-network-endpoints NEG_NAME

Controlla se tutti gli endpoint previsti sono nel NEG.

Se hai selezionato un numero limitato di backend (ad esempio 1 pod) da un bilanciatore del carico nativo del container, valuta la possibilità di aumentare il numero di repliche e distribuisci i pod di backend in tutte le zone su cui si estende il cluster GKE. Ciò assicura che l'infrastruttura del bilanciatore del carico sottostante sia completamente programmata. Altrimenti, valuta la possibilità di limitare i pod di backend a una singola zona.

Implementazione bloccata

Sintomi
L'implementazione di un deployment Deployment aggiornato e il numero di repliche aggiornate non corrispondono al numero di repliche desiderato.
Potenziali cause

I controlli di integrità del deployment non vanno a buon fine. L'immagine container potrebbe essere errata o il controllo di integrità potrebbe essere configurato in modo errato. La sostituzione continua dei pod attende che il pod appena avviato superi il gateway di idoneità dei pod. Questo si verifica solo se il pod risponde ai controlli di integrità del bilanciatore del carico. Se il pod non risponde o se il controllo di integrità non è configurato correttamente, le condizioni del gateway di idoneità non possono essere soddisfatte e l'implementazione non può continuare.

Se utilizzi kubectl 1.13 o versioni successive, puoi controllare lo stato dei gateway di idoneità di un pod con il seguente comando:

kubectl get pod POD_NAME -o wide

Controlla la colonna READINESS GATES.

Questa colonna non esiste in kubectl 1.12 e versioni precedenti. Un pod contrassegnato come in stato READY potrebbe avere un gateway di idoneità non riuscito. Per verificarlo, utilizza il comando seguente:

kubectl get pod POD_NAME -o yaml

I controlli di idoneità e il relativo stato sono elencati nell'output.

Risoluzione

Verifica che l'immagine container nella specifica del pod del deployment funzioni correttamente e sia in grado di rispondere ai controlli di integrità. Verifica che i controlli di integrità siano configurati correttamente.

Problemi noti

Il bilanciamento del carico nativo del container su GKE presenta i seguenti problemi noti:

Raccolta dei rifiuti incompleta

La garbage GKE raccoglie i bilanciatori del carico nativi del container ogni due minuti. Se un cluster viene eliminato prima che i bilanciatori del carico siano completamente rimossi, devi eliminare manualmente il NEG del bilanciatore del carico.

Visualizza i NEG nel tuo progetto eseguendo il comando seguente:

gcloud compute network-endpoint-groups list

Nell'output comando, cerca il NEG pertinente.

Per eliminare un NEG, esegui il comando seguente, sostituendo NEG_NAME con il nome del NEG:

gcloud compute network-endpoint-groups delete NEG_NAME

Allineare le implementazioni dei carichi di lavoro con la propagazione degli endpoint

Quando esegui il deployment di un carico di lavoro nel cluster o quando aggiorni un carico di lavoro esistente, il bilanciatore del carico nativo del container può impiegare più tempo per propagare nuovi endpoint di quanto sia necessario per completare l'implementazione del carico di lavoro. Il deployment di esempio di cui esegui il deployment in questa guida utilizza due campi per allineare la sua implementazione al numero di endpoint: terminationGracePeriodSeconds e minReadySeconds.

terminationGracePeriodSeconds consente al pod di arrestare correttamente l'operazione in attesa dell'arresto delle connessioni dopo la pianificazione dell'eliminazione di un pod.

minReadySeconds aggiunge un periodo di latenza dopo la creazione di un pod. Puoi specificare un numero minimo di secondi per cui un nuovo pod deve trovarsi in stato Ready, senza che nessuno dei suoi container si arresti in modo anomalo, per poter essere considerato disponibile.

Devi configurare i valori dei carichi di lavoro minReadySeconds e terminationGracePeriodSeconds in modo che siano di 60 secondi o più per garantire che il servizio non venga interrotto a causa dell'implementazione dei carichi di lavoro.

terminationGracePeriodSeconds è disponibile in tutte le specifiche dei pod e minReadySeconds è disponibile per i deployment e i DaemonSet.

Per scoprire di più sull'ottimizzazione delle implementazioni, consulta RollingUpdateStrategy.

initialDelaySeconds nel pod readinessProbe non rispettato

Puoi aspettarti che la configurazione di initialDelaySeconds nel pod readinessProbe venga rispettata dal bilanciatore del carico nativo del container, ma readinessProbe venga implementata da kubelet e la configurazione initialDelaySeconds controlli il controllo di integrità kubelet, non il bilanciatore del carico nativo del container. Il bilanciamento del carico nativo del container ha il proprio controllo di integrità del bilanciamento.

Passaggi successivi