Procedure ottimali per la gestione dei cluster

Scopri le best practice per la gestione dei cluster creati da Kubernetes Engine (OKE).

Questa sezione contiene le best practice per la gestione dei cluster e il motore Kubernetes.

Best practice: utilizzare le etichette Kubernetes

Ti consigliamo di utilizzare le etichette Kubernetes per organizzare le numerose risorse Kubernetes (ad esempio servizi, pod, container, reti) che costituiscono un cluster.

Le etichette Kubernetes sono coppie chiave-valore che ti aiutano a mantenere queste risorse e a tenere traccia del modo in cui interagiscono tra loro in un cluster.

Ad esempio, è possibile utilizzare oci.oraclecloud.com/oke-is-preemptible=true label (il motore Kubernetes si applica ai nodi di lavoro ospitati su istanze prerilasciabili) con selettori dei nodi Kubernetes e affinità/antiaffinità dei nodi per controllare quali pod sono pianificati su tali nodi di lavoro.

Vedere Etichette, annotazioni e taint ben noti nella documentazione di Kubernetes.

Best Practice: utilizza l'applicazione di tag alle risorse OCI

Ti consigliamo di utilizzare l'applicazione di tag alle risorse OCI per organizzare le numerose risorse (ad esempio, nodi di lavoro, VCN, load balancer e volumi a blocchi) utilizzate dai cluster Kubernetes creati con Kubernetes Engine. Quando in una tenancy viene distribuito un numero elevato di risorse in più compartimenti, è difficile tenere traccia delle risorse utilizzate per scopi specifici. Allo stesso modo, è difficile aggregare le risorse, creare report su di esse e intraprendere azioni di massa su di esse.

L'applicazione di tag consente di definire chiavi e valori e di associarli alle risorse. È quindi possibile utilizzare le tag per organizzare ed elencare le risorse in base alle esigenze aziendali.

Vedere Applicazione di tag alle risorse correlate al cluster Kubernetes.

Best Practice: impostare le richieste e i limiti delle risorse

Si consiglia di impostare:

  • richieste di risorse, per specificare la quantità minima di risorse che un contenitore può utilizzare
  • limiti di risorse, per specificare la quantità massima di risorse che un contenitore può utilizzare

Quando si lavora con un cluster Kubernetes, una sfida comune è l'errore occasionale di un'applicazione di distribuire su un cluster a causa della disponibilità limitata di risorse su tale cluster. L'errore è causato da richieste di risorse e limiti di risorse non impostati.

Se non si impostano richieste e limiti di risorse, i pod in un cluster possono iniziare a utilizzare più risorse del necessario. Se un pod inizia a consumare più CPU o memoria su un nodo, il kube-scheduler potrebbe non essere in grado di posizionare nuovi pod sul nodo e il nodo stesso potrebbe persino bloccarsi.

Vedere Richieste e limiti nella documentazione di Kubernetes.

Best Practice: Riserva le risorse per i daemon di sistema Kubernetes e OS

Si consiglia di utilizzare i flag kubelet --kube-reserved e --system-reserved per riservare risorse di CPU e memoria per i daemon di sistema Kubernetes (ad esempio, kubelet e container runtime) e i daemon di sistema del sistema operativo (ad esempio, sshd e systemd). Ad esempio:

  • --kube-reserved=cpu=500m,memory=1Gi
  • --system-reserved=cpu=100m,memory=100Mi

I pod in esecuzione su un nodo di lavoro possono utilizzare tutte le risorse di CPU e memoria disponibili e quindi impedire l'esecuzione di altri processi essenziali (ad esempio, i daemon del sistema Kubernetes e del sistema operativo) sul nodo. Quando i daemon di sistema Kubernetes e del sistema operativo non possono essere eseguiti, il nodo di lavoro può diventare non reattivo, instabile e causare un crash imprevisto a causa di un carico elevato.

Per evitare che i pod richiedano risorse richieste dai daemon di sistema Kubernetes e OS, includere i flag kubelet --kube-reserved e --system-reserved come opzioni kubelet-extra-args in uno script di inizializzazione cloud personalizzato. Per ulteriori informazioni e un esempio, vedere l'Esempio 4: utilizzo di uno script cloud-init personalizzato per riservare le risorse per i daemon di sistema Kubernetes e OS.

Quando si utilizza il flag kubelet --kube-reserved per riservare una parte delle risorse di CPU e memoria di un nodo di lavoro per l'uso da parte dei daemon di sistema Kubernetes, tenere presenti i seguenti suggerimenti:

  • La quantità di risorsa CPU che si consiglia di riservare per i daemon di sistema Kubernetes dipende dal numero di memorie centrali CPU nel nodo di lavoro, come illustrato nella tabella riportata di seguito.
    Numero di core CPU nel nodo di lavoro 1 2 3 4 5 Più di 5
    CPU consigliata da riservare, in millicore (m) 60 m 70 m 80 m 85 m 90 m 2,5 m aggiuntivi per ogni core aggiuntivo sul nodo di lavoro
  • La quantità di risorsa di memoria che si consiglia di riservare per i daemon di sistema Kubernetes dipende dalla quantità di memoria nel nodo di lavoro, come illustrato nella tabella riportata di seguito.
    Memoria sul nodo di lavoro, in GiB 4 GiB 8 GiB 16 GiB 128 GiB Più di 128 GiB
    Memoria consigliata da riservare, in GiB 1 GiB 1 GiB 2 GiB 9 GiB 20 MiB aggiuntivi per ogni GiB aggiuntivo di memoria dei nodi di lavoro

Quando si utilizza il flag kubelet --system-reserved per riservare una parte delle risorse di CPU e memoria di un nodo per l'uso da parte dei daemon di sistema del sistema operativo, tenere presenti i seguenti suggerimenti:

  • La quantità di risorsa CPU che si consiglia di riservare per i daemon di sistema del sistema operativo (indipendentemente dalla forma del nodo) è di 100 m (millicore).
  • La quantità di risorsa di memoria che si consiglia di riservare per i daemon di sistema del sistema operativo (indipendentemente dalla forma del nodo) è pari a 100 Mi (mebibyte).

Tenere presente che i suggerimenti relativi alla CPU e alla memoria per i flag kubelet --kube-reserved e --system-reserved potrebbero non essere ottimali per i carichi di lavoro che si desidera eseguire, pertanto potrebbe essere necessario modificare i valori di conseguenza. Potrebbe essere inoltre necessario modificare i valori nel tempo.

Per vedere la differenza tra le risorse totali su un nodo di lavoro e le risorse sul nodo che i carichi di lavoro possono utilizzare, eseguire il comando seguente:

kubectl get node <NODE_NAME> -o=yaml | grep -A 6 -B 7 capacity

Output di esempio:

  allocatable:
    cpu: 15743m
    ephemeral-storage: "34262890849"
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 234972476Ki
    pods: "110"
  capacity:
    cpu: "16"
    ephemeral-storage: 37177616Ki
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 257197372Ki
    pods: "110"

La differenza tra la CPU e la memoria "capacità" e "allocatabile" nell'output di esempio include le prenotazioni di CPU e memoria per i daemon di sistema Kubernetes e OS.

Nota

A partire da giugno 2024, i suggerimenti per le prenotazioni di risorse di CPU e memoria per i daemon di sistema Kubernetes e del sistema operativo descritti in questa sezione vengono utilizzati come valori predefiniti per tutte le immagini OKE, per tutte le versioni Kubernetes supportate. I suggerimenti vengono inoltre utilizzati come valori predefiniti per tutte le immagini della piattaforma per Kubernetes versione 1.30 e successive. Le impostazioni predefinite vengono applicate sia quando si specifica un'immagine OKE rilasciata nel giugno 2024 (o successivamente) sia quando si aggiorna la versione di Kubernetes in esecuzione in un cluster alla versione 1.30 (o successiva). Se si specifica un'immagine OKE rilasciata a giugno 2024 (o successivamente) o si aggiorna un cluster a Kubernetes versione 1.30, si consiglia di controllare che le prenotazioni predefinite siano appropriate per i carichi di lavoro che si intende eseguire.

Suggerimenti aggiuntivi:

  • Prima di applicare le modifiche alle prenotazioni ai cluster di produzione, eseguire sempre il benchmark e il test dell'impatto delle modifiche alle prenotazioni in un ambiente non di produzione.
  • Utilizzare i flag kubelet --eviction-hard o --eviction-soft per impostare le soglie appropriate per la memoria e la pressione del disco. Quando si impostano queste soglie, il sistema Kubernetes è in grado di proteggere la stabilità del sistema rimuovendo i pod meno importanti quando necessario. Per ulteriori informazioni, vedere Svuotamento della pressione dei nodi nella documentazione di Kubernetes.
  • Tenere presente che riservare troppe risorse può portare alla sottoutilizzazione dei nodi. Il tuo obiettivo è trovare un equilibrio appropriato tra garantire la disponibilità delle risorse per i componenti critici e massimizzare la disponibilità delle risorse per i carichi di lavoro. Si consiglia di iniziare con prenotazioni di risorse più grandi e ridurre gradualmente le dimensioni delle prenotazioni in base all'osservazione, anziché iniziare con prenotazioni di risorse più piccole troppo basse e correre il rischio di instabilità del sistema. Utilizza le metriche degli strumenti di monitoraggio e avviso per osservare l'uso delle risorse da parte di Kubernetes e dei componenti di sistema nel tempo.
  • Quando si riservano le risorse, tenere conto delle differenze nella forma del nodo e nel tipo di carico di lavoro. I nodi di grandi dimensioni potrebbero richiedere assegnazioni assolute maggiori rispetto ai nodi più piccoli. I carichi di lavoro con esigenze di risorse specifiche o pattern di suddivisione noti potrebbero richiedere assegnazioni di risorse maggiori o minori.

Per ulteriori informazioni sulla prenotazione delle risorse, consulta la sezione relativa alla riserva delle risorse di computazione per i daemon di sistema nella documentazione di Kubernetes.

Best Practice: fornire nodi dedicati utilizzando taint e tolleranze

Ti consigliamo di utilizzare taint e tolleranze Kubernetes per limitare le applicazioni a uso intensivo di risorse a nodi di lavoro specifici.

L'uso di taint e tolleranze consente di mantenere le risorse dei nodi disponibili per i carichi di lavoro che le richiedono e impedisce la pianificazione di altri carichi di lavoro sui nodi.

Ad esempio, quando crei un cluster utilizzando Kubernetes Engine, puoi definire i nodi di lavoro in modo che abbiano una forma GPU o una forma con un gran numero di CPU potenti. Questi nodi di lavoro ben specificati sono ideali per carichi di lavoro di elaborazione dati di grandi dimensioni. Tuttavia, tale hardware specializzato è normalmente costoso da implementare. Di conseguenza, in genere si desidera limitare i carichi di lavoro che possono essere pianificati su questi nodi. Per limitare i carichi di lavoro che possono essere pianificati sui nodi di lavoro ben specificati, aggiungere un tocco ai nodi. Ad esempio, eseguendo uno dei seguenti comandi:

  • kubectl taint nodes <node-name> special=true:NoSchedule
  • kubectl taint nodes <node-name> special=true:PreferNoSchedule

Dopo aver aggiunto un tocco ai nodi di lavoro ben specificati, aggiungere una tolleranza corrispondente ai pod che si desidera consentire di utilizzare i nodi.

Analogamente, puoi utilizzare oci.oraclecloud.com/oke-is-preemptible=true label (che Kubernetes Engine applica ai nodi di lavoro ospitati su istanze prerilasciabili) con tolleranze Kubernetes per controllare quali pod sono pianificati su tali nodi di lavoro.

Vedere Taints and Tolerations nella documentazione di Kubernetes.

Best Practice: controlla la pianificazione dei pod utilizzando i selettori dei nodi e l'affinità

Esistono diversi modi per vincolare l'esecuzione di un pod su determinati nodi o per specificare una preferenza per l'esecuzione di un pod su determinati nodi. Gli approcci consigliati utilizzano tutti i selettori di etichette per facilitare la selezione. Spesso, il kube-scheduler farà automaticamente un posizionamento ragionevole senza tali vincoli o preferenze. Tuttavia, ci sono alcune circostanze in cui potresti voler controllare il nodo su cui viene eseguito un pod.

In queste situazioni, si consiglia di controllare la pianificazione dei pod sui nodi utilizzando i selettori dei nodi Kubernetes, l'affinità dei nodi e l'affinità inter-pod.

L'uso di selettori di nodi, affinità di nodi e affinità tra nodi consente al kube-scheduler di isolare logicamente i carichi di lavoro, ad esempio mediante l'hardware del nodo.

Ad esempio, è possibile assegnare ai nodi un'etichetta per indicare che dispongono di storage SSD collegato a livello locale. Per specificare che un pod deve essere eseguito solo sui nodi con storage SSD collegato localmente, è quindi necessario includere tale etichetta come selettore di nodi nella specifica del pod. Kubernetes pianifica i pod solo sui nodi con etichette corrispondenti.

Vedere Assegnazione dei pod ai nodi nella documentazione di Kubernetes.

Best Practice: utilizza il servizio OCI Full Stack Disaster Recovery per il backup e il disaster recovery

Ti consigliamo di utilizzare il servizio OCI Full Stack Disaster Recovery con Kubernetes Engine per il backup e il disaster recovery. Full Stack Disaster Recovery è un servizio di gestione e orchestrazione del disaster recovery cloud nativo che fornisce funzionalità complete di disaster recovery per tutti i livelli di uno stack di applicazioni, tra cui infrastruttura, middleware, database e applicazioni.

Quando utilizzi Full Stack Disaster Recovery, puoi aggiungere i cluster Kubernetes creati con Kubernetes Engine ai gruppi di protezione da disaster recovery, consentendoti di automatizzare l'orchestrazione di ripristino end-to-end del tuo sistema Kubernetes tra le region OCI.

Per ulteriori informazioni, consulta la documentazione su Full Stack Disaster Recovery e in particolare le seguenti sezioni:

Prima del rilascio di Full Stack Disaster Recovery, in precedenza era stato consigliato l'uso di strumenti di terze parti (ad esempio Kasten, Rancher, Trilio o Velero) con Kubernetes Engine per il backup e il recupero da errori irreversibili. Se è già presente uno strumento di disaster recovery di terze parti, è possibile continuare a utilizzarlo. Tuttavia, ti consigliamo di considerare i vantaggi di OCI Full Stack Disaster Recovery come un'alternativa agli strumenti di terze parti.