Cosa sono i finalizzatori in Kubernetes? Come gestire le eliminazioni di oggetti

0
158

Le eliminazioni di oggetti Kubernetes non sono così semplici come sembrano sul superficie. L'eliminazione di un oggetto è un processo coinvolto che include controlli condizionali per determinare se è possibile una rimozione sicura. Ciò si ottiene tramite oggetti API chiamati Finalizzatori.

In questo articolo, esamineremo cosa sono i Finalizzatori, come vengono gestiti e le sfide che possono causare quando si desidera eliminare un oggetto. Avere una migliore comprensione del processo di eliminazione può aiutarti a eseguire il debug dei problemi in cui le risorse non sembrano terminare in modo tempestivo.

Che cosa sono i finalizzatori?

h2>

I finalizzatori sono un meccanismo per far rispettare determinate condizioni prima che un oggetto possa essere eliminato. Quando esegui un comando come kubectl delete namespace/example, Kubernetes controlla i Finalizzatori definiti sull'oggetto di riferimento. Questi sono elencati nel suo campo metadata.finalizers. Ciascun Finalizer ha la possibilità di posticipare l'eliminazione fino a quando non ha completato le sue azioni.

Il processo di eliminazione effettivo finisce per assomigliare a questo:

  1. Emetti un comando di eliminazione. – Kubernetes contrassegna l'oggetto come eliminazione in sospeso. Questo lascia la risorsa in sola lettura “Terminazione” stato.
  2. Esegui ciascuna delle azioni associate ai Finalizzatori dell'oggetto. – Ogni volta che un'azione di Finalizer viene completata, il Finalizer viene scollegato dall'oggetto, quindi non apparirà più nel campo metadata.finalizers.
  3. Kubernetes continua a monitorare i Finalizer allegati all'oggetto . – L'oggetto verrà eliminato una volta che il campo metadata.finalizers è vuoto, poiché tutti i Finalizzatori sono stati rimossi al completamento delle loro azioni.

I finalizzatori vengono comunemente utilizzati per eseguire procedure di pulizia e raccolta dati obsoleti prima che un oggetto venga rimosso dal cluster. Puoi aggiungere i tuoi finalizzatori utilizzando l'API Kubernetes; I finalizzatori integrati vengono applicati automaticamente anche ad alcuni tipi di oggetti.

Ad esempio, le risorse PersistentVolume sono dotate di un finalizzatore kubernetes.io/pv-protection che impedisce l'eliminazione accidentale dei volumi in uso attivo da parte dei pod. Il Finalizer impone che il PersistentVolume non possa essere rimosso dal cluster finché non ci sono pod che lo utilizzano. L'invio di un comando di eliminazione mentre c'è ancora un Pod attivo farà sì che il volume venga contrassegnato come terminato; rimarrà in questo stato per tutto il tempo in cui il Pod avrà bisogno del volume, quindi verrà eliminato automaticamente il prima possibile.

Sfide Finalizer

I finalizzatori di lunga durata che attendono una condizione che coinvolge altre risorse possono far apparire le eliminazioni bloccate nello stato Terminating. Potresti anche riscontrare problemi in cui un Finalizer blocca l'eliminazione degli oggetti dipendenti impedendo al genitore di terminare correttamente.

Pubblicità

Questi problemi causano regolarmente confusione – sviluppatori e operatori tendono a vedere le eliminazioni come procedure semplici quando il processo è in realtà sfumato e variabile. I prerequisiti per una corretta eliminazione dipendono dalle relazioni della risorsa e dai relativi Finalizzatori, nonché dall'oggetto di destinazione stesso.

Quando un oggetto è stato terminato per troppo tempo, controlla i suoi Finalizzatori controllando il campo metadata.finalizers nel suo YAML:

kubectl get pod example-pod –namespace example -o json | jq

Una volta che sai quali finalizzatori sono definiti, puoi iniziare a identificare quelli che potrebbero bloccare un'eliminazione. La visualizzazione degli eventi dell'oggetto e delle modifiche alle condizioni può aiutare il debug mostrando le azioni che si sono verificate da quando è stato emesso il comando di eliminazione. Le condizioni sono mostrate nel campo spec.status.conditions di YAML; gli eventi sono visibili durante l'esecuzione di kubectl describe pod example-pod.

Puoi rimuovere manualmente i finalizzatori di un oggetto applicando una patch al campo spec.finalizers su null. Questa tecnica non dovrebbe essere utilizzata a meno che non sia assolutamente necessario. I finalizzatori sono salvaguardie intese a proteggere il tuo cluster; sovrascriverli potrebbe portare a oggetti orfani e catene di dipendenze rotte.

kubectl patch pod example-pod -p '{“metadata: {“finalizers”: null}}'

Proprietari e criteri di propagazione

Un argomento correlato è i proprietari degli oggetti e le politiche di propagazione dell'eliminazione. I riferimenti del proprietario definiscono le relazioni tra gli oggetti. Vengono utilizzati per rimuovere interi alberi di oggetti quando un genitore viene eliminato. Ad esempio, se elimini una distribuzione, Kubernetes deve distruggere anche i pod all'interno quella distribuzione.

I riferimenti del proprietario sono definiti tramite il campo metadata.ownerReferences sugli oggetti. Ciascun riferimento include il tipo e il nome dell'oggetto a cui inviare la risorsa corrente.

Pubblicità

Quando vengono utilizzati i riferimenti del proprietario, l'eliminazione di un genitore rimuove automaticamente tutti i suoi figli. Questo è chiamato eliminazione a cascata. È possibile disabilitare la cascata aggiungendo il flag –cascade=orphan a kubectl delete. Kubernetes consentirà ai figli dell'oggetto di rimanere nel cluster, lasciandoli disponibili ma orfani.

Kubernetes supporta anche diverse “politiche di propagazione.” Questi definiscono se il genitore oi suoi figli vengono eliminati per primi. La politica in primo piano predefinita elimina i figli e quindi il genitore, assicurando che non si verifichino orfani. Lo sfondo inverte l'ordine in modo che il genitore venga rimosso per primo. La terza norma, Orphan, indica a Kubernetes di ignorare del tutto i riferimenti del proprietario.

Il comando kubectl delete non supporta le politiche di propagazione. È necessario effettuare una richiesta API diretta se si desidera modificare la politica per un'operazione di eliminazione:

curl -X DELETE localhost/api/v1/namespaces/default/deployments/example -d '{“apiVersion”: “v1”, “kind”: “DeleteOptions”, “propagationPolicy”: “Background”}' -H “Content-Type: application/json”

I finalizzatori vengono rispettati quando un'eliminazione viene propagata o sovrapposta a oggetti correlati. Nel caso della politica in primo piano, ciò significa che tutti i Finalizzatori su tutti i bambini dovranno completare prima che il genitore possa terminare. Per le norme in background, i bambini rimarranno attivi fino al termine dei finalizzatori dei loro genitori.

Implementazione dei finalizzatori

Puoi implementare i tuoi finalizzatori utilizzando l'API Kubernetes e l'SDK Go. I finalizzatori vengono creati registrando gli hook nel metodo Reconcile di un controller.

Il metodo dovrebbe verificare se l'oggetto da riconciliare ha un valore nel campo DeleteTimestamp. Ciò significa che è in attesa di eliminazione ed è nello stato Terminating. Scegli un identificatore per il tuo finalizzatore e controlla se l'oggetto include il valore nel suo campo metadata.finalizers. In tal caso, eseguire tutte le azioni necessarie e quindi scollegare il Finalizer dall'oggetto. Un'implementazione di esempio è inclusa nella guida Kubebuilder per scrivere i propri tipi di oggetti Kubernetes utilizzando CRD (definizioni di risorse personalizzate).

I finalizzatori sono sempre implementati come codice in un metodo controller. Il campo metadata.finalizers agisce in modo simile alle annotazioni e alle etichette, elencando i Finalizzatori da applicare a quell'oggetto senza definire direttamente il codice da eseguire.

Conclusione

I finalizzatori controllano il ciclo di vita di un oggetto Kubernetes dopo l'avvio dell'eliminazione. Vengono utilizzati per implementare la raccolta dei rifiuti, notificare ai controller le rimozioni imminenti e prevenire l'eliminazione accidentale di oggetti a cui fanno ancora riferimento altre risorse.

Pubblicità

Perché i finalizzatori possono bloccare le eliminazioni di oggetti per periodi di tempo arbitrariamente lunghi, sono una comune fonte di frustrazione quando i team operativi non capiscono perché un oggetto è “bloccato” terminando. In questa situazione è meglio ispezionare le risorse interessate, vedere quali finalizzatori sono attivi ed esaminare le relazioni tra oggetti che potrebbero agire come dipendenze di blocco. La rimozione forzata di un finalizzatore dovrebbe essere la tua ultima risorsa se devi eliminare immediatamente un oggetto di terminazione o hai esaurito tutte le altre opzioni.