Quando gestisci i cluster standard di Google Kubernetes Engine (GKE), i problemi con i pool di nodi possono interrompere le operazioni critiche. Questi problemi possono impedirti di scalare orizzontalmente i carichi di lavoro per soddisfare la domanda o di eseguire upgrade essenziali dell'infrastruttura, il che potrebbe influire sull'affidabilità della tua applicazione.
Utilizza questa pagina per risolvere questi problemi comuni dei pool di nodi. Trova indicazioni su come verificare se hai risorse insufficienti, utilizzare funzionalità come il provisioning con il massimo impegno per creare nodi ed eseguire la migrazione in sicurezza dei carichi di lavoro senza causare interruzioni.
Queste informazioni sono importanti per gli amministratori e gli operatori della piattaforma responsabili della gestione dell'infrastruttura dei cluster. Possono essere utili anche per gli sviluppatori di applicazioni che devono capire in che modo le limitazioni dei pool di nodi potrebbero influire sui deployment delle loro applicazioni. Per saperne di più sui ruoli comuni e sulle attività di esempio a cui facciamo riferimento nei Google Cloud contenuti, consulta Ruoli e attività comuni degli utenti GKE .
Problemi di creazione dei pool di nodi
Questa sezione elenca i problemi che potrebbero verificarsi durante la creazione di nuovi pool di nodi nei cluster standard e fornisce suggerimenti su come risolverli.
Problema: la creazione del pool di nodi non riesce a causa di risorse insufficienti
Il seguente problema si verifica quando crei un pool di nodi con hardware specifico in una Google Cloud zona che non dispone di hardware sufficiente per soddisfare i tuoi requisiti.
Per verificare che la creazione del pool di nodi non sia riuscita perché una zona non aveva risorse sufficienti, controlla i log per individuare i messaggi di errore pertinenti.
Vai a Esplora log nella Google Cloud console:
Nel campo Query, specifica la seguente query:
log_id(cloudaudit.googleapis.com/activity) resource.labels.cluster_name="CLUSTER_NAME" protoPayload.status.message:("ZONE_RESOURCE_POOL_EXHAUSTED" OR "does not have enough resources available to fulfill the request" OR "resource pool exhausted" OR "does not exist in zone")Sostituisci
CLUSTER_NAMEcon il nome del tuo cluster GKE.Fai clic su Esegui query.
Potresti visualizzare uno dei seguenti messaggi di errore:
resource pool exhaustedThe zone does not have enough resources available to fulfill the request. Try a different zone, or try again later.ZONE_RESOURCE_POOL_EXHAUSTEDZONE_RESOURCE_POOL_EXHAUSTED_WITH_DETAILSMachine type with name 'MACHINE_NAME' does not exist in zone 'ZONE_NAME'
Per risolvere il problema, prova i seguenti suggerimenti:
- Assicurati che la regione o la zona selezionata disponga dell'hardware specifico di cui hai bisogno. Google Cloud Utilizza la tabella di disponibilità di Compute Engine per verificare se zone specifiche supportano hardware specifici. Scegli una regione o una zona diversa Google Cloud per i nodi che potrebbero avere una migliore disponibilità dell'hardware di cui hai bisogno.
- Crea il pool di nodi con tipi di macchina più piccoli. Aumenta il numero di nodi nel pool di nodi in modo che la capacità di calcolo totale rimanga la stessa.
- Utilizza la prenotazione della capacità di Compute Engine per prenotare le risorse in anticipo.
- Utilizza il provisioning con il massimo impegno, descritto nella sezione seguente, per creare correttamente il pool di nodi se può eseguire il provisioning di almeno un numero minimo specificato di nodi rispetto al numero richiesto.
Provisioning con il massimo impegno
Per determinati hardware, puoi utilizzare il provisioning con il massimo impegno, che indica a GKE di creare correttamente il pool di nodi se può eseguire il provisioning di almeno un numero minimo specificato di nodi. Nel tempo, GKE continua a tentare di eseguire il provisioning dei nodi rimanenti per soddisfare la richiesta originale. Per indicare a GKE di utilizzare il provisioning con il massimo impegno, utilizza il seguente comando:
gcloud container node-pools create NODE_POOL_NAME \
--cluster=CLUSTER_NAME \
--location=CONTROL_PLANE_LOCATION \
--node-locations=ZONE1,ZONE2,... \
--machine-type=MACHINE_TYPE
--best-effort-provision \
--min-provision-nodes=MINIMUM_NODES
Sostituisci quanto segue:
NODE_POOL_NAME: il nome del nuovo pool di nodi.CONTROL_PLANE_LOCATION: la località di Compute Engine del control plane del tuo cluster. Fornisci una regione per i cluster regionali o una zona per i cluster a livello di zona.ZONE1,ZONE2,...: le zone di Compute Engine per i nodi. Queste zone devono supportare l'hardware selezionato.MACHINE_TYPE: il tipo di macchina di Compute Engine per i nodi. Ad esempio,a2-highgpu-1g.MINIMUM_NODES: il numero minimo di nodi di cui GKE deve eseguire il provisioning e creare correttamente il pool di nodi. Se omesso, il valore predefinito è1.
Ad esempio, considera uno scenario in cui hai bisogno di 10 nodi con GPU NVIDIA A100 da 40 GB collegate in us-central1-c. In base alle
località delle GPU,
questa zona supporta le GPU A100. Per evitare che la creazione del pool di nodi non riesca se non sono disponibili 10 macchine GPU, utilizza il provisioning con il massimo impegno.
gcloud container node-pools create a100-nodes \
--cluster=ml-cluster \
--location=us-central1 \
--node-locations=us-central1-c \
--num-nodes=10 \
--machine-type=a2-highgpu-1g \
--accelerator=type=nvidia-tesla-a100,count=1 \
--best-effort-provision \
--min-provision-nodes=5
GKE crea il pool di nodi anche se in us-central1-c sono disponibili solo cinque GPU. Nel tempo, GKE tenta di eseguire il provisioning di altri nodi finché non ce ne sono 10 nel pool di nodi.
Errore: l'istanza non contiene i metadati "instance-template"
Potresti visualizzare il seguente errore come stato di un pool di nodi per cui non è stato possibile eseguire l'upgrade, la scalabilità o la riparazione automatica dei nodi:
Instance INSTANCE_NAME does not contain 'instance-template' metadata
Questo errore indica che i metadati delle istanze VM, allocati da GKE, sono stati danneggiati. In genere, questo accade quando script o automazione creati personalizzati tentano di aggiungere nuovi metadati dell'istanza (ad esempio
block-project-ssh-keys) e, anziché aggiungere o aggiornare solo i valori, eliminano anche i metadati esistenti.
Puoi leggere i metadati delle istanze VM in
Impostazione dei metadati personalizzati.
Se uno dei valori dei metadati critici (tra gli altri: instance-template, kube-labels, kubelet-config, kubeconfig, cluster-name, configure-sh, cluster-uid) è stato eliminato, il nodo o l'intero pool di nodi potrebbe diventare instabile, poiché questi valori sono fondamentali per le operazioni GKE.
Se i metadati dell'istanza sono stati danneggiati, ti consigliamo di recuperarli ricreando il pool di nodi che contiene le istanze VM danneggiate. Dovrai aggiungere un pool di nodi al cluster e aumentare il numero di nodi nel nuovo pool, mentre contrassegni come non pianificabili e rimuovi i nodi in un altro pool. Consulta le istruzioni per eseguire la migrazione dei carichi di lavoro tra i pool di nodi.
Per scoprire chi e quando sono stati modificati i metadati dell'istanza, puoi esaminare le informazioni di audit logging di Compute Engine o trovare i log utilizzando Esplora log con una query di ricerca simile alla seguente:
resource.type="gce_instance_group_manager"
protoPayload.methodName="v1.compute.instanceGroupManagers.setInstanceTemplate"
Nei log puoi trovare l'indirizzo IP e lo user agent dell'origine della richiesta. Ad esempio:
requestMetadata: {
callerIp: "REDACTED"
callerSuppliedUserAgent: "google-api-go-client/0.5 GoogleContainerEngine/v1"
}
Eseguire la migrazione dei carichi di lavoro tra i pool di nodi
Segui queste istruzioni per eseguire la migrazione dei carichi di lavoro da un pool di nodi a un altro pool di nodi. Se vuoi modificare gli attributi della macchina dei nodi in nel pool di nodi, consulta Scalare verticalmente modificando gli attributi della macchina dei nodi.
Informazioni su come eseguire la migrazione dei pod a un nuovo pool di nodi
Per eseguire la migrazione dei pod a un nuovo pool di nodi, devi:
Contrassegnare i nodi nel pool di nodi esistente come non pianificabili: questa operazione contrassegna i nodi del pool di nodi esistente come non pianificabili. Quando li contrassegni come non pianificabili , Kubernetes smette di pianificare nuovi pod in questi nodi.
Svuotare i nodi nel pool di nodi esistente: questa operazione rimuove in modo controllato i carichi di lavoro in esecuzione sui nodi del pool di nodi esistente.
Questi passaggi, eseguiti singolarmente per ogni nodo, causano l'arresto controllato dei pod in esecuzione nel pool di nodi esistente. Kubernetes li ripianifica su altri nodi disponibili.
Per assicurarti che Kubernetes arresti le applicazioni in modo controllato, i container
devono gestire il segnale SIGTERM. Utilizza questo approccio per chiudere le connessioni attive ai client ed eseguire il commit o il rollback delle transazioni di database in modo pulito. Nel manifest del pod, puoi utilizzare il campo spec.terminationGracePeriodSeconds per specificare per quanto tempo Kubernetes deve attendere prima di arrestare i container nel pod. Il valore predefinito è 30 secondi.
Puoi saperne di più sull'arresto dei pod
nella documentazione di Kubernetes.
Puoi contrassegnare i nodi come non pianificabili e svuotarli utilizzando i comandi kubectl cordon e kubectl drain.
Creare un pool di nodi ed eseguire la migrazione dei carichi di lavoro
Per eseguire la migrazione dei carichi di lavoro a un nuovo pool di nodi, crea il nuovo pool di nodi, quindi contrassegna come non pianificabili e svuota i nodi nel pool di nodi esistente:
Aggiungi un pool di nodi al tuo cluster.
Verifica che il nuovo pool di nodi sia stato creato eseguendo il seguente comando:
gcloud container node-pools list --cluster CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATIONSostituisci quanto segue:
CLUSTER_NAME: il nome del cluster.CONTROL_PLANE_LOCATION: la località di Compute Engine del control plane del tuo cluster. Fornisci una regione per i cluster regionali o una zona per i cluster a livello di zona.
Per disabilitare la scalabilità automatica nel pool di nodi esistente, se è abilitata, esegui il seguente comando:
gcloud container clusters update CLUSTER_NAME --location=CONTROL_PLANE_LOCATION \ --no-enable-autoscaling \ --node-pool=EXISTING_NODE_POOL_NAMEEsegui il seguente comando per vedere su quale nodo sono in esecuzione i pod (vedi la colonna
NODE):kubectl get pods -o=wideRecupera un elenco di nodi nel pool di nodi esistente, sostituendo
EXISTING_NODE_POOL_NAMEcon il nome:kubectl get nodes -l cloud.google.com/gke-nodepool=EXISTING_NODE_POOL_NAMEEsegui il comando
kubectl cordon NODE(sostituisciNODEcon i nomi del comando precedente). Il seguente comando shell scorre ogni nodo nel pool di nodi esistente e li contrassegna come non pianificabili:for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=EXISTING_NODE_POOL_NAME -o=name); do kubectl cordon "$node"; done(Facoltativo) Aggiorna i carichi di lavoro in esecuzione nel pool di nodi esistente per aggiungere un nodeSelector per l'etichetta
cloud.google.com/gke-nodepool:NEW_NODE_POOL_NAME, doveNEW_NODE_POOL_NAMEè il nome del nuovo pool di nodi. In questo modo, GKE inserisce questi carichi di lavoro sui nodi del nuovo pool di nodi.Svuota ogni nodo eliminando tutti i pod con un periodo di arresto controllato assegnato di 10 secondi:
for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=EXISTING_NODE_POOL_NAME -o=name); do kubectl drain --force --ignore-daemonsets --delete-emptydir-data --grace-period=GRACEFUL_TERMINATION_SECONDS "$node"; doneSostituisci
GRACEFUL_TERMINATION_PERIOD_SECONDScon la quantità di tempo necessaria per l'arresto controllato.Verifica che i nodi nel pool di nodi esistente abbiano lo stato
SchedulingDisablednell'elenco dei nodi eseguendo il seguente comando:kubectl get nodesInoltre, dovresti vedere che i pod sono ora in esecuzione sui nodi del nuovo pool di nodi:
kubectl get pods -o=wideElimina il pool di nodi esistente se non ti serve:
gcloud container node-pools delete default-pool --cluster CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION
Passaggi successivi
Se non riesci a trovare una soluzione al tuo problema nella documentazione, consulta Richiedere assistenza per ulteriore aiuto, inclusi consigli sui seguenti argomenti:
- Aprire una richiesta di assistenza contattando l'assistenza clienti Google Cloud.
- Ottenere assistenza dalla community ponendo domande su Stack Overflow e utilizzando il tag
google-kubernetes-engineper cercare problemi simili. Puoi anche unirti al#kubernetes-enginecanale Slack per ulteriore assistenza dalla community. - Aprire richieste di funzionalità o problemi utilizzando lo strumento di monitoraggio dei problemi pubblico.