Condividi tramite


Configurare le politiche di interruzione per i nodi di auto-provisioning (NAP) nel servizio Azure Kubernetes (AKS)

Questo articolo spiega come configurare i criteri di interruzione per i nodi del servizio Azure Kubernetes (AKS) con provisioning automatico dei nodi e descrive in dettaglio il funzionamento delle interruzioni per ottimizzare l'utilizzo delle risorse e l'efficienza dei costi.

NAP ottimizza il cluster tramite:

  • Rimozione o sostituzione di nodi sottoutilizzati.
  • Consolidamento dei carichi di lavoro per ridurre i costi.
  • Rispetto dei budget di interruzione e delle finestre di manutenzione.
  • Fornire il controllo manuale quando necessario.

Prima di iniziare

Come funziona l'interruzione del nodo per i nodi Protezione accesso alla rete?

Karpenter imposta un finalizzatore Kubernetes su ogni nodo e richiesta del nodo di cui effettua il provisioning. Il finalizzatore blocca l'eliminazione dell'oggetto nodo, mentre il controller di terminazione si blocca e svuota il nodo prima di rimuovere l'attestazione del nodo sottostante.

Quando i carichi di lavoro nei nodi vengono ridotti, NAP utilizza regole di interruzione nella specifica del pool di nodi per decidere quando e come rimuovere tali nodi e potenzialmente riprogrammare i carichi di lavoro per garantire l'efficienza.

Metodi di interruzione del nodo

Protezione accesso alla rete scopre automaticamente i nodi idonei per l'interruzione e avvia le sostituzioni quando necessario. È possibile attivare interruzioni tramite metodi automatizzati come Scadenza, Consolidamento e Deriva, metodi manuali o sistemi esterni.

Scadenza

La scadenza consente di impostare un'età massima per i nodi di Protezione Accesso Rete. I nodi vengono contrassegnati come scaduti e interrotti dopo aver raggiunto l'età specificata per il valore di spec.disruption.expireAfter del pool di nodi.

Configurazione di scadenza di esempio

L'esempio seguente illustra come impostare l'ora di scadenza per i nodi nap su 24 ore:

spec:
  disruption:
    expireAfter: 24h  # Expire nodes after 24 hours

Consolidation

Il NAP lavora attivamente per ridurre il costo del cluster identificando quando i nodi possono essere rimossi perché sono vuoti o sottoutilizzati, o quando i nodi possono essere sostituiti con varianti a prezzo inferiore. Questo processo è denominato Consolidamento. NAP utilizza principalmente il consolidamento per eliminare o sostituire i nodi al fine di un posizionamento ottimale dei pod.

NAP esegue i seguenti tipi di consolidamento per ottimizzare l'utilizzo delle risorse:

  • Consolidamento di nodi vuoti: elimina tutti i nodi vuoti in parallelo.
  • Consolidamento di più nodi: elimina più nodi, eventualmente avviando una singola sostituzione.
  • Consolidamento a nodo singolo: elimina qualsiasi nodo singolo, eventualmente avviando una sostituzione.

È possibile attivare il consolidamento tramite il campo spec.disruption.consolidationPolicy nella specifica del pool di nodi, utilizzando le impostazioni WhenEmpty o WhenEmptyOrUnderUtilized. È possibile impostare anche il campo consolidateAfter, una condizione basata sul tempo che stabilisce quanto tempo la Protezione accesso alla rete attende prima di interrompere il nodo, dopo aver trovato un'opportunità di consolidamento.

Configurazione di consolidamento di esempio

L'esempio seguente illustra come configurare NAP per consolidare i nodi vuoti e attendere 30 secondi dopo aver individuato un'opportunità di consolidamento prima di interferire con il nodo:

  disruption:
    # Describes which types of nodes NAP should consider for consolidation
    # `WhenEmptyOrUnderUtilized`: NAP considers all nodes for consolidation and attempts to remove or replace nodes when it discovers that the node is empty or underutilized and could be changed to reduce cost
    # `WhenEmpty`: NAP only considers nodes for consolidation that don't contain any workload pods
    
    consolidationPolicy: WhenEmpty

    # The amount of time NAP should wait after discovering a consolidation decision
    # Currently, you can only set this value when the consolidation policy is `WhenEmpty`
    # You can choose to disable consolidation entirely by setting the string value `Never`
    consolidateAfter: 30s

