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 scegliere come target direttamente i pod Kubernetes e di distribuire il traffico ai pod in modo uniforme.
Per ulteriori informazioni su vantaggi, requisiti e limitazioni del bilanciamento del carico nativo del container, consulta Bilanciamento del carico nativo del container.
Utilizza il bilanciamento del carico nativo del container
Le sezioni seguenti illustrano la configurazione del bilanciamento del carico nativo 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 è predefinito e non richiede un'annotazione di servizio cloud.google.com/neg: '{"ingress": true}'
esplicita.
Crea un cluster nativo di VPC
Per utilizzare il bilanciamento del carico nativo del container, nel cluster GKE devono essere abilitati gli IP alias.
Ad esempio, il seguente comando crea un cluster GKE, neg-demo-cluster
, con una subnet di cui è stato eseguito il provisioning automatico:
Autopilot
In tutti i cluster Autopilot sono abilitati gli indirizzi IP alias.
gcloud container clusters create-auto neg-demo-cluster \
--location=us-central1
Standard
In modalità GKE Standard, abilita gli indirizzi IP alias quando crei il cluster:
gcloud container clusters create neg-demo-cluster \
--enable-ip-alias \
--create-subnetwork="" \
--network=default \
--zone=us-central1-a
Creazione di un deployment
Il seguente deployment di esempio neg-demo-app
esegue una singola istanza di un server HTTP containerizzato. Ti consigliamo di utilizzare carichi di lavoro che utilizzano feedback sull'idoneità dei pod.
Utilizzo del feedback sull'idoneità dei 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: registry.k8s.io/serve_hostname:v1.4 # Application to run in Deployment's Pods name: hostname # Container name ports: - containerPort: 9376 protocol: TCP
Utilizzo del 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: registry.k8s.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 come risposta 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:
kubectl apply -f neg-demo-app.yaml
Crea un servizio per un bilanciatore del carico nativo del container
Dopo aver creato un deployment, devi raggrupparne i 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:
kubectl apply -f neg-demo-svc.yaml
Crea una risorsa Ingress per il servizio
Il seguente esempio
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 il file Ingress:
kubectl apply -f neg-demo-ing.yaml
Al momento della creazione della risorsa Ingress, viene creato un Application Load Balancer nel progetto e i NEG vengono creati in ogni zona in cui viene eseguito il cluster. Gli endpoint nel NEG e gli endpoint del servizio vengono mantenuti sincronizzati.
Verifica il traffico in entrata
Dopo aver eseguito il deployment di un carico di lavoro, aver raggruppato i relativi pod in un servizio e creato una risorsa Ingress per il servizio, devi verificare che la risorsa Ingress abbia eseguito correttamente il provisioning del bilanciatore del carico nativo del container.
Recupera lo stato della risorsa Ingress:
kubectl describe ingress neg-demo-ing
L'output include 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
Testa il bilanciatore del carico
Le seguenti sezioni spiegano come testare la funzionalità di un bilanciatore del carico nativo del container.
Visita indirizzo IP Ingress
Attendi alcuni minuti per la configurazione dell'Application Load Balancer.
Puoi verificare che il bilanciatore del carico nativo del container funzioni visitando l'indirizzo IP della risorsa Ingress.
Per ottenere l'indirizzo IP Ingress, esegui questo comando:
kubectl get ingress neg-demo-ing
Nell'output comando, l'indirizzo IP del traffico in entrata è visualizzato nella colonna ADDRESS
. Visita l'indirizzo IP in un browser web.
Controlla lo stato di integrità del servizio di backend
Puoi anche ottenere lo stato di integrità del servizio di backend del bilanciatore del carico.
Recupera un elenco dei servizi di backend in esecuzione nel tuo progetto:
gcloud compute backend-services list
Registra il nome del servizio di backend che include il nome del servizio, ad esempio
neg-demo-svc
.Recupera lo stato di integrità del servizio di backend:
gcloud compute backend-services get-health BACKEND_SERVICE_NAME --global
Sostituisci
BACKEND_SERVICE_NAME
con il nome del servizio di backend.
Testa la risorsa Ingress
Un altro modo per verificare che il bilanciatore del carico funzioni come previsto consiste nello scalare il deployment di esempio, inviare richieste di test alla risorsa Ingress e verificare che risponda il numero corretto di repliche.
Scala il deployment
neg-demo-app
da una a due istanze:kubectl scale deployment neg-demo-app --replicas 2
Il completamento di questo comando potrebbe richiedere diversi minuti.
Verifica che l'implementazione sia stata completata:
kubectl get deployment neg-demo-app
L'output dovrebbe includere due repliche disponibili:
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE neg-demo-app 2 2 2 2 26m
Recupera l'indirizzo IP Ingress:
kubectl describe ingress neg-demo-ing
Se questo comando restituisce un errore 404, attendi qualche minuto per l'avvio del bilanciatore del carico, quindi riprova.
Conta 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.L'output è simile al seguente:
44 neg-demo-app-7f7dfd7bc6-dcn95 56 neg-demo-app-7f7dfd7bc6-jrmzf
In questo output, il numero di risposte distinte corrisponde al numero di repliche, che indica che tutti i pod di backend gestiscono il traffico.
Esegui la pulizia
Dopo aver completato le attività su questa pagina, segui questi passaggi per rimuovere le risorse ed evitare addebiti indesiderati sul tuo account:
Eliminare il cluster
gcloud
gcloud container clusters delete neg-demo-cluster
Console
Vai alla pagina Google Kubernetes Engine nella console Google Cloud.
Seleziona neg-demo-cluster e fai clic su delete Elimina.
Quando ti viene richiesto di confermare, fai clic su Elimina.
Risolvere i problemi
Utilizza le tecniche riportate di seguito per verificare la configurazione di 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 corrisponde 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 al servizio e le zone del NEG.Puoi verificare 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 suo 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
Visualizzi questo errore se tenti di creare un cluster con IP alias che utilizza anche una rete legacy.
- Risoluzione
Assicurati di non creare contemporaneamente un cluster con IP alias e una rete legacy. Per ulteriori informazioni sull'utilizzo di IP alias, consulta Creare un cluster nativo di VPC.
Il traffico non raggiunge gli endpoint
- Sintomi
- Errori 502 o connessioni rifiutate.
- Potenziali cause
In genere, i nuovi endpoint diventano raggiungibili dopo averli collegati al bilanciatore del carico, a condizione che rispondano ai controlli di integrità. Se il traffico non può raggiungere gli endpoint, potresti riscontrare errori 502 o connessioni rifiutate.
Gli errori 502 e le connessioni rifiutate possono essere causati anche da un container che non gestisce
SIGTERM
. Se un container non gestisce in modo esplicitoSIGTERM
, termina immediatamente e smette di gestire le richieste. Il bilanciatore del carico continua a inviare il 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 in modo che gestiscano
SIGTERM
e continuino a rispondere alle richieste durante il periodo di tolleranza per la terminazione (30 secondi per impostazione predefinita). Configura i pod in modo che inizino a non superare i controlli di integrità quando ricevonoSIGTERM
. Questo indica al bilanciatore del carico di interrompere l'invio di traffico al pod mentre è in corso la deprogrammazione degli endpoint.Se l'applicazione non si arresta correttamente e smette di rispondere alle richieste quando riceve un
SIGTERM
, è possibile utilizzare l'hook preStop per gestireSIGTERM
e continuare a gestire il traffico mentre è in corso la deprogrammazione dell'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 pod e 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 che l'unica istanza venga arrestata prima che la nuova istanza sia completamente programmata. Per i pod dell'applicazione gestiti dal carico di lavoro
Deployment
, è possibile ottenere questo risultato configurando la strategia di implementazione con il parametromaxUnavailable
uguale a0
.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 gli endpoint negli intervalli
130.211.0.0/22
e35.191.0.0/16
. Per saperne di più, consulta Aggiunta dei controlli di integrità nella documentazione di Cloud Load Balancing.Visualizza 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 non sono integri per un breve periodo di tempo, la causa potrebbe essere la latenza della programmazione di rete.
Se alcuni backend non sono visualizzati 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 i 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 un numero ridotto di backend (ad esempio, 1 pod) selezionati da un bilanciatore del carico nativo del container, valuta la possibilità di aumentare il numero di repliche e distribuire i pod di backend in tutte le zone distribuite dal cluster GKE. Ciò garantisce che l'infrastruttura sottostante del bilanciatore del carico sia completamente programmata. Altrimenti, valuta la possibilità di limitare i pod di backend a una singola zona.
Implementazione interrotta
- Sintomi
- L'implementazione di un deployment aggiornato si blocca e il numero di repliche aggiornate non corrisponde 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 in sequenza dei pod attende che il pod appena avviato superi la gate di idoneità del pod. Ciò 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 della soglia di idoneità non possono essere soddisfatte e l'implementazione non può continuare.
Se utilizzi
kubectl
1.13 o versioni successive, puoi controllare lo stato delle porte 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 statoREADY
potrebbe avere un gate di idoneità non riuscito. Per verificarlo, utilizza il seguente comando:kubectl get pod POD_NAME -o yaml
Le porte di idoneità e il relativo stato sono elencati nell'output.
- Risoluzione
Verifica che l'immagine container nella specifica dei 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:
Garbage collection incompleta
La garbage collection GKE raccoglie i bilanciatori del carico nativi del container ogni due minuti. Se un cluster viene eliminato prima della rimozione completa dei bilanciatori del carico, dovrai eliminare manualmente i NEG del bilanciatore del carico.
Visualizza i NEG nel tuo progetto eseguendo questo comando:
gcloud compute network-endpoint-groups list
Nell'output comando, cerca i NEG pertinenti.
Per eliminare un NEG, esegui il comando seguente, sostituendo NEG_NAME
con il nome del NEG:
gcloud compute network-endpoint-groups delete NEG_NAME
Allinea le implementazioni dei carichi di lavoro con la propagazione degli endpoint
Quando esegui il deployment di un carico di lavoro nel tuo cluster o quando aggiorni un carico di lavoro esistente, il bilanciatore del carico nativo del container può richiedere più tempo per propagare nuovi endpoint rispetto a quanto 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 l'implementazione alla propagazione degli endpoint: terminationGracePeriodSeconds
e minReadySeconds
.
terminationGracePeriodSeconds
consente al pod di arrestarsi in modo controllato attendendo che le connessioni terminino dopo che il pod è stato
pianificato per l'eliminazione.
minReadySeconds
aggiunge un periodo di latenza dopo la creazione
di un pod. Devi specificare un numero minimo di secondi durante i quali un nuovo pod deve trovarsi in stato Ready
, senza che si verifichi un arresto anomalo di nessuno dei suoi container, affinché il pod venga considerato disponibile.
Devi configurare i valori minReadySeconds
e terminationGracePeriodSeconds
dei carichi di lavoro in modo che abbiano una durata minima di 60 secondi per assicurarti che il servizio non venga interrotto a causa di implementazioni dei carichi di lavoro.
terminationGracePeriodSeconds
è disponibile in tutte le specifiche dei pod, mentre minReadySeconds
è disponibile per i deployment e i DaemonSet.
Per scoprire di più sul perfezionamento delle implementazioni, consulta la pagina RollingUpdateStrategy.
initialDelaySeconds
nel pod readinessProbe
non rispettata
È possibile che la configurazione initialDelaySeconds
in readinessProbe
del pod venga rispettata dal bilanciatore del carico nativo del container; tuttavia, readinessProbe
viene implementato da kubelet e la configurazione initialDelaySeconds
controlla il controllo di integrità di kubelet, non il bilanciatore del carico nativo del container. Il bilanciamento del carico nativo del container dispone di un proprio controllo di integrità del bilanciamento del carico.
Passaggi successivi
- Scopri di più sui NEG.
- Scopri di più sui cluster nativi di VPC.