Per ogni risorsa Kubernetes, è possibile configurare due tipi di requisiti: Requests e Limits. Il primo descrive i requisiti minimi per la disponibilità di risorse libere sul nodo, necessarie per avviare un contenitore o un pod; il secondo limita rigidamente le risorse disponibili per il contenitore.
Quando Kubernetes pianifica un pod, è molto importante che i contenitori abbiano risorse sufficienti per funzionare normalmente. Se prevedi di distribuire una grande applicazione su un nodo con risorse limitate, è possibile che non funzioni a causa della mancanza di memoria o di potenza della CPU. In questo articolo vedremo come risolvere i problemi di carenza di potenza informatica utilizzando le richieste di risorse e i limiti.
Le richieste e i limiti sono meccanismi utilizzati da Kubernetes per gestire risorse come CPU e memoria. Le richieste garantiscono che un contenitore ottenga le risorse richieste. Se un contenitore richiede una risorsa, Kubernetes lo pianificherà solo su quel nodo in grado di fornirla. I limiti controllano che le risorse richieste dal contenitore non superino mai un certo valore.

Un contenitore può aumentare le sue capacità computazionali solo fino a un certo limite, oltre il quale sarà limitato. Vediamo come funziona. Ci sono due tipi di risorse: CPU e memoria. Il pianificatore Kubernetes utilizza informazioni su queste risorse per capire dove eseguire i tuoi pod. Una specifica tipica delle risorse per un pod appare così.

Ogni contenitore in un pod può impostare le proprie richieste e limitazioni, e tutto ciò è additivo. Le risorse della CPU sono definite in milli-core. Se il tuo contenitore ha bisogno di due core completi per funzionare, imposti un valore di 2000m. Se invece il contenitore richiede solo un quarto di core, il valore sarà 250m. Tieni presente che, se imposti un valore delle risorse della CPU superiore al numero di core del nodo più grande, il tuo pod non sarà programmato per l'esecuzione. Una situazione simile avverrà se hai un pod che richiede quattro core, mentre il cluster Kubernetes è composto da sole due macchine virtuali principali.
A meno che la tua applicazione non sia stata progettata specificamente per sfruttare i vantaggi di più core (pensando a programmi come calcoli scientifici complessi e operazioni su database), la prassi migliore è impostare le richieste CPU su 1 o inferiore, aumentando poi il numero di repliche per la scalabilità. Questa soluzione conferirà maggiore flessibilità e affidabilità al sistema.
Quando si tratta di limitazioni della CPU, la situazione si fa più interessante, poiché è considerata una risorsa comprimibile. Se la tua applicazione si avvicina al limite della potenza di elaborazione della CPU, Kubernetes inizierà a rallentare il tuo container tramite il CPU Throttling — riduzione della frequenza della CPU. Ciò significa che la CPU sarà artificialmente limitata, fornendo potenzialmente prestazioni inferiori all'applicazione, ma il processo non verrà fermato o terminato.
Le risorse di memoria sono definite in byte. Di solito, il valore nelle impostazioni è misurato in mebibyte (Mib), ma puoi impostare qualsiasi valore, dai byte ai petabyte. Qui si verifica la stessa situazione della CPU: se fai una richiesta per una quantità di memoria che supera la quantità disponibile sui tuoi nodi, l'esecuzione di quel pod non verrà programmata. Ma a differenza delle risorse della CPU, la memoria non è comprimibile, poiché non esiste un modo per limitare il suo utilizzo. Pertanto, l'esecuzione del container verrà interrotta non appena supera la memoria a lui allocata.

È importante ricordare che non puoi configurare richieste che superano la quantità di risorse che i tuoi nodi possono fornire. Le caratteristiche delle risorse condivise per le macchine virtuali GKE possono essere trovate nei link forniti sotto questo video.
In un mondo ideale, le impostazioni predefinite del container sarebbero più che sufficienti per permettere un flusso di lavoro fluido. Ma il mondo reale non è così: le persone possono dimenticare facilmente di configurare l'uso delle risorse, o i hacker possono impostare richieste e limiti che superano le reali capacità dell'infrastruttura. Per prevenire lo sviluppo di tali scenari, è possibile configurare le quote delle risorse ResourceQuota e i limiti range LimitRange.
Dopo aver creato gli spazi dei nomi, è possibile bloccarli utilizzando le quote. Ad esempio, se hai spazi dei nomi prod e dev, si usa un modello in cui non ci sono quote per la produzione, mentre le quote per lo sviluppo sono molto rigorose. Questo consente a prod, in caso di un'improvvisa impennata del traffico, di attingere a tutte le risorse disponibili, bloccando completamente dev.
La quota delle risorse può apparire in questo modo. In questo esempio ci sono 4 sezioni – queste sono 4 righe di codice in basso.

Esaminiamo ciascuna di esse. requests.cpu rappresenta il numero massimo di richieste di potenza di elaborazione che possono arrivare da tutti i contenitori nello spazio dei nomi. In questo esempio, puoi avere 50 contenitori con richieste di 10m, cinque contenitori con richieste di 100m oppure semplicemente un contenitore con una richiesta di 500m. Finché il numero totale di requests.cpu per questo spazio dei nomi rimarrà sotto i 500m, tutto andrà bene.
La memoria richiesta requests.memory è la massima quantità combinata di richieste di memoria che possono avere tutti i contenitori nello spazio dei nomi. Come nel caso precedente, puoi avere 50 contenitori da 2 MiB, cinque contenitori da 20 MiB o un unico contenitore con 100 MiB, finché la quantità totale di memoria richiesta nello spazio dei nomi sarà inferiore ai 100 mebibyte.
limits.cpu è il valore massimo combinato della potenza di elaborazione che può essere utilizzato da tutti i container nello spazio dei nomi. Può essere considerato come il limite delle richieste di potenza di elaborazione.
Infine, limits.memory rappresenta la quantità massima di memoria totale che possono utilizzare tutti i container nello spazio dei nomi. Questa è una limitazione delle richieste aggregate di memoria.
Quindi, per impostazione predefinita, i container nel cluster Kubernetes funzionano con risorse computazionali illimitate. Utilizzando le quote di risorse, gli amministratori del cluster possono limitare il consumo e la creazione di risorse sulla base dello spazio dei nomi. In uno spazio dei nomi, il modulo pod o container può consumare tanta potenza di CPU e memoria quanto definito dalla quota di risorse dello spazio dei nomi. Tuttavia, c'è preoccupazione che un singolo pod o container possa monopolizzare tutte le risorse disponibili. Per evitare tale situazione, si utilizza il limite Range, una politica di limitazione dell'allocazione delle risorse (per pod o container) nello spazio dei nomi.
Il limite Range fornisce restrizioni che possono:
- garantire l'uso minimo e massimo delle risorse di calcolo per ciascun modulo o container nello spazio dei nomi;
- forzare l'esecuzione della richiesta minima e massima di archiviazione Storage Request per ogni PersistentVolumeClaim nello spazio dei nomi;
- forzare l'impostazione del rapporto tra la richiesta Request e il limite Limit per la risorsa nello spazio dei nomi;
- impostare per impostazione predefinita Requests/Limits per le risorse di calcolo nello spazio dei nomi e inserirli automaticamente nei container durante l'esecuzione.
Così puoi creare un limite di intervallo nel tuo spazio dei nomi. A differenza delle quote, che si applicano all'intero spazio dei nomi, il Limit Range è utilizzato per singoli container. Questo può prevenire la creazione da parte degli utenti di container troppo piccoli o, al contrario, giganteschi all'interno dello spazio dei nomi. Il Limit Range può apparire in questo modo.

Come nel caso precedente, qui possiamo evidenziare 4 sezioni. Esaminiamo ciascuna.
Nella sezione default si impostano i limiti predefiniti per il contenitore nel pod. Se impostate questi valori nell'intervallo massimo, qualsiasi contenitore per il quale questi valori non siano stati esplicitamente impostati seguirà i valori predefiniti.
Nella sezione della richiesta predefinita defaultRequest sono configurate le richieste predefinite per il contenitore nel pod. Ancora una volta, se impostate questi valori nell'intervallo massimo, qualsiasi contenitore per il quale questi parametri non siano esplicitamente definiti utilizzerà questi valori predefiniti.
Nella sezione max sono indicati i limiti massimi che possono essere impostati per il contenitore nel pod. I valori nella sezione default e i limiti per il contenitore non possono essere impostati oltre questo limite. È importante notare che se è impostato un valore max e la sezione default è assente, il valore massimo diventa il valore predefinito.
Nella sezione min sono indicate le richieste minime che possono essere impostate per il contenitore nel pod. In questo caso, i valori nella sezione default e le richieste per il contenitore non possono essere impostati al di sotto di questo limite.
Ancora una volta, è importante notare che se questo valore è impostato, il valore di default è no, il valore minimo diventa la richiesta predefinita.
Alla fine, queste richieste di risorse vengono utilizzate dal pianificatore di Kubernetes per eseguire i tuoi carichi di lavoro. Perché tu possa configurare correttamente i tuoi container, è fondamentale capire come funziona. Supponiamo che tu voglia avviare diversi pod nel tuo cluster. Supponendo che le specifiche del pod siano valide, nel scheduling di Kubernetes verrà utilizzato un bilanciamento ciclico per scegliere il nodo su cui eseguire il carico di lavoro.

Kubernetes verificherà se il nodo Node 1 dispone di risorse sufficienti per gestire le richieste dei container del pod e, in caso contrario, passerà al nodo successivo. Se nessuno dei nodi nel sistema è in grado di soddisfare le richieste, i pod passeranno allo stato di attesa Pending state. Con funzionalità come il ridimensionamento automatico dei nodi, Google Kubernetes Engine (GKE) può rilevare automaticamente lo stato di attesa e creare altri nodi aggiuntivi.
Se successivamente si verifica un'eccessiva capacità dei nodi, la funzione di auto-scaling ne ridurrà il numero per risparmiare denaro. Ecco perché Kubernetes pianifica i pod in base alle richieste. Tuttavia, il limite può essere superiore alle richieste e in alcuni casi un nodo può effettivamente esaurire le risorse. Chiamiamo questa situazione stato di overcommitment.

Come ho già detto, se si tratta di CPU, Kubernetes inizierà a limitare i pod. Ogni pod riceverà quanto richiesto, ma se non raggiunge il limite, verrà applicato il throttling.
Per quanto riguarda le risorse di memoria, Kubernetes è costretto a prendere decisioni su quali pod eliminare e quali mantenere finché non si liberano risorse di sistema, altrimenti l'intero sistema collassa.
Immaginiamo uno scenario in cui avete una macchina che ha esaurito il limite di memoria: come si comporterà in questo caso Kubernetes?
Kubernetes cercherà i pod che utilizzano più risorse di quelle richieste. Quindi, se i tuoi container non presentano richieste di risorse, significa che di default stanno usando più di quanto richiesto, semplicemente perché non hanno richiesto nulla! Questi container diventano i principali candidati per lo spegnimento. I seguenti candidati sono i container che hanno soddisfatto tutte le loro richieste, ma sono ancora al di sotto del limite massimo.
Se Kubernetes trova diversi pod che hanno superato i parametri delle loro richieste, li ordinerà in base alla priorità e quindi rimuoverà i moduli con la priorità più bassa. Se tutti i moduli hanno la stessa priorità, Kubernetes fermerà i pod che hanno superato le loro richieste più di altri pod.
In rari casi, Kubernetes può interrompere i pod che sono comunque all'interno delle loro richieste. Questo può accadere quando componenti critici del sistema, come l'agente Kubelet o Docker, iniziano a consumare più risorse di quelle riservate per loro.
Nei primi stadi di sviluppo delle piccole aziende, un cluster Kubernetes può funzionare perfettamente senza la configurazione di richieste e limiti di risorse, ma man mano che i tuoi team e progetti crescono, rischi di affrontare problemi in questo ambito. Aggiungere richieste e limiti ai tuoi pod e namespace richiede solo un minimo sforzo aggiuntivo e può risparmiarti molte seccature.

Un po' di pubblicità 🙂
Grazie per essere con noi. Ti piacciono i nostri articoli? Vuoi vedere più contenuti interessanti? Supportaci effettuando un ordine o raccomandandoci ai tuoi conoscenti, , un'alternativa unica ai server entry-level, che abbiamo creato per te: (disponibili opzioni con RAID1 e RAID10, fino a 24 core e fino a 40GB DDR4).
Dell R730xd a metà prezzo nel data center Equinix Tier IV ad Amsterdam? Solo da noi nei Paesi Bassi! Dell R420 — 2x E5-2430 2.2GHz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB — a partire da $99! Scopri di più su
Fonte: habr.com