Drift

La deriva gestisce le modifiche apportate alle NodePool/AKSNodeClass risorse. I valori in NodeClaimTemplateSpec/AKSNodeClassSpec vengono riflessi nello stesso modo in cui vengono impostati. Un NodeClaim viene rilevato come con deriva se i valori nell'NodePool/AKSNodeClass associato non corrispondono ai valori in NodeClaim. Analogamente alla relazione upstream deployment.spec.template con i pod, Karpenter annota l'oggetto associato a NodePool/AKSNodeClass con un hash del NodeClaimTemplateSpec, per verificare la deriva. Karpenter rimuove la Drifted condizione di stato negli scenari seguenti:

  • Il gate della funzionalità Drift non è abilitato, ma NodeClaim è con deriva.
  • L'oggetto NodeClaim non è in deriva, ma ha la condizione di stato.

Karpenter o l'interfaccia del provider di servizi cloud potrebbero individuare casi speciali attivati dalle NodeClaim/Instance/NodePool/AKSNodeClassmodifiche.

Casi speciali sulla deriva

In casi speciali, la deriva può corrispondere a più valori e deve essere gestita in modo diverso. La deriva nei campi risolti può creare casi in cui si verifica la deriva senza modifiche alle definizioni di risorse personalizzate (CRD) o in cui le modifiche CRD non comportano deviazioni.

Ad esempio, se un oggetto NodeClaim ha node.kubernetes.io/instance-type: Standard_D2s_v3e i requisiti cambiano da node.kubernetes.io/instance-type In [Standard_D2s_v3] a node.kubernetes.io/instance-type In [Standard_D2s_v3, Standard_D4s_v3], l'oggetto NodeClaim non viene derivato perché il relativo valore è ancora compatibile con i nuovi requisiti. Viceversa, se un NodeClaim usa un NodeClaimimageFamily, ma il campo spec.imageFamily cambia, Karpenter rileva NodeClaim come in deriva e ruota il nodo per soddisfare tale specifica.

Importante

Karpenter monitora le modifiche alla configurazione della subnet e rileva la deviazione quando il vnetSubnetID viene modificato in un AKSNodeClass. Comprendere questo comportamento è fondamentale quando si gestiscono configurazioni di rete personalizzate. Per altre informazioni, vedere Comportamento della deriva della subnet.

Per ulteriori informazioni, vedere Drift Design.

Periodo di tolleranza di terminazione

È possibile impostare un periodo di tolleranza di terminazione per i nodi NAP, usando il campo spec.template.spec.terminationGracePeriod nella specifica del pool di nodi. Questa impostazione consente di configurare per quanto tempo Karpenter attende il completamento normale dei pod. Questa impostazione ha la precedenza su terminationGracePeriodSeconds di un pod e bypassa PodDisruptionBudgets e l'annotazione karpenter.sh/do-not-disrupt.

Esempio di configurazione per il periodo di tolleranza di terminazione

L'esempio seguente illustra come impostare un periodo di tolleranza di terminazione di 30 secondi per i nodi nap:

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  template:
    spec:
      terminationGracePeriod: 30s

Budget di interruzione

È possibile limitare l'interruzione di Karpenter modificando il campo spec.disruption.budgets nella specifica del pool di nodi. Se si lascia questa impostazione non definita, Karpenter usa per impostazione predefinita un budget con nodes: 10%. I budget tengono conto dei nodi che vengono eliminati per qualsiasi motivo e impediscono a Karpenter solo le interruzioni volontarie dovute a scadenza, deriva, svuotamento e consolidamento.

Quando si determina se un budget protegge i nodi dalle interruzioni, Karpenter conta il numero totale di nodi di proprietà di un pool di nodi e quindi sottrae i nodi che stanno per essere eliminati e i nodi che sono NotReady. Se il budget è configurato con un valore percentuale, ad esempio 20%, Karpenter calcola il numero di interruzioni consentite come allowed_disruptions = roundup(total * percentage) - total_deleting - total_notready. Per più budget in un pool di nodi, Karpenter accetta il valore minimo (più restrittivo) di ognuno dei budget.

Campi programma e durata

Quando si usano i budget, è possibile impostare facoltativamente i schedule campi e duration per creare budget basati sul tempo. Questi campi consentono di definire finestre di manutenzione o intervalli di tempo specifici quando i limiti di interruzione sono più rigorosi.

  • La pianificazione usa la sintassi del processo cron con macro speciali come @yearly, @monthly@weekly, @daily@hourly.
  • La durata consente durate composte come 10h5m, 30mo 160h. La durata e la pianificazione devono essere definite insieme.

Esempi di pianificazione e durata

Budget della finestra di manutenzione

Evitare interruzioni durante l'orario di ufficio:

budgets:
- nodes: "0"
  schedule: "0 9 * * 1-5"  # 9 AM Monday-Friday
  duration: 8h             # For 8 hours
Interruzioni solo fine settimana

Consenti solo interruzioni nei fine settimana:

budgets:
- nodes: "50%"
  schedule: "0 0 * * 6"    # Saturday midnight
  duration: 48h            # All weekend
- nodes: "0"               # Block all other times
Budget di implementazione graduale

Consenti tassi di interruzione crescenti:

budgets:
- nodes: "1"
  schedule: "0 2 * * *"    # 2 AM daily
  duration: 2h
- nodes: "3"
  schedule: "0 4 * * *"    # 4 AM daily
  duration: 4h

Esempi di configurazione del budget

La specifica seguente NodePool include tre budget configurati:

  • Il budget iniziale consente di interrompere il 20% dei nodi appartenenti al pool di nodi contemporaneamente.
  • Il secondo budget funge da limite massimo, consentendo solo cinque interruzioni quando sono presenti più di 25 nodi.
  • L'ultimo budget blocca le interruzioni durante i primi 10 minuti di ogni giorno.
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    expireAfter: 720h # 30 * 24h = 720h
    budgets:
    - nodes: "20%"      # Allow 20% of nodes to be disrupted
    - nodes: "5"        # Cap at maximum 5 nodes
    - nodes: "0"        # Block all disruptions during maintenance window
      schedule: "@daily" # Scheduled daily
      duration: 10m # Duration of 10 minutes

Interruzione manuale del nodo

È possibile interrompere manualmente i nodi nap usando kubectl o eliminando le NodePool risorse.

Rimuovere nodi con kubectl

È possibile rimuovere manualmente i nodi usando il kubectl delete node comando . È possibile eliminare nodi specifici, tutti i nodi gestiti da NAP o i nodi di un pool di nodi specifico usando etichette, ad esempio:

# Delete a specific node
kubectl delete node $NODE_NAME

# Delete all NAP-managed nodes
kubectl delete nodes -l karpenter.sh/nodepool

# Delete nodes from a specific nodepool
kubectl delete nodes -l karpenter.sh/nodepool=$NODEPOOL_NAME

Eliminare le NodePool risorse

NodePool possiede NodeClaims tramite un riferimento al proprietario. NAP termina i nodi in modo elegante tramite l'eliminazione a catena quando si elimina l'oggetto associato NodePool.

Controllare l'interruzione usando le annotazioni

È possibile bloccare o disabilitare l'interruzione per pod, nodi o pool di nodi specifici usando annotazioni.

Controlli pod

Impedire a NAP di interrompere determinati pod impostando l'annotazione karpenter.sh/do-not-disrupt: "true"

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    metadata:
      annotations:
        karpenter.sh/do-not-disrupt: "true"

Questa annotazione impedisce interruzioni volontarie per scadenza, consolidamento e deriva. Tuttavia, non impedisce interruzioni manuali o da sistemi esterni tramite l'eliminazione di kubectl o NodePool.

Controlli nodo

Bloccare NAP affinché non interrompa nodi specifici.

apiVersion: v1
kind: Node
metadata:
  annotations:
    karpenter.sh/do-not-disrupt: "true"

Controlli del pool di nodi

Disabilitare le interruzioni per tutti i nodi in un NodePool.

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  template:
    metadata:
      annotations:
        karpenter.sh/do-not-disrupt: "true"

Passaggi successivi

Per altre informazioni sul provisioning automatico dei nodi in AKS (Azure Kubernetes Service), vedere gli articoli seguenti: