Cum să obții acces la resursele Kubernetes Pod

Cum să obții acces la resursele Kubernetes PodRecompensa de Tohad

La începutul lucrului cu Kubernetes, de obicei se uită la configurarea resurselor containerelor. În această etapă, este suficient să te asiguri că imaginea Docker funcționează și poate fi desfășurată în clusterul Kubernetes.

Însă, mai târziu, aplicația trebuie desfășurată în clusterul de producție împreună cu alte aplicații. Pentru aceasta, trebuie alocate resurse pentru container și asigurate suficiente pentru a porni și funcționa aplicația, fără a provoca probleme altor aplicații rulate.

Comanda Kubernetes aaS de la Mail.ru am tradus articolul despre resursele containerelor (CPU & MEM), cererile și limitările resurselor. Vei afla ce avantaje oferă aceste setări și ce se întâmplă dacă nu sunt configurate.

Resurse de calcul

Avem două tipuri de resurse cu următoarele unități:

  • Unitate centrală de procesare (CPU) - nuclee;
  • Memorie (MEM) - biți.

Resursele se specifică pentru fiecare container. În următorul fișier YAML al Pod-ului, vei vedea secțiunea resurselor, care conține resursele solicitate și limitele resurselor:

  • Resursele solicitate ale Pod-ului = suma resurselor solicitate de toate containerele;
  • Resursele limitate ale Pod-ului = suma resurselor limitate de toate containerele.

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 # CPU SOLICITAT: 200m nuclee
          memory: "1Gi" # MEM SOLICITAT: 1Gi
        limits:
          cpu: 1 # UTILIZARE MAXIMĂ CPU: 1 nucleu
          memory: "1Gi" # UTILIZARE MAXIMĂ MEM:  1Gi
    - name: other-container
      image: other-app
      tag: v1
      ports:
      - containerPort: 8000
      resources:
        requests:
          cpu: "200m" # CPU SOLICITAT: 200m nuclee
          memory: "0.5Gi" # MEM SOLICITAT: 0.5Gi
        limits:
          cpu: 1 # UTILIZARE MAXIMĂ CPU: 1 nucleu
          memory: "1Gi" # UTILIZARE MAXIMĂ MEM:  1Gi

Exemplu de resurse solicitate și limitate

Câmp resources.requested din specificația Pod-ului - unul dintre elementele folosite pentru a căuta nodul necesar. Pe acesta poate fi programată desfășurarea Pod-ului. Cum se caută nodul potrivit?

Kubernetes este format din mai multe componente, inclusiv conține un nod principal sau un nod master (Kubernetes Control Plane). În nodul master există mai multe procese: kube-apiserver, kube-controller-manager și kube-scheduler.

Procesul kube-scheduler se ocupă cu vizualizarea modulelor recent create și căutarea nodurilor de lucru posibile care corespund tuturor cerințelor modulelor, inclusiv la numărul de resurse solicitate. Lista nodurilor găsite de kube-scheduler este clasificată. Pod-ul este programat pe nodul cu cele mai mari punctaje.

Cum să obții acces la resursele Kubernetes PodUnde va fi plasat Pod-ul violet?

În imagine se observă că kube-scheduler trebuie să planifice un nou Pod violet. Clusterul Kubernetes conține două noduri: A și B. După cum se poate observa, kube-scheduler nu poate planifica Podul pe nodul A — resursele disponibile (necerute) nu corespund cerințelor Podului violet. Astfel, memoria solicitată de Podul violet, de 1 GB, nu se va încadra pe nodul A, deoarece volumul de memorie disponibil este de 0,5 GB. Dar nodul B are suficiente resurse. În cele din urmă, kube-scheduler decide că destinația Podului violet este nodul B.

Acum știm cum resursele solicitate influențează alegerea nodului pentru a rula un Pod. Dar cum influențează resursele limită?

Resursele limită reprezintă limitele pe care CPU/MEM nu le pot depăși. Totuși, resursa CPU este flexibilă, așa că containerele care ating valorile limită la CPU nu vor duce la oprirea Podului. În schimb, se va activa throttling-ul CPU. Dacă însă se atinge limita de utilizare a MEM, atunci containerul va fi oprit din cauza OOM-Killer și va fi repornit dacă acest lucru este permis de setarea RestartPolicy.

Resursele solicitate și limită în detalii

Cum să obții acces la resursele Kubernetes PodLegătura resurselor între Docker și Kubernetes

Cel mai bun mod de a explica cum funcționează resursele solicitate și limită este de a reprezenta legătura dintre Kubernetes și Docker. În imaginea de mai sus, puteți vedea cum sunt corelate câmpurile Kubernetes și flag-urile de pornire Docker.

Memorie: solicitare și limită

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

După cum s-a menționat anterior, memoria este măsurată în octeți. Pe baza documentația Kubernetes, putem specifica memoria sub formă de număr. De obicei, este un întreg, de exemplu 2678 — adică 2678 octeți. De asemenea, se pot folosi sufixe G și Gi, este important să reținem că acestea nu sunt echivalente. Primul este zecimal, iar al doilea este binar. Ca exemplu, menționat în documentația k8s: 128974848, 129e6, 129M, 123Mi — ele sunt practic echivalente.

Parameterul Kubernetes limits.memory corespunde flag-ului --memory din Docker. În cazul lui request.memory săgeata pentru Docker lipsește, deoarece Docker nu folosește acest câmp. Te poți întreba, este acesta cu adevărat necesar? Da, este. După cum am spus, câmpul are valoare pentru Kubernetes. Pe baza informațiilor din acesta, kube-scheduler decidă pe ce nod să planifice Podul.

Ce se va întâmpla dacă se solicită o memorie insuficientă?

Dacă containerul atinge limitele memoriei solicitate, Podul este plasat într-un grup de Poduri care se opresc în caz de insuficiență de memorie în nod.

Ce se va întâmpla dacă se setează o limită prea mică pentru memorie?

Dacă un container depășește limita de memorie, acesta va fi oprit din cauza OOM-Killed. Și va fi repornit, dacă acest lucru este posibil în funcție de RestartPolicy, unde valoarea implicită este Întotdeauna.

Ce se va întâmpla dacă nu se specifică memoria cerută?

Kubernetes va lua limita de memorie și o va stabili ca valoare implicită.

Ce se poate întâmpla dacă nu se specifică limita de memorie?

Containerul nu are restricții, poate utiliza atâta memorie cât dorește. Dacă începe să folosească întreaga memorie disponibilă a nodului, atunci va fi oprit de OOM. Apoi, containerul va fi repornit, dacă acest lucru este posibil pe baza RestartPolicy.

Ce se va întâmpla dacă nu se specifică limitele de memorie?

Acesta este cel mai rău scenariu: planificatorul nu știe câte resurse sunt necesare pentru container, iar acest lucru poate provoca probleme serioase pe nod. În acest caz, ar fi bine să existe limite implicite în spațiul de nume (stabilite de LimitRange). Nu există limite implicite - Pod-ul nu are restricții, poate folosi atâta memorie cât dorește.

Dacă memoria cerută este mai mare decât poate oferi nodul - Pod-ul nu va fi planificat. Este important de reținut că Requests.memory nu este o valoare minimă. Aceasta descrie cantitatea de memorie suficientă pentru funcționarea constantă a containerului.

De obicei, se recomandă să se stabilească aceeași valoare pentru request.memory și limit.memory. Datorită acestui fapt, Kubernetes nu va planifica Pod-ul pe un nod care are suficientă memorie pentru a rula Pod-ul, dar insuficientă pentru a funcționa. Rețineți: în timpul planificării Pod-ului, Kubernetes ia în considerare doar requests.memory, iar limits.memory nu ia în considerare.

CPU: cerere și limită

containere:
...
 resurse:
   cereri:
     cpu: 1
   limite:
     cpu: "1200m"

Referitor la CPU, lucrurile sunt puțin mai complicate. Revenind la imaginea cu relația dintre Kubernetes și Docker, se poate observa că request.cpu corespunde --cpu-shares, în timp ce limit.cpu corespunde flag-ului cpus în Docker.

CPU-ul cerut de Kubernetes se înmulțește cu 1024 — proporția ciclurilor CPU. Dacă doriți să solicitați 1 nucleu complet, trebuie să adăugați cpu: 1, așa cum este prezentat mai sus.

Cererea pentru un nucleu complet (proporție = 1024) nu înseamnă că containerul dumneavoastră îl va primi. Dacă serverul dumneavoastră gazdă are un singur nucleu și folosiți mai multe containere, atunci toate containerele trebuie să împartă CPU-ul disponibil între ele. Cum se întâmplă asta? Hai să aruncăm o privire la imagine.

Cum să obții acces la resursele Kubernetes Pod
Cererea CPU — sistem cu un singur nucleu

Imaginați-vă că aveți un sistem gazdă cu un singur nucleu, pe care rulează containere. Mama (Kubernetes) a făcut o plăcintă (CPU) și vrea să o împartă între copii (containere). Trei copii vor fiecare o plăcintă întreagă (proporție = 1024), iar un alt copil vrea o jumătate de plăcintă (512). Mama vrea să fie corectă și face un calcul simplu.

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

Conform calculului, cei trei copii vor primi câte 28% dintr-un nucleu, și nu un nucleu întreg. Al patrulea copil va primi 14% dintr-un nucleu complet, și nu jumătate. Dar totul va fi diferit dacă aveți un sistem multicore.

Cum să obții acces la resursele Kubernetes Pod
Cererea CPU — sistem multicore (4)

În imaginea de mai sus, se vede că trei copii vor fiecare o plăcintă întreagă, iar unul — o jumătate. Deoarece mama a făcut patru plăcinte, fiecare dintre copiii ei va primi tot ce dorește. Într-un sistem multicore, resursele procesorului sunt distribuite între toate nucleele disponibile. Dacă un container este limitat la mai puțin de un nucleu complet de CPU, tot poate folosi 100% din acesta.

Calculurile de mai sus sunt simplificate pentru a înțelege cum se distribuie CPU-ul între containere. Desigur, pe lângă containere, există și alte procese care folosesc resursele CPU. Atunci când procesele dintr-un container sunt inactive, altele pot folosi resursele acestuia. CPU: "200m" corespunde CPU: 0,2, ceea ce înseamnă aproximativ 20% dintr-un nucleu.

Acum să discutăm despre limit.cpu. CPU-ul, care limitează Kubernetes, este înmulțit cu 100. Rezultatul este cantitatea de timp pe care containerul o poate folosi la fiecare 100 µs (cpu-period).

limit.cpu corespunde flag-ului Docker --cpus. Aceasta reprezintă o nouă combinație a vechilor --cpu-period și --cpu-quota. Stabilindu-l, indicăm cât din resursele CPU poate folosi containerul până nu începe restricționarea:

  • cpus — combinația cpu-period și cpu-quota. cpus = 1.5 echivalează cu setarea cpu-period = 100000 și cpu-quota = 150000;
  • cpu-period — perioada planificatorului CPU CFS, implicit 100 microsecunde;
  • cpu-quota — numărul de microsecunde în cadrul cpu-period, la care este limitat containerul.

Ce se va întâmpla dacă se stabilește un CPU insuficient solicitat?

Dacă containerului îi este necesar mai mult decât este alocat, va fura CPU de la alte procese.

Ce se va întâmpla dacă se stabilește un limită insuficientă de CPU?

Deoarece resursa CPU este reglementată, se va activa throttling-ul.

Ce se va întâmpla dacă nu se specifică solicitarea de CPU?

La fel ca în cazul memoriei, valoarea solicitării este egală cu limita.

Ce se va întâmpla dacă nu se specifică limita de CPU?

Containerul va folosi cât CPU are nevoie. Dacă în spațiul de nume este definită o politică de CPU implicită (LimitRange), atunci această limită va fi folosită și pentru container.

Ce se va întâmpla dacă nu se specifică nici solicitarea, nici limita de CPU?

La fel ca în cazul memoriei, acesta este cel mai rău scenariu. Planificatorul nu știe câte resurse are nevoie containerul tău, iar aceasta poate provoca probleme serioase pe nod. Pentru a evita acest lucru, trebuie să se stabilească limitele implicite pentru spațiile de nume (LimitRange).

Amintiți-vă: dacă solicitați mai mult CPU decât pot oferi nodurile, pod-ul nu va fi planificat. Requests.cpu — nu o valoare minimă, ci o valoare suficientă pentru a porni pod-ul și a funcționa fără erori. Dacă aplicația nu efectuează calcule complexe, cea mai bună opțiune este să stabiliți request.cpu <= 1 și să lansați atâtea replici câte sunt necesare.

Cantitatea ideală de resurse solicitate sau limitate

Am învățat despre limitarea resurselor computaționale. Acum este timpul să răspundem la întrebarea: "Câte resurse necesită pod-ul meu pentru a rula aplicația fără probleme? Ce cantitate este ideală?".

Din păcate, nu există răspunsuri clare la aceste întrebări. Dacă nu știți cum funcționează aplicația dumneavoastră, câte CPU sau memorie îi sunt necesare, cea mai bună opțiune este să îi oferiți multe resurse de memorie și CPU și apoi să rulați teste de performanță.

În plus față de teste de performanță, observați comportamentul aplicației în monitorizare timp de o săptămână. Dacă din grafice reiese că aplicația dumneavoastră consumă mai puține resurse decât ați solicitat, atunci puteți reduce cantitatea de CPU sau memorie solicitată.

Ca exemplu, consultați acest dashboard Grafana. Acesta afișează diferența dintre resursele solicitate sau limita de resurse și utilizarea actuală a resurselor.

Concluzie

Cererea și limitarea resurselor ajută la menținerea funcționării clusterei Kubernetes. O configurație corectă a limitelor minimizează costurile și menține constant aplicațiile funcționale.

Pe scurt, trebuie să avem în vedere câteva aspecte:

  1. Resursele solicitate reprezintă configurația luată în considerare în timpul lansării (când Kubernetes planifică plasarea aplicației). În schimb, limitarea resurselor este importantă în timpul funcționării — când aplicația este deja lansată pe nod.
  2. Spre deosebire de memorie, CPU este o resursă reglementată. În cazul unei insuficiențe de CPU, Pod-ul tău nu se va opri, ci va activa mecanismul de throttling.
  3. Resursele solicitate și limita de resurse nu reprezintă valori minime și maxime! Stabilind resursele solicitate, te asiguri că aplicația va funcționa fără probleme.
  4. O practică bună este să setezi cererea de memorie egală cu limita de memorie.
  5. Este bine să setezi resursa solicitată CPU <=1, dacă aplicația nu efectuează calcule complexe.
  6. Dacă soliciți mai multe resurse decât sunt disponibile pe nod, Pod-ul nu va fi niciodată programat pe acest nod.
  7. Pentru a determina cantitatea corectă de resurse solicitate/limite de resurse, folosește testarea de încărcare și monitorizarea.

Sper că acest articol te va ajuta să înțelegi conceptul de bază al limitării resurselor. Și că vei putea aplica aceste cunoștințe în munca ta.

Good luck!

Ce altceva să citești:

  1. Observabilitatea SRE: spații de nume și structura metricilor.
  2. 90+ instrumente utile pentru Kubernetes: desfășurare, gestionare, monitorizare, securitate și altele.
  3. Our Around Kubernetes channel on Telegram.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster