Come accedere alle risorse del pod Kubernetes

Come accedere alle risorse del pod KubernetesLa ricompensa di Tohad

Quando si inizia con Kubernetes, è normale dimenticare di configurare le risorse del contenitore. A questo punto è sufficiente assicurarsi che l'immagine Docker funzioni e possa essere distribuita nel cluster Kubernetes.

Successivamente, però, l'applicazione dovrà essere distribuita in un cluster di produzione insieme ad altre applicazioni. Per fare ciò, è necessario allocare risorse per il contenitore e assicurarsi che ce ne siano abbastanza per far funzionare l'applicazione e che altre applicazioni in esecuzione non abbiano problemi.

Squadra Kubernetes aaS da Mail.ru tradotto un articolo sulle risorse del contenitore (CPU e MEM), richieste e limitazioni delle risorse. Imparerai i vantaggi di queste impostazioni e cosa succede se non le imposti.

Risorse informatiche

Abbiamo due tipi di risorse con le seguenti unità:

  • Unità di elaborazione centrale (CPU) - core;
  • Memoria (MEM) - byte.

Le risorse sono specificate per ciascun contenitore. Nel seguente file YAML del pod, vedrai una sezione delle risorse che contiene le risorse richieste e limitate:

  • Risorse pod richieste = somma delle risorse richieste di tutti i contenitori;
  • Limite risorse pod = Somma di tutti i limiti delle risorse pod.

apiVersion: v1
kind: Pod
metadata:
  name: backend-pod-name
  labels:
    application: backend
spec:
  containers:
    — name: main-container
      image: my-backend
      tag: v1
      ports:
      — containerPort: 8080
      resources:
        requests:
          cpu: 0.2 # REQUESTED CPU: 200m cores
          memory: "1Gi" # REQUESTED MEM: 1Gi
        limits:
          cpu: 1 # MAX CPU USAGE: 1 core
          memory: "1Gi" # MAX MEM USAGE:  1Gi
    — name: other-container
      image: other-app
      tag: v1
      ports:
      — containerPort: 8000
      resources:
        requests:
          cpu: "200m" # REQUESTED CPU: 200m cores
          memory: "0.5Gi" # REQUESTED MEM: 0.5Gi
        limits:
          cpu: 1 # MAX CPU USAGE: 1 core
          memory: "1Gi" # MAX MEM USAGE:  1Gi

Esempio di risorse richieste e limitate

Campo resources.requested dalla specifica Pod è uno degli elementi utilizzati per trovare il nodo desiderato. Puoi già pianificare la distribuzione del pod per questo. Come trovi un nodo adatto?

Kubernetes è costituito da diversi componenti, incluso un nodo master o un nodo master (piano di controllo Kubernetes). Il nodo master ha diversi processi: kube-apiserver, kube-controller-manager e kube-scheduler.

Il processo kube-scheduler è responsabile della revisione dei pod appena creati e della ricerca di possibili nodi di lavoro che corrispondono a tutte le richieste di pod, incluso il numero di risorse richieste. L'elenco dei nodi trovati da kube-scheduler viene classificato. Il pod viene pianificato sul nodo con i punteggi più alti.

Come accedere alle risorse del pod KubernetesDove verrà posizionato il Pod viola?

Nell'immagine puoi vedere che kube-scheduler dovrebbe programmare un nuovo Pod viola. Il cluster Kubernetes contiene due nodi: A e B. Come puoi vedere, kube-scheduler non può pianificare un pod sul nodo A: le risorse disponibili (non richieste) non corrispondono alle richieste del pod viola. Quindi, l’1 GB di memoria richiesto dal Pod viola non entrerà nel nodo A, poiché la memoria disponibile è di 0,5 GB. Ma il nodo B ha abbastanza risorse. Di conseguenza, kube-scheduler decide che la destinazione del Pod viola è il nodo B.

Ora sappiamo come le risorse richieste influiscono sulla scelta del nodo su cui eseguire il Pod. Ma qual è l’impatto delle risorse marginali?

Il limite delle risorse è un limite che la CPU/MEM non può oltrepassare. Tuttavia, la risorsa CPU è flessibile, quindi i container che raggiungono i limiti della CPU non causeranno l'uscita del pod. Verrà invece avviata la limitazione della CPU. Se viene raggiunto il limite di utilizzo MEM, il contenitore verrà arrestato a causa di OOM-Killer e riavviato se consentito dall'impostazione RestartPolicy.

Risorse richieste e massime in dettaglio

Come accedere alle risorse del pod KubernetesComunicazione delle risorse tra Docker e Kubernetes

Il modo migliore per spiegare come funzionano le richieste di risorse e i limiti delle risorse è introdurre la relazione tra Kubernetes e Docker. Nell'immagine sopra puoi vedere come sono correlati i campi Kubernetes e i flag di avvio di Docker.

La memoria: richiesta e limitazione

containers:
...
 resources:
   requests:
     memory: "0.5Gi"
   limits:
     memory: "1Gi"

Come accennato in precedenza, la memoria è misurata in byte. Basato su Documentazione Kubernetes, possiamo specificare la memoria come un numero. Di solito è un numero intero, ad esempio 2678, ovvero 2678 byte. Puoi anche usare i suffissi G и Gi, l'importante è ricordare che non sono equivalenti. Il primo è decimale e il secondo è binario. Come l'esempio menzionato nella documentazione di k8: 128974848, 129e6, 129M, 123Mi - sono praticamente equivalenti.

Opzione Kubernetes limits.memory corrisponde alla bandiera --memory da Docker. In caso di request.memory Non è presente alcuna freccia per Docker perché Docker non utilizza questo campo. Potresti chiedere, è addirittura necessario? Sì, serve. Come ho detto prima, il campo è importante per Kubernetes. In base alle informazioni da esso contenute, kube-scheduler decide su quale nodo pianificare il Pod.

Cosa succede se imposti una memoria insufficiente per una richiesta?

Se il container ha raggiunto i limiti della memoria richiesta, allora il Pod viene inserito in un gruppo di Pod che si fermano quando non c'è abbastanza memoria nel nodo.

Cosa succede se imposti un limite di memoria troppo basso?

Se il contenitore supera il limite di memoria, verrà terminato a causa di OOM-Killed. E si riavvierà, se possibile, in base a RestartPolicy dove si trova il valore predefinito Always.

Cosa succede se non si specifica la memoria richiesta?

Kubernetes prenderà il valore limite e lo imposterà come valore predefinito.

Cosa può succedere se non si specifica un limite di memoria?

Il contenitore non ha restrizioni; può utilizzare tutta la memoria che desidera. Se inizia a utilizzare tutta la memoria disponibile del nodo, OOM lo ucciderà. Il contenitore verrà quindi riavviato, se possibile, in base a RestartPolicy.

Cosa succede se non si specificano i limiti di memoria?

Questo è lo scenario peggiore: lo scheduler non sa quante risorse richiede il contenitore, e questo può causare seri problemi al nodo. In questo caso, sarebbe bello avere limiti predefiniti sullo spazio dei nomi (impostati da LimitRange). Non ci sono limiti predefiniti: il Pod non ha limiti, può utilizzare tutta la memoria che desidera.

Se la memoria richiesta è superiore a quella che il nodo può offrire, il Pod non verrà schedulato. È importante ricordarlo Requests.memory - non il valore minimo. Questa è una descrizione della quantità di memoria sufficiente per mantenere il contenitore in esecuzione continua.

Di solito si consiglia di impostare lo stesso valore per request.memory и limit.memory. Ciò garantisce che Kubernetes non pianificherà un pod su un nodo che dispone di memoria sufficiente per eseguire il pod ma non abbastanza per eseguirlo. Tieni presente: la pianificazione del Pod Kubernetes tiene conto solo requests.memoryE limits.memory non tiene conto.

CPU: richiesta e limite

containers:
...
 resources:
   requests:
     cpu: 1
   limits:
     cpu: "1200m"

Con una CPU tutto è un po' più complicato. Tornando al quadro della relazione tra Kubernetes e Docker, puoi vederlo request.cpu fiammiferi --cpu-sharesMentre limit.cpu corrisponde alla bandiera cpus in Docker.

La CPU richiesta da Kubernetes viene moltiplicata per 1024, la proporzione dei cicli della CPU. Se vuoi richiedere 1 core completo, devi aggiungere cpu: 1come mostrato sopra.

Richiedere un kernel completo (proporzione = 1024) non significa che il tuo contenitore lo riceverà. Se il tuo computer host ha un solo core e stai eseguendo più di un container, tutti i container devono condividere tra loro la CPU disponibile. Come avviene questo? Diamo un'occhiata alla foto.

Come accedere alle risorse del pod Kubernetes
Richiesta CPU - Sistema single core

Immaginiamo di avere un sistema host single-core che esegue contenitori. La mamma (Kubernetes) ha preparato una torta (CPU) e vuole dividerla tra i bambini (contenitori). Tre bambini vogliono una torta intera (proporzione = 1024), un altro bambino vuole mezza torta (512). La mamma vuole essere onesta e fa un semplice calcolo.

# Сколько пирогов хотят дети?
# 3 ребенка хотят по целому пирогу и еще один хочет половину пирога
cakesNumberKidsWant = (3 * 1) + (1 * 0.5) = 3.5
# Выражение получается так:
3 (ребенка/контейнера) * 1 (целый пирог/полное ядро) + 1 (ребенок/контейнер) * 0.5 (половина пирога/половина ядра)
# Сколько пирогов испечено?
availableCakesNumber = 1
# Сколько пирога (максимально) дети реально могут получить?
newMaxRequest = 1 / 3.5 =~ 28%

In base al calcolo, tre bambini riceveranno il 28% del nucleo e non l'intero nucleo. Il quarto figlio riceverà il 14% dell'intero kernel, non la metà. Ma le cose andranno diversamente se disponi di un sistema multi-core.

Come accedere alle risorse del pod Kubernetes
Richiesta CPU - Sistema multi-core (4).

Nell'immagine sopra puoi vedere che tre bambini vogliono una torta intera e uno ne vuole la metà. Dato che la mamma ha preparato quattro torte, ciascuno dei suoi figli ne riceverà quante ne vorrà. In un sistema multi-core, le risorse del processore sono distribuite su tutti i core del processore disponibili. Se un contenitore è limitato a meno di un core CPU completo, può comunque utilizzarlo al 100%.

I calcoli precedenti sono semplificati per comprendere come viene distribuita la CPU tra i contenitori. Naturalmente, oltre ai contenitori stessi, ci sono anche altri processi che utilizzano risorse della CPU. Quando i processi in un contenitore sono inattivi, altri possono utilizzare la sua risorsa. CPU: "200m" fiammiferi CPU: 0,2, il che significa circa il 20% di un core.

Ora parliamo di limit.cpu. La CPU limitata da Kubernetes viene moltiplicata per 100. Il risultato è la quantità di tempo che il contenitore può utilizzare ogni 100 µs (cpu-period).

limit.cpu corrisponde al flag Docker --cpus. Questa è una nuova combinazione di vecchio --cpu-period и --cpu-quota. Impostandolo, indichiamo quante risorse CPU disponibili il contenitore può utilizzare al massimo prima che inizi la limitazione:

  • CPU - combinazione cpu-period и cpu-quota. cpus = 1.5 equivalente all'impostazione cpu-period = 100000 и cpu-quota = 150000;
  • Periodo della CPU - periodo Programmatore CFS della CPU, valore predefinito 100 microsecondi;
  • quota-cpu - numero di microsecondi interni cpu-period, che è delimitato dal contenitore.

Cosa succede se installi una CPU richiesta insufficiente?

Se il contenitore necessita di più di quanto ha installato, ruberà CPU da altri processi.

Cosa succede se imposti il ​​limite della CPU troppo basso?

Poiché la risorsa CPU è regolabile, verrà attivata la limitazione.

Cosa succede se non specifichi una richiesta CPU?

Come per la memoria, il valore della richiesta è uguale al limite.

Cosa succede se non specifichi un limite di CPU?

Il contenitore utilizzerà tutta la CPU di cui ha bisogno. Se nello spazio dei nomi è definita una policy CPU predefinita (LimitRange), questo limite viene utilizzato anche per il contenitore.

Cosa succede se non specifichi né una richiesta né un limite di CPU?

Come per la memoria, questo è lo scenario peggiore. Lo scheduler non sa di quante risorse ha bisogno il tuo contenitore e questo può causare seri problemi al nodo. Per evitare ciò, è necessario impostare limiti predefiniti per gli spazi dei nomi (LimitRange).

Ricorda: se richiedi più CPU di quella che i nodi possono fornire, il Pod non verrà schedulato. Requests.cpu - non il valore minimo, ma un valore sufficiente per avviare il Pod e funzionare senza guasti. Se l'applicazione non esegue calcoli complessi, l'opzione migliore è installarla request.cpu <= 1 e lanciare tutte le repliche necessarie.

Quantità ideale di risorse richieste o limite di risorse

Abbiamo appreso della limitazione delle risorse informatiche. Adesso è il momento di rispondere alla domanda: “Quante risorse richiede il mio Pod per eseguire l’applicazione senza problemi? Qual è la quantità ideale?

Sfortunatamente, non ci sono risposte chiare a queste domande. Se non sai come funziona la tua applicazione o di quanta CPU o memoria ha bisogno, l'opzione migliore è fornire all'applicazione molta memoria e CPU ed eseguire quindi test delle prestazioni.

Oltre ai test delle prestazioni, monitora il comportamento dell'applicazione durante il monitoraggio per una settimana. Se i grafici indicano che la tua applicazione sta consumando meno risorse di quelle richieste, puoi ridurre la quantità di CPU o memoria richiesta.

Come esempio vedi questo Cruscotto Grafana. Visualizza la differenza tra le risorse richieste o il limite delle risorse e l'utilizzo corrente delle risorse.

conclusione

Richiedere e limitare le risorse aiuta a mantenere integro il tuo cluster Kubernetes. La corretta configurazione dei limiti riduce al minimo i costi e mantiene le applicazioni sempre attive.

In breve, ci sono alcune cose da tenere a mente:

  1. Le risorse richieste sono una configurazione che viene presa in considerazione al momento dell'avvio (quando Kubernetes prevede di ospitare l'applicazione). Al contrario, limitare le risorse è importante in fase di runtime, quando l'applicazione è già in esecuzione sul nodo.
  2. Rispetto alla memoria, la CPU è una risorsa regolamentata. Se la CPU non è sufficiente, il tuo Pod non si spegnerà e si attiverà il meccanismo di limitazione.
  3. Le risorse richieste e il limite delle risorse non sono valori minimi e massimi! Definendo le risorse richieste, ti assicuri che l'applicazione funzionerà senza problemi.
  4. Una buona pratica è impostare la richiesta di memoria uguale al limite di memoria.
  5. Ok installazione richiesta CPU <=1, se l'applicazione non esegue calcoli complessi.
  6. Se richiedi più risorse di quelle disponibili su un nodo, il pod non verrà mai pianificato su quel nodo.
  7. Per determinare la quantità corretta di risorse/limiti di risorse richiesti, utilizzare il test e il monitoraggio del carico.

Spero che questo articolo ti aiuti a comprendere il concetto di base della limitazione delle risorse. E sarai in grado di applicare questa conoscenza nel tuo lavoro.

Buona fortuna!

Cos'altro leggere:

  1. Osservabilità SRE: spazi dei nomi e struttura metrica.
  2. Oltre 90 strumenti utili per Kubernetes: distribuzione, gestione, monitoraggio, sicurezza e altro ancora.
  3. Il nostro canale Around Kubernetes in Telegram.

Fonte: habr.com

Aggiungi un commento