Deviat tipov na zvýšenie výkonu Kubernetes

Deviat tipov na zvýšenie výkonu Kubernetes

Ahojte všetci! Volám sa Oleg Sidorenkov, pracujem v spoločnosti DomKlik ako vedúci tímu infraštruktúry. Systém „Kostka“ prevádzkujeme v produkcii už viac ako tri roky a za ten čas sme prežili množstvo zaujímavých momentov. Dnes vám poviem, ako pri správnom prístupe môžeme z „vanilkového“ Kubernetes získať ešte viac výkonu pre váš klaster. Pripravený, pozor, start!

Všetci dobre viete, že Kubernetes je škálovateľný systém s otvoreným zdrojovým kódom na orchestráciu kontajnerov; alebo inak povedané, 5 binárnych súborov, ktoré vykonávajú kúzla, riadiac životný cyklus vašich mikroservisov v serverovom prostredí. Je to tiež dosť flexibilný nástroj, ktorý môžete zostaviť ako LEGO, aby vyhovoval rôznym úlohám.

A vyzerá to, že všetko je v poriadku: hádzajte servery do klastru ako drevo do pece a žiadny problém. Ale ak ste ekologicky zameraní, zamyslíte sa: „Ako môžem udržiavať oheň v peci a zároveň šetriť les?“. Inými slovami, ako nájsť spôsoby na zlepšenie infraštruktúry a zníženie nákladov.

1. Sledujte zdroje tímov a aplikácií

Deviat tipov na zvýšenie výkonu Kubernetes

Jedna z najzákladnejších, ale účinných metód je zavedenie requests/limits. Rozdeľte aplikácie do namespaces a namespaces podľa vývojových tímov. Pred nasadením nastavte aplikácii hodnoty pre spotrebu procesorového času, pamäte a efemérneho ukladania.

resources:
   requests:
     memory: 2Gi
     cpu: 250m
   limits:
     memory: 4Gi
     cpu: 500m

Skúsenosti nás naučili, že nemá zmysel nafukovať požiadavky nad limity viac než dvakrát. Objem klastru sa počíta na základe požiadaviek a ak nastavíte aplikáciám rozdiel v zdrojoch, napríklad 5-10 násobne, predstavte si, čo sa stane s vašou uzlom, keď sa naplní podmi a náhle dostane záťaž. Nič dobré. Minimálne spomalenie, v najhoršom prípade sa rozlúčite s pracovníkom a dostanete cyklickú záťaž na ostatné uzly, keď začnú podi prechádzať.

Okrem toho je možné pomocou limitranges môžete pri štarte nastaviť pre kontajner hodnoty zdrojov — minimálne, maximálne a predvolené:

➜  ~ kubectl describe limitranges --namespace ops
Name:       limit-range
Namespace:  ops
Type        Resource           Min   Max   Default Request  Default Limit  Max Limit/Request Ratio
----        --------           ---   ---   ---------------  -------------  -----------------------
Container   cpu                50m   10    100m             100m           2
Container   ephemeral-storage  12Mi  8Gi   128Mi            4Gi            -
Container   memory             64Mi  40Gi  128Mi            128Mi          2

Nezabudnite obmedziť prostriedky namespace, aby jedna skupina nemohla získať všetky prostriedky klastru:

➜  ~ kubectl describe resourcequotas --namespace ops
Name:                   resource-quota
Namespace:              ops
Resource                Used          Hard
--------                ----          ----
limits.cpu              77250m        80
limits.memory           124814367488  150Gi
pods                    31            45
requests.cpu            53850m        80
requests.memory         75613234944   150Gi
services                26            50
services.loadbalancers  0             0
services.nodeports      0             0

Z popisu je zrejmé resourcequotas, ak chce tím ops nasadiť pady, ktoré budú spotrebúvať ďalších 10 cpu, plánovač to nedovolí a vyhlási chybu:

Error creating: pods "nginx-proxy-9967d8d78-nh4fs" is forbidden: exceeded quota: resource-quota, requested: limits.cpu=5,requests.cpu=5, used: limits.cpu=77250m,requests.cpu=53850m, limited: limits.cpu=10,requests.cpu=10

Na vyriešenie podobnej úlohy je možné napísať nástroj, napríklad ako web, ktorý dokáže uchovávať a zdieľať stav zdrojov tímov.

2. Vyberte optimálne úložisko súborov

Deviat tipov na zvýšenie výkonu Kubernetes

Tu by som chcel načrtnúť tému persistentných objemov a diskových subsystémov worker-nód Kubernetes. Dúfam, že nikto nepoužíva „Kube“ na HDD v produkcii, ale občas je aj bežný SSD už nedostatočný. Stretli sme sa s problémom, že logy preťažovali disk pri operáciách vstupu a výstupu, a tu nie je veľa možností riešenia:

  • Použiť vysoko výkonné SSD alebo prejsť na NVMe (ak si sami spravujete svoje zariadenia).

  • Znížiť úroveň logovania.

  • Vykonávať "inteligentné" vyvažovanie podov, ktoré zaťažujú disk (podAntiAffinity).

Snímka vyššie ukazuje, čo sa deje pod nginx-ingress-controller s diskom, keď je povolené logovanie access_logs (~12 tisíc záznamov/sec.). Takýto stav môže samozrejme viesť k degradácii všetkých aplikácií na tejto nód.

Čo sa týka PV, žiaľ, nevyskúšal som všetky druhy Trvalé objemy. Použite najlepšiu možnosť, ktorá vyhovuje práve vám. Historicky sa stalo, že malá časť služieb potrebuje RWX objemy, a na tento účel sa už dávno začalo používať NFS úložisko. Je to lacné a… stačí to. Samozrejme, že sme sa s ním naplno zažili ťažkosti — zdravím vás, ale naučili sme sa ho optimalizovať, takže nás to už netrápi. A ak je to možné, prejdite na objektové úložisko S3.

3. Zbierajte optimalizované obrazy

Deviat tipov na zvýšenie výkonu Kubernetes

Najlepšie je používať obrazy optimalizované pre kontajnery, aby Kubernetes mohol rýchlejšie ich získavať a efektívnejšie vykonávať. 

Optimalizácia znamená, že obrazy:

  • obsahujú iba jednu aplikáciu alebo vykonávajú iba jednu funkciu;

  • sú malých rozmerov, pretože veľké obrazy sa ťažšie prenášajú cez sieť;

  • majú koncové body na kontrolu funkčnosti a pripravenosti, pomocou ktorých Kubernetes môže vykonávať určité akcie v prípade výpadkov;

  • používajú operačné systémy priateľské ku kontajnerom (ako Alpine alebo CoreOS), ktoré sú odolnejšie voči chybám konfigurácie;

  • používajú viacstupňové zostavenia, aby ste mohli nasadzovať iba skompilované aplikácie a nie súvisiace zdrojové kódy.

Existuje mnoho nástrojov a služieb, ktoré umožňujú kontrolovať a optimalizovať obrazy naživo. Je dôležité ich vždy udržiavať aktuálne a bezpečne overené. Nakoniec dostanete:

  1. Zníženie sieťovej záťaže na celý klaster.

  2. Zníženie času spustenia kontajnera.

  3. Menší objem celého vášho Docker registry.

4. Používajte DNS cache

Deviat tipov na zvýšenie výkonu Kubernetes

Ak hovoríme o vysokých záťažiach, bez ladenia DNS systému klastrov je život dosť zlý. Kedysi dávno vývojári Kubernetes podporovali svoje riešenie kube-dns. To bolo implementované aj u nás, ale táto softvér nebola predmetom optimalizácie a nedosahovala požadovaný výkon, aj keď, zdalo by sa, že úloha je jednoduchá. Následne sa objavil coredns, na ktorý sme prešli a žiadne starosti sme nemali; nakoniec sa stal predvoleným DNS službou v K8s. V istom momente sme dosiahli 40 000 rps na DNS systéme a toto riešenie už tiež nestačilo. Ale, na šťastnú náhodu, vyšiel Nodelocaldns, tiež známy ako node local cache, tiež NodeLocal DNSCache.

Prečo to používame? V jadre Linuxu je chyba, ktorá pri viacerých požiadavkách prostredníctvom conntrack NAT cez UDP vedie k závode o zápisy do conntrack tabuliek, pričom časť dopravy cez NAT sa stratí (každý prístup cez službu je NAT). Nodelocaldns rieši tento problém eliminovaním NAT a vylepšením pripojenia na TCP k upstreamovým DNS, ako aj lokálnym cachingom DNS požiadaviek na upstreamy (vrátane krátkeho 5-sekundového negatívneho cache).

5. Automaticky horizontálne a vertikálne škálujte pod.

Deviat tipov na zvýšenie výkonu Kubernetes

Môžete si s istotou povedať, že všetky vaše mikroslužby sú pripravené na dvoj- až trojnásobný nárast zaťaženia? Ako správne prideľovať zdroje svojim aplikáciám? Držať bežiace niekoľko podov nad pracovnou záťažou sa môže ukázať ako nadbytočné, a ak ich budete držať na hranici, riskujete výpadok v prípade náhleho nárastu prevádzky na službu. Zlatej strednej cesty môže pomôcť dosiahnuť kouzlo násobenia, ako sú Horizontal Pod Autoscaler a Vertical Pod Autoscaler.

VPA umožňuje automaticky zvyšovať requests/limits vašich kontajnerov v pode v závislosti od skutočného využitia. Ako vám môže byť užitočný? Ak máte pod, ktorý z nejakého dôvodu nemôže byť horizontálne škálovaný (čo nie je úplne spoľahlivé), môžete skúsiť zveriť zmenu jeho zdrojov VPA. Jeho výhodou je systém odporúčaní založený na historických a aktuálnych údajoch z metric-server, takže ak nechcete automaticky meniť requests/limits, môžete sledovať odporúčané zdroje pre vaše kontajnery a optimalizovať nastavenia za účelom úspory CPU a pamäte v klastri.

Deviat tipov na zvýšenie výkonu KubernetesObrázok prevzatý z https://levelup.gitconnected.com/kubernetes-autoscaling-101-cluster-autoscaler-horizontal-pod-autoscaler-and-vertical-pod-2a441d9ad231

Rozvrhovač v Kubernetes sa vždy zakladá na requests. Akúkoľvek hodnotu tam nastavíte, rozvrhovač hľadá vhodný uzol na základe nej. Hodnoty limits sú potrebné kubletu na pochopenie, kedy obmedziť alebo zabiť pod. A keďže jediným dôležitým parametrom je hodnota requests, VPA bude pracovať s ňou. Kedykoľvek nastavíte vertikálne škálovanie aplikácie, určujete, aké by mali byť requests. A čo sa teda stane s limits? Tento parameter bude tiež proporcionálne škálovaný.

Napríklad, tu sú bežné nastavenia podu:

zdroje:
   požiadavky:
     pamäť: 250Mi
     procesor: 200m
   limity:
     pamäť: 500Mi
     procesor: 350m

Mechanizmus odporúčaní určuje, že vašej aplikácii na normálnu prevádzku je potrebných 300m CPU a 500Mi. Získate takéto nastavenia:

zdroje:
   požiadavky:
     pamäť: 500Mi
     procesor: 300m
   limity:
     pamäť: 1000Mi
     procesor: 525m

Ako bolo spomenuté vyššie, ide o proporcionálne škálovanie na základe pomeru požiadaviek/limitov v manifeste:

  • CPU: 200m → 300m: pomer 1:1.75;

  • Pamäť: 250Mi → 500Mi: pomer 1:2.

Čo sa týka HPA, tu je mechanizmus práce transparentnejší. Sú nastavené prahové hodnoty metrík, napríklad procesor a pamäť, a ak priemerná hodnota všetkých replik prekročí prahovú hodnotu, aplikácia sa škáluje o +1 pod až kým hodnoty neklesnú pod prah alebo kým sa nedosiahne maximálny počet replik.

Deviat tipov na zvýšenie výkonu KubernetesObrázok prevzatý z https://levelup.gitconnected.com/kubernetes-autoscaling-101-cluster-autoscaler-horizontal-pod-autoscaler-and-vertical-pod-2a441d9ad231

Okrem bežných metrík, ako sú procesor a pamäť, môžete nastaviť prahy na vlastných metrík zo systému Prometheus a pracovať s nimi, ak to považujete za najpresnejšiu definíciu, kedy by ste mali škálovať vašu aplikáciu. Po stabilizácii aplikácie pod zadanú hranicou metriky, HPA začne znižovať počet podov až na minimum replik alebo na stav, kedy bude záťaž vyhovovať zadanému prahu.

6. Nezabúdajte na Node Affinity a Pod Affinity.

Deviat tipov na zvýšenie výkonu Kubernetes

Nie všetky uzly sú na rovnakom hardvéri, nie všetkým podom je potrebné vykonávať aplikácie, ktoré vyžadujú intenzívne výpočty. Kubernetes umožňuje nastaviť špecializáciu uzlov a podov pomocou Node Affinity a Pod Affinity.

Ak máte uzly, ktoré sú vhodné na operácie s vysokou intenzitou výpočtov, pre maximálnu efektívnosť je lepšie priradiť aplikácie k príslušným uzlom. Na to použite nodeSelector s označením uzla.

Predpokladajme, že máte dva uzly: jeden s CPUType=HIGHFREQ a s veľkým počtom rýchlych jadier, druhý s MemoryType=HIGHMEMORY veľkým množstvom pamäte a vyššou výkonnosťou. Najjednoduchšie je priradiť nasadenie podu uzlu HIGHFREQ, pridaním do sekcie spec takého selektora:

…
nodeSelector:
	CPUType: HIGHFREQ

Nákladnejší a špecifickejší spôsob, ako to dosiahnuť, je použiť nodeAffinity v poli affinity v sekcii spec. Existujú dve možnosti:

  • requiredDuringSchedulingIgnoredDuringExecution: prísne nastavenie (plánovač bude nasadzovať pody iba na konkrétnych uzloch (a nikde inde));

  • preferredDuringSchedulingIgnoredDuringExecution: jemné nastavenie (plánovač sa pokúsi nasadiť na konkrétnych nodoch, a ak to nebude možné, pokúsi sa nasadiť na nasledujúcom dostupnom node).

Môžete zadať určitú syntax riadenia značkami uzlov, napríklad, In, NotIn, Exists, DoesNotExist, Gt alebo Lt. Pamätajte však, že zložité metódy v dlhých zoznamoch značiek spomaľujú rozhodovanie v kritických situáciách. Inými slovami, nezložte to.

Ako bolo spomenuté vyššie, Kubernetes umožňuje nastaviť viazanie aktuálnych podov. To znamená, že môžete nastaviť, aby určité pody fungovali spolu s ďalšími podmi v tej istej zóne dostupnosti (aktuálne pre cloudy) alebo nodoch.

V podAffinity polí affinity v sekcii spec sú k dispozícii tie isté polia, čo sa týka nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution a preferredDuringSchedulingIgnoredDuringExecution. Jediný rozdiel je v tom, že matchExpressions pripúta pody k node, na ktorej už beží pod s touto značkou.

Ešte Kubernetes ponúka pole podAntiAffinity, ktoré naopak nepripája pod k node s určitými podmi.

Pokiaľ ide o výrazy nodeAffinity , môžete dať rovnakú radu: snažte sa zachovať jednoduchosť a logiku pravidiel, nesnažte sa preťažiť špecifikáciu podov zložitou sadou pravidiel. Je veľmi jednoduché vytvoriť pravidlo, ktoré nebude zodpovedať podmienkam klastru, čím vytvoríte zbytočné zaťaženie plánovača a znížite celkovú výkonnosť.

7. Taints & Tolerations

Existuje ešte jeden spôsob správy plánovača. Ak máte veľký klaster so stovkami uzlov a tisíckami mikroslužieb, je veľmi ťažké neumožniť určitým podom umiestniť sa na určitých uzloch.

Toto pomáha mechanizmus taints — zakazujúcich pravidiel. Napríklad, v určitých scenároch je možné zakázať určitým uzlom spúšťať u seba pody. Na použitie taint na konkrétnom uzle musíte použiť možnosť taint v kubectl. Zadajte kľúč a hodnotu, a potom taint ako NoSchedule alebo NoExecute:

$ kubectl taint nodes node10 node-role.kubernetes.io/ingress=true:NoSchedule

Rovnako stojí za zmienku, že mechanizmus taint podporuje tri hlavné efekty: NoSchedule, NoExecute a PreferNoSchedule.

  • NoSchedule znamená, že pokiaľ v špecifikácii podu nebude zodpovedajúci záznam tolerations, nemôže byť nasadený na node (v tomto príklade node10).

  • PreferNoSchedule — zjednodušená verzia NoSchedule. V tomto prípade sa plánovač pokúsi nepriraďovať pody, ktoré nemajú zodpovedajúci záznam tolerations na node, ale to nie je tvrdé obmedzenie. Ak v klastru nebudú zdroje, pody sa začnú nasadzovať na tento uzol.

  • NoExecute — tento efekt spúšťa okamžitú evakuáciu podov, ktoré nemajú zodpovedajúci záznam tolerations.

Zaujímavé je, že toto správanie je možné zrušiť pomocou mechanizmu tolerancií. Je to pohodlné, keď existuje „zakázaný“ uzol a chcete na ňom umiestniť iba infraštruktúrne služby. Ako to dosiahnuť? Povoliť iba tie pody, pre ktoré existuje vhodná tolerancia.

Takto bude vyzerať špecifikácia podu:

spec:
   tolerations:
     - key: "node-role.kubernetes.io\/ingress"
        operator: "Equal"
        value: "true"
        effect: "NoSchedule"

To neznamená, že pri ďalšom redeploy sa pod dostane presne na tento uzol, nie je to mechanizmus Node Affinity a nodeSelector. Ale kombinovaním niekoľkých funkcií môžete dosiahnuť veľmi flexibilné nastavenie plánovača.

8. Nastavte prioritu nasadzovania podov

To, že ste nastavili viazanosť podov na uzly, neznamená, že všetky pody musia byť spracovávané s rovnakou prioritou. Napríklad, môžete chcieť nasadzovať určité pody skôr ako ostatné.

Kubernetes ponúka rôzne spôsoby, ako nastaviť prioritu podov (Pod Priority and Preemption). Nastavenie sa skladá z niekoľkých častí: objektu PriorityClass a opisu poľa priorityClassName v špecifikácii podu. Pozrime sa na príklad:

apiVersion: scheduling.k8s.io\/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 99999
globalDefault: false
description: "Tento priorita triedy by sa mala používať iba pre veľmi dôležité pody"

Vytvárame PriorityClass, nastavujeme mu meno, popis a hodnotu. Čím vyššia value, tým vyššia priorita. Hodnota môže byť akékoľvek 32-bitové celé číslo, menšie alebo rovné 1 000 000 000. Vyššie hodnoty sú rezervované pre kriticky dôležité systémové pody, ktoré zvyčajne nemôžu byť vytlačené. Vytlačenie sa uskutoční iba vtedy, ak nebude mať vysoko priorizovaný pod, kde sa umiestniť, v takom prípade budú evakuované niektoré pody z určitého uzla. Ak je pre vás tento mechanizmus príliš prísny, môžete pridať možnosť preemptionPolicy: Never, a potom nevytláčanie nebude, pod bude stáť prvý v rade a čakať, až plánovač nájde pre neho voľné zdroje.

Ďalej vytvoríme pod, v ktorom uvedieme meno priorityClassName:

apiVersion: v1
kind: Pod
metadata:
  name: static-web
  labels:
    role: myrole
 spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: web
          containerPort: 80
          protocol: TCP
  priorityClassName: high-priority
          

Môžete vytvárať neobmedzený počet tried priorít, hoci sa odporúča to nepreháňať (povedzme, obmedziť sa na nízky, stredný a vysoký prioritu).

Takto, v prípade potreby, zvýšite efektivitu nasadenia kritických služieb ako nginx-ingress-controller, coredns a podobne.

9. Optimalizujte ETCD klaster

Deviat tipov na zvýšenie výkonu Kubernetes

ETCD môžeme nazvať mozgom celého klastra. Je veľmi dôležité udržiavať túto databázu na vysokej úrovni, pretože od nej závisí rýchlosť operácií v "Kube". Celkom štandardným a zároveň dobrým riešením je mať ETCD klaster na master-node, aby ste mali minimálnu latenciu na kube-apiserver. Ak to nie je možné, umiestnite ETCD čo najbližšie, pričom zabezpečte dobrú prenosovú kapacitu medzi účastníkmi. Taktiež si dávajte pozor na to, koľko nodov z ETCD môže vypadnúť bez poškodenia klastra.

Deviat tipov na zvýšenie výkonu Kubernetes

Beriete do úvahy, že nadmerné zvyšovanie počtu účastníkov v klastri môže zvýšiť odolnosť voči výpadkom na úkor výkonu, všetko musí byť v miere.

Pokiaľ ide o nastavenie služby, odporúčaní je málo:

  1. Mať dobrý hardvér na základe veľkosti klastra (môžete si prečítať tu).

  2. Upraviť niekoľko parametrov, ak ste rozprestrel klastra medzi pár DC alebo vaša sieť a disky nie sú optimálne (môžete si prečítať tu).

Záver

V tomto článku sú uvedené body, ktoré sa naša tím snaží dodržiavať. Nie je to krok za krokom popis ukončenia, ale varianty, ktoré môžu byť užitočné pri optimalizácii nákladov na klaster. Je jasné, že každý klaster je unikátny a riešenia pre nastavenie sa môžu veľmi líšiť, preto by bolo zaujímavé dostať od vás spätnú väzbu: ako sledujete svoj Kubernetes klaster, čím zlepšujete jeho výkon. Podeľte sa o svoje skúsenosti v komentároch, bude zaujímavé ich spoznať.

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster