Kako dostopati do virov Kubernetes Pod

Kako dostopati do virov Kubernetes PodNagrada od Tohada

Na početku rada s Kubernetes-om obično se zaboravlja na postavljanje resursa kontejnera. U ovoj fazi dovoljno je osigurati da Docker slika radi i da se može rasporediti unutar Kubernetes klastera.

No kasnije se aplikacija zahtijeva distribuirati unutar produkcijskog klastera zajedno s drugim aplikacijama. Za to je potrebno dodijeliti resurse kontejneru i osigurati da ih ima dovoljno za pokretanje i rad aplikacije, a da pritom u drugim pokrenutim aplikacijama ne dođe do problema.

Komanda Kubernetes aaS od Mail.ru prevela je članak o resursima kontejnera (CPU & MEM), zahtjevima i ograničenjima resursa. Saznat ćete koje prednosti pružaju ova podešavanja i što će se dogoditi ako ih ne postavite.

Računarski resursi

Imamo dva tipa resursa s sljedećim jedinicama:

  • Centralna procesorska jedinica (CPU) — jezgre;
  • Memorija (MEM) — bajtovi.

Resursi se navode za svaki kontejner. U sljedećem YAML fajlu Pod-a vidjet ćete odjeljak resursa koji sadrži tražene i maksimalne resurse:

  • Traženi resursi Pod-a = zbroj traženih resursa svih kontejnera;
  • Maksimalni resursi Pod-a = zbroj maksimalnih resursa svih kontejnera.

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 # TRAŽENI CPU: 200m jezgri
          memory: "1Gi" # TRAŽENA MEM: 1Gi
        limits:
          cpu: 1 # MAKSIMALNA UPOTREBA CPU: 1 jezgra
          memory: "1Gi" # MAKSIMALNA UPOTREBA MEM:  1Gi
    - name: other-container
      image: other-app
      tag: v1
      ports:
      - containerPort: 8000
      resources:
        requests:
          cpu: "200m" # TRAŽENI CPU: 200m jezgri
          memory: "0.5Gi" # TRAŽENA MEM: 0.5Gi
        limits:
          cpu: 1 # MAKSIMALNA UPOTREBA CPU: 1 jezgra
          memory: "1Gi" # MAKSIMALNA UPOTREBA MEM:  1Gi

Primjer traženih i maksimalnih resursa

Field resources.requested iz specifikacije Pod-a — jedan od elemenata koji se koristi za pronalaženje potrebne čvorove. Na njega se već može planirati raspored Pod-a. Kako pronalaze odgovarajući čvor?

Kubernetes se sastoji od nekoliko komponenti, uključujući glavni čvor ili majstorski čvor (Kubernetes Control Plane). U majstorskom čvoru postoji nekoliko procesa: kube-apiserver, kube-controller-manager i kube-scheduler.

Proces kube-scheduler odgovoran je za gledanje novo kreiranih modula i pronalaženje mogućih radnih čvorova koji udovoljavaju svim zahtjevima modula, uključujući količinu traženih resursa. Popis čvorova koje je pronašao kube-scheduler rangira se. Pod se planira na čvoru s najvišim bodovima.

Kako dostopati do virov Kubernetes PodGdje će biti postavljen ljubičasti Pod?

Na sliki je vidno, da kube-scheduler mora načrtovati nov vijolični Pod. Kubernetes klastra vsebuje dva vozlišča: A in B. Kot lahko opazite, kube-scheduler ne more načrtovati Poda na vozlišču A — na voljo (neprijavljeni) viri ne ustrezajo zahtevam vijoličnega Poda. Tako, da 1 GB pomnilnika, ki ga zahteva vijolični Pod, ne more biti nameščen na vozlišče A, saj je razpoložljivi pomnilnik le 0,5 GB. Vendar pa ima vozlišče B dovolj virov. Kube-scheduler tako odloči, da je ciljna lokacija vijoličnega Poda — vozlišče B.

Zdaj vemo, kako zahtevani viri vplivajo na izbiro vozlišča za zagon Poda. Ampak, kakšen vpliv imajo maksimalni viri?

Maksimalni viri so meja, ki je CPU/MEM ne more preseči. Kljub temu je vir CPU fleksibilen, zato doseženi maksimumi CPU ne povzročijo konca delovanja Poda. Namesto tega se prične trotljenje CPU. Če pa bo dosežen maksimum porabe MEM, bo vsebnik ustavljen zaradi OOM-Killer in ponovno zagnan, če to omogoča nastavitev RestartPolicy.

Zahtevani in maksimalni viri podrobno

Kako dostopati do virov Kubernetes PodPovezava virov med Dockerjem in Kubernetesom

Najboljši način za razlago delovanja zahtevanih in maksimalnih virov je predstavitev povezave med Kubernetesom in Dockerjem. Na zgornji sliki lahko vidite povezave med polji Kubernetes in zagonimi zastavicami Dockerja.

Pomnilnik: zahteva in omejitev

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

Kot je bilo omenjeno zgoraj, se pomnilnik meri v bajtih. Na podlagi dokumentacija Kubernetes, lahko pomnilnik označimo kot število. Običajno je celo število, na primer 2678 — torej 2678 bajtov. Uporabljajo se lahko tudi priponke G in Gi, pomembno pa je, da se zavedate, da niso enakovredni. Prvi je decimalni, drugi pa binarni. Kot primer, omenjen v dokumentaciji k8s: 128974848, 129e6, 129M, 123Mi — sta praktično ekvivalentna.

Parameter Kubernetes limits.memory ustreza zastavici --memory iz Dockra. V primeru request.memory zastavice za Docker ni, saj Docker tega polja ne uporablja. Morda se sprašujete, ali je to sploh potrebno? Da, potrebno je. Kot sem že povedal, je polje pomembno za Kubernetes. Na podlagi informacij iz njega kube-scheduler odloča, na katero vozlišče načrtovati Pod.

Kaj se zgodi, če nastavite nezadostno zahtevo po pomnilniku?

Če vsebnik doseže meje zahtevanega pomnilnika, se Pod doda v skupino Pod, ki se ustavi ob pomanjkanju pomnilnika na vozlišču.

Kaj se zgodi, če nastavite premajhno omejitev pomnilnika?

Če kontejner preseže omejitev pomnilnika, bo končan zaradi OOM-Killed. In znova se bo zagnal, če je to mogoče na podlagi RestartPolicy, kjer je privzeta vrednost — Vedno.

Kaj se zgodi, če ne navedete zahtevane pomnilniške kapacitete?

Kubernetes bo vzel omejitev in jo nastavil kot privzeto vrednost.

Kaj se lahko zgodi, če ne navedete omejenega pomnilnika?

Kontejner nima omejitev, lahko uporablja toliko pomnilnika, kolikor želi. Če pa začne uporabljati vse razpoložljive pomnilniške kapacitete vozlišča, ga bo ubil OOM. Nato bo kontejner znova zagnal, če je to mogoče na podlagi RestartPolicy.

Kaj se zgodi, če ne navedete omejitev pomnilnika?

To je na najslabšem scenariju: planer ne ve, koliko virov potrebuje kontejner, kar lahko povzroči resne težave na vozlišču. V tem primeru bi bilo dobro imeti privzete omejitve v imenskem prostoru (nastavljene z LimitRange). Privzetih omejitev ni — Pod nima omejitev, lahko uporablja toliko pomnilnika, kolikor želi.

Če je zahtevana pomnilniška kapaciteta večja, kot jo lahko ponudi vozlišče — Pod ne bo načrtovan. Pomembno je vedeti, da Requests.memory — ni minimalna vrednost. To je opis količine pomnilnika, dovolj za stalno delovanje kontejnerja.

Običajno priporočamo, da nastavljate enako vrednost za request.memory in limit.memory. S tem Kubernetes ne bo načrtoval Pod na vozlišču, ki ima dovolj pomnilnika za zagon Pod, vendar ne dovolj za njegovo delovanje. Upoštevajte: pri načrtovanju Pod Kubernetes upošteva samo requests.memory, a limits.memory ne pa tudi.

CPU: zahteva in omejitev

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

S CPU je vse nekoliko zapleteno. Če se vrnemo k sliki povezave med Kubernetes in Dockerjem, lahko opazimo, da request.cpu ustreza --cpu-shares, medtem ko limit.cpu ustreza zastavici cpu v Dockerju.

CPU, ki ga zahteva Kubernetes, se pomnoži s 1024 — razmerjem ciklov CPU. Če želite zahtevati 1 polno jedro, morate dodati cpu: 1, kot je prikazano zgoraj.

Zahteva polnega jedra (razmerje = 1024) ne pomeni, da bo vaš kontejner to tudi prejel. Če ima vaš gostiteljski računalnik le eno jedro in uporabljate več kot en kontejner, morajo vsi kontejnerji skupno uporabljati razpoložljiv CPU med seboj. Kako to poteka? Poglejmo sliko.

Kako dostopati do virov Kubernetes Pod
Zahteva CPU — sistem z enim jedrom

Predstavljajte si, da imate gostiteljski sistem z enim jedrom, na katerem so zagnani kontejnerji. Mama (Kubernetes) je spekla torto (CPU) in jo želi deliti med otroke (kontejnerje). Trije otroci želijo celo torto (razmerje = 1024), en otrok želi polovico torte (512). Mama želi biti poštena in opravi preprost izračun.

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

Na podlagi izračuna bodo trije otroci dobili po 28% jedra, namesto celotnega jedra. Četrtemu otroku bo pripadlo 14% celotnega jedra, namesto polovice. Vse pa bo drugače, če imate večjedrni sistem.

Kako dostopati do virov Kubernetes Pod
Zahteva CPU — večjedrni (4) sistem

Na sliki zgoraj je vidno, da trije otroci želijo celo torto, en pa polovico. Ker je mama spekla štiri torte, bo vsak od njenih otrok dobil, kar želi. V večjedrnem sistemu so procesorske zmogljivosti razdeljene po vseh razpoložljivih jedrih procesorja. Če je kontejner omejen na manj kot eno celotno jedro CPU, ga lahko vseeno uporablja v 100%.

Navedeni izračuni so poenostavljeni, da bi razumeli, kako se CPU deli med kontejnerje. Seveda pa poleg samih kontejnerjev obstajajo tudi drugi procesi, ki prav tako uporabljajo CPU vire. Ko procesi v enem kontejnerju mirujejo, lahko drugi uporabljajo njegove vire. CPU: "200m" ustreza CPU: 0,2, kar pomeni približno 20% enega jedra.

Sedaj pa se pogovorimo o limit.cpu. CPU, ki ga omejuje Kubernetes, se pomnoži s 100. Rezultat je količina časa, ki ga kontejner lahko uporabi vsake 100 mks (cpu-period).

limit.cpu ustreza zastavici Docker --cpus. To je nova kombinacija starih --cpu-period in --cpu-quota. Z njeno nastavitvijo določimo, koliko razpoložljivih CPU virov lahko kontejner maksimalno uporabi, preden se začne omejevanje:

  • cpu — kombinacija cpu-period in cpu-quota. cpus = 1.5 je enaka nastavitvi cpu-period = 100000 in cpu-quota = 150000;
  • cpu-period — obdobje CFS načrtovalnika CPU, privzeto 100 mikrosekund;
  • cpu-quota — število mikrosekund znotraj cpu-period, ki je omejeno za kontejner.

Kaj se zgodi, če je zahtevani CPU nezadosten?

Če kontejner potrebuje več, kot je nastavljeno, bo ukradel CPU od drugih procesov.

Kaj se zgodi, če je omejitev CPU nezadostna?

Ker je CPU vir reguliran, se vklopi omejevanje.

Kaj se zgodi, če ne navedete zahteve za CPU?

Kot pri pomnilniku, je vrednost zahtevka enaka omejitvi.

Kaj se zgodi, če ne navedete omejitve CPU?

Kontejner bo uporabil toliko CPU, kolikor jih potrebuje. Če je v imenskem prostoru določena standardna politika CPU (LimitRange), se ta omejitev uporablja tudi za kontejner.

Kaj se zgodi, če ne navedete niti zahtevka niti omejitve CPU?

Kot pri pomnilniku, je to najslabši scenarij. Načrtovalec ne ve, koliko virov potrebuje vaš kontejner, kar lahko povzroči resne težave na nodi. Da bi se temu izognili, je treba nastaviti privzete omejitve za imenske prostore (LimitRange).

Zapomnite si: če zahtevate več CPU, kot ga lahko zagotovijo nodi, nato Pod ne bo načrtovan. Requests.cpu – to ni minimalna vrednost, temveč vrednost, dovolj za zagon Pod in delovanje brez prekinitev. Če aplikacija ne izvaja zapletenih izračunov, je najboljša izbira nastaviti request.cpu <= 1 in zagnati toliko replik, kolikor je potrebno.

Idealna količina zaprošenih virov ali omejitve virov

Naučili smo se o omejitvi računalniških virov. Zdaj je čas, da odgovorimo na vprašanje: "Koliko virov potrebuje moj Pod, da aplikacija deluje brez težav? Kakšna količina je idealna?".

Na žalost ni enoznačnih odgovorov na ta vprašanja. Če ne veste, kako deluje vaša aplikacija, koliko CPU ali pomnilnika potrebuje, je najboljša izbira, da aplikaciji dodelite veliko pomnilnika in CPU, nato pa izvedete teste zmogljivosti.

Poleg testov zmogljivosti opazujte vedenje aplikacije v monitoringu skozi teden. Če iz grafikonov izhaja, da vaša aplikacija porablja manj virov, kot ste jih zahtevali, potem lahko zmanjšate količino zaprošenega CPU ali pomnilnika.

Kot primer si oglejte to Grafana nadzorno ploščo. Prikazuje razliko med zaprošenimi viri ali omejitvijo virov ter trenutnim uporabo virov.

Zaključek

Zahteve in omejitve virov pomagajo ohranjati delovanje Kubernetes grozda. Pravilna konfiguracija omejitev minimizira stroške in nenehno ohranja aplikacije v delovanju.

Na kratko, zapomniti si morate več stvari:

  1. Zahtevani resursi predstavljaju konfiguracijo, ki se upošteva med zagonom (ko Kubernetes načrtuje namestitev aplikacije). Nasprotno pa je omejitev virov pomembna med delovanjem — ko je aplikacija že zagnana na vozlišču.
  2. V primerjavi z pomnilnikom je CPU reguliran vir. V primeru pomanjkanja CPU vaš Pod ne bo končal dela, temveč se bo aktiviral mehanizem omejevanja.
  3. Zahtevani viri in omejitev virov niso minimalne in maksimalne vrednosti! Z določanjem zahtevanih virov zagotavljate, da bo aplikacija delovala brez težav.
  4. Dobra praksa je, da nastavite zahtevo pomnilnika, enako omejitvi pomnilnika.
  5. Dobro je nastaviti zahtevani CPU <=1, če aplikacija ne izvaja zahtevnih izračunov.
  6. Če zahtevate več virov, kot jih ima vozlišče, Pod nikoli ne bo načrtovan na to vozlišče.
  7. Za določitev pravega števila zahtevanih virov/omejitev virov uporabite obremenitveno testiranje in spremljanje.

Upam, da vam bo ta članek pomagal razumeti osnovno koncept omejevanja virov. In da boste lahko te informacije uporabili v svojem delu.

Srećno!

Šta još pročitati:

  1. Opaznost SRE: imenska prostorska in struktura metrik.
  2. 90+ korisnih alata za Kubernetes: implementacija, upravljanje, nadzor, bezbednost i još mnogo toga.
  3. Naš kanal Oko Kubernetes na Telegramu.

Izvor: habr.com

Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki 🔥 Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki | ProHoster