Níu Kubernetes árangursráð

Níu Kubernetes árangursráð

Hæ allir! Ég heiti Oleg Sidorenkov, ég vinn hjá DomClick sem innviðateymisstjóri. Við höfum notað teninginn til sölu í meira en þrjú ár og á þessum tíma höfum við upplifað margar mismunandi áhugaverðar stundir með honum. Í dag mun ég segja þér hvernig, með réttri nálgun, þú getur kreist enn meiri frammistöðu úr vanillu Kubernetes fyrir klasann þinn. Viðbúinn tilbúinn nú!

Þið vitið öll vel að Kubernetes er stigstærð opinn uppspretta kerfi til að skipuleggja gáma; vel, eða 5 tvístirni sem gera töfra með því að stjórna lífsferli örþjónustunnar þinna í netþjónsumhverfi. Að auki er þetta nokkuð sveigjanlegt tól sem hægt er að setja saman eins og Lego smið til að sérsníða fyrir mismunandi verkefni.

Og allt virðist vera í lagi: hentu netþjónum inn í þyrpinguna, eins og eldivið í eldhólf, og þekki ekki sorgina. En ef þú ert fyrir umhverfið, þá muntu hugsa: "Hvernig get ég haldið eldinum í eldavélinni og séð eftir skóginum?". Með öðrum orðum, hvernig á að finna leiðir til að bæta innviði og draga úr kostnaði.

1. Fylgstu með auðlindum liðs og forrita

Níu Kubernetes árangursráð

Ein banalasta en áhrifaríkasta aðferðin er innleiðing beiðna/takmarkana. Aðskilið forrit eftir nafnasvæðum og nafnrými eftir þróunarteymi. Stilltu forritið áður en þú setur gildi fyrir neyslu á örgjörvatíma, minni, skammvinnri geymslu.

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

Af reynslu komumst við að þeirri niðurstöðu: það er ekki þess virði að blása upp beiðnir frá mörkum oftar en tvisvar. Klasastærðin er reiknuð út frá beiðnum og ef þú stillir forritið á mismun á tilföngum, til dæmis um 5-10 sinnum, ímyndaðu þér þá hvað verður um hnútinn þinn þegar hann fyllist af belgjum og fær skyndilega álag. Ekkert gott. Að minnsta kosti, inngjöf, og að hámarki, segðu bless við starfsmanninn og fáðu hringlaga álag á restina af hnútunum eftir að belgirnir byrja að hreyfast.

Að auki, með hjálp limitranges þú getur stillt auðlindagildi fyrir ílátið í upphafi - lágmark, hámark og sjálfgefið:

➜  ~ 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

Mundu að takmarka tilföng nafnrýmis þannig að ein skipun geti ekki tekið öll tilföng þyrpingarinnar:

➜  ~ 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

Eins og sjá má af lýsingunni resourcequotas, ef ops skipunin vill dreifa belg sem munu eyða 10 örgjörva í viðbót, þá mun tímaáætlunarmaðurinn ekki leyfa það og mun gefa út villu:

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

Til að leysa svipað vandamál geturðu skrifað verkfæri, til dæmis, sem þetta, sem getur geymt og framkvæmt stöðu stjórnvalda.

2. Veldu bestu skráargeymsluna

Níu Kubernetes árangursráð

Hér langar mig að snerta efni viðvarandi bindi og diska undirkerfi Kubernetes vinnuhnúta. Ég vona að enginn noti "Cube" á HDD í framleiðslu, en stundum dugar jafnvel venjulegur SSD ekki nú þegar. Við stóðum frammi fyrir slíku vandamáli að annálarnir voru að drepa diskinn með I / O aðgerðum og það eru ekki mjög margar lausnir hér:

  • Notaðu afkastamikla SSD diska eða skiptu yfir í NVMe (ef þú stjórnar eigin vélbúnaði).

  • Minnka stig skráningar.

  • Gerðu "snjöll" jafnvægi á fræbelgjum sem nauðga disknum (podAntiAffinity).

Skjámyndin hér að ofan sýnir hvað gerist undir nginx-ingress-controller með diski þegar access_logs er virkt (~12k logs/sek). Slíkt ástand getur auðvitað leitt til hnignunar á öllum forritum á þessum hnút.

Hvað varðar PV, því miður, ég hef ekki prófað allt. tegundir Viðvarandi bindi. Notaðu besta kostinn sem hentar þér. Það hefur sögulega gerst í okkar landi að lítill hluti þjónustu þarf RWX bindi og fyrir löngu síðan fóru þeir að nota NFS geymslu fyrir þetta verkefni. Ódýrt og ... nóg. Auðvitað borðuðum við skít með honum - vertu heilbrigður, en við lærðum að stilla hann og hausinn hans er ekki lengur sár. Og ef mögulegt er skaltu skipta yfir í S3 hlutageymslu.

3. Byggja bjartsýni myndir

Níu Kubernetes árangursráð

Best er að nota gáma-bjartsýni myndir svo Kubernetes geti sótt þær hraðar og framkvæmt þær á skilvirkari hátt. 

Hagræðing þýðir að myndir:

  • innihalda aðeins eitt forrit eða framkvæma aðeins eina aðgerð;

  • lítil stærð, vegna þess að stórar myndir eru verr sendar um netið;

  • hafa heilsu- og viðbúnaðarendapunkta sem Kubernetes getur notað til að grípa til aðgerða ef stöðvun er;

  • nota gámavæn stýrikerfi (eins og Alpine eða CoreOS) sem eru ónæmari fyrir stillingarvillum;

  • notaðu fjölþrepa smíðar þannig að þú getur aðeins sett upp samansett forrit en ekki meðfylgjandi heimildir.

Það eru mörg tæki og þjónusta sem gerir þér kleift að athuga og fínstilla myndir á flugu. Það er mikilvægt að halda þeim alltaf uppfærðum og öruggum. Fyrir vikið færðu:

  1. Minni netálag á allan klasann.

  2. Minnkaður ræsingartími gáma.

  3. Minni stærð af allri Docker skránni þinni.

4. Notaðu DNS skyndiminni

Níu Kubernetes árangursráð

Ef við tölum um mikið álag, þá er lífið frekar ömurlegt án þess að stilla DNS kerfi klasans. Einu sinni studdu Kubernetes forritararnir kube-dns lausnina sína. Það var einnig innleitt í okkar landi, en þessi hugbúnaður var ekki sérstaklega stilltur og gaf ekki nauðsynlegan árangur, þó að það virðist vera einfalt verkefni. Svo birtist coredns, sem við skiptum yfir í og ​​vissum ekki sorg, síðar varð það sjálfgefin DNS þjónusta í K8s. Á einhverjum tímapunkti óxum við upp í 40 þúsund rps í DNS kerfið og þessi lausn var heldur ekki nóg. En fyrir tilviljun kom Nodelocaldns út, aka hnútur staðbundinn skyndiminni, aka NodeLocal DNSCache.

Af hverju erum við að nota það? Það er galli í Linux kjarnanum sem, þegar margfaldur aðgangur í gegnum conntrack NAT yfir UDP, leiðir til keppnisskilyrði fyrir að skrifa í conntrack töflurnar og hluti af umferð í gegnum NAT tapast (hver ferð í gegnum þjónustuna er NAT). Nodelocaldns leysir þetta vandamál með því að losna við NAT og uppfæra TCP tengingu við andstreymis DNS, auk þess að vista andstreymis DNS fyrirspurnir á staðnum (þar á meðal stutt 5 sekúndna neikvæð skyndiminni).

5. Skala belg lárétt og lóðrétt sjálfkrafa

Níu Kubernetes árangursráð

Geturðu sagt með vissu að allar örþjónustur þínar séu tilbúnar fyrir tvöfalt til þrefalt álag? Hvernig á að úthluta auðlindum rétt í forritin þín? Það getur verið óþarfi að halda nokkrum belgjum í gangi umfram vinnuálagið og að halda þeim bak við bak er hætta á niður í miðbæ vegna skyndilegrar aukningar á umferð til þjónustunnar. Hinn gullni meðalvegur hjálpar til við að ná margföldunarálögum svo sem þjónustu eins og Láréttur Pod Autoscaler и Vertical Pod Autoscaler.

VPA gerir þér kleift að hækka sjálfkrafa beiðnir/takmörk ílátanna þinna í belg byggt á raunverulegri notkun. Hvernig getur það verið gagnlegt? Ef þú ert með pods sem af einhverjum ástæðum er ekki hægt að minnka lárétt (sem er ekki alveg áreiðanlegt), þá geturðu reynt að treysta VPA til að breyta auðlindum þess. Eiginleiki þess er meðmælakerfi byggt á sögulegum og núverandi gögnum frá metric-miðlara, þannig að ef þú vilt ekki breyta beiðnum/takmörkunum sjálfkrafa geturðu einfaldlega fylgst með ráðlögðum auðlindum fyrir ílátin þín og fínstillt stillingarnar til að spara CPU og minni í klasanum.

Níu Kubernetes árangursráðMynd tekin af https://levelup.gitconnected.com/kubernetes-autoscaling-101-cluster-autoscaler-horizontal-pod-autoscaler-and-vertical-pod-2a441d9ad231

Tímaáætlunin í Kubernetes er alltaf byggð á beiðnum. Hvaða gildi sem þú setur þarna, mun tímaáætlunarmaðurinn leita að hentugum hnút byggt á því. Takmarkagildið er nauðsynlegt fyrir kublettinn til að vita hvenær á að inngjöf eða drepa belg. Og þar sem eina mikilvæga færibreytan er beiðnagildið mun VPA vinna með það. Alltaf þegar þú skalar forritið þitt lóðrétt skilgreinir þú hvaða beiðnir eiga að vera. Og hvað verður þá um mörkin? Þessi færibreyta verður einnig skaluð hlutfallslega.

Til dæmis, hér eru dæmigerðar pod stillingar:

resources:
   requests:
     memory: 250Mi
     cpu: 200m
   limits:
     memory: 500Mi
     cpu: 350m

Meðmælisvélin ákvarðar að forritið þitt þurfi 300m CPU og 500Mi til að keyra rétt. Þú færð þessar stillingar:

resources:
   requests:
     memory: 500Mi
     cpu: 300m
   limits:
     memory: 1000Mi
     cpu: 525m

Eins og getið er hér að ofan er þetta hlutfallsstærð miðað við hlutfall beiðna/takmarka í upplýsingaskránni:

  • Örgjörvi: 200m → 300m: hlutfall 1:1.75;

  • Minni: 250Mi → 500Mi: 1:2 hlutfall.

Eins varðar HPA, þá er rekstraraðferðin gagnsærri. Þröskuldar eru stilltir fyrir mælikvarða eins og örgjörva og minni, og ef meðaltal allra eftirmynda fer yfir viðmiðunarmörkin, þá skalast forritið um +1 pod þar til gildið fer undir viðmiðunarmörkin, eða þar til hámarksfjölda eftirmynda er náð.

Níu Kubernetes árangursráðMynd tekin af https://levelup.gitconnected.com/kubernetes-autoscaling-101-cluster-autoscaler-horizontal-pod-autoscaler-and-vertical-pod-2a441d9ad231

Til viðbótar við venjulega mælikvarða eins og örgjörva og minni geturðu stillt þröskulda á sérsniðnum Prometheus mæligildum þínum og unnið með þær ef þér finnst þetta vera nákvæmasta leiðin til að ákvarða hvenær á að skala forritið þitt. Þegar forritið er komið á stöðugleika undir tilgreindum mælikvarða mun HPA byrja að stækka pods niður í lágmarksfjölda eftirlíkinga eða þar til álagið nær þröskuldinum.

6. Ekki gleyma hnútasækni og fræbelgsækni

Níu Kubernetes árangursráð

Ekki eru allir hnútar keyrðir á sama vélbúnaði og ekki þurfa allir hnúðar að keyra tölvufrek forrit. Kubernetes gerir þér kleift að tilgreina sérhæfingu hnúta og fræbelgja með því að nota Hnútsækni и Pod Affinity.

Ef þú ert með hnúta sem henta fyrir tölvufrekar aðgerðir, þá er betra að binda forrit við viðeigandi hnúta fyrir hámarks skilvirkni. Til að gera þetta, notaðu nodeSelector með hnútamerki.

Segjum að þú sért með tvo hnúta: einn með CPUType=HIGHFREQ og mikill fjöldi hraðkjarna, annar með MemoryType=HIGHMEMORY meira minni og hraðari árangur. Auðveldasta leiðin er að úthluta pod-dreifingu á hnút HIGHFREQmeð því að bæta við kaflann spec valkostur eins og þessi:

…
nodeSelector:
	CPUType: HIGHFREQ

Dýrari og sértækari leið til að gera þetta er að nota nodeAffinity á sviði affinity razdela spec. Það eru tveir valkostir:

  • requiredDuringSchedulingIgnoredDuringExecution: hörð stilling (áætlunarmaður mun aðeins dreifa belg á tilteknum hnútum (og hvergi annars staðar));

  • preferredDuringSchedulingIgnoredDuringExecution: mjúk stilling (áætlunarmaðurinn mun reyna að dreifa á tiltekna hnúta og ef það mistekst mun hann reyna að dreifa á næsta tiltæka hnút).

Þú getur tilgreint ákveðna setningafræði til að stjórna hnútamerkjum, til dæmis, In, NotIn, Exists, DoesNotExist, Gt eða Lt. Hins vegar mundu að flóknar aðferðir í löngum lista yfir merki munu hægja á ákvarðanatöku í mikilvægum aðstæðum. Með öðrum orðum, ekki of flækja.

Eins og getið er hér að ofan gerir Kubernetes þér kleift að stilla bindingu núverandi belg. Það er, þú getur látið ákveðna belg vinna saman með öðrum belgjum á sama framboðssvæði (viðeigandi fyrir ský) eða hnúta.

В podAffinity framlegð affinity razdela spec sömu reitir eru í boði og í tilviki nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution и preferredDuringSchedulingIgnoredDuringExecution. Eini munurinn er sá matchExpressions mun binda belg við hnút sem er þegar að keyra belg með því merki.

Meira Kubernetes býður upp á sviði podAntiAffinity, sem aftur á móti bindur ekki belg við hnút með sérstökum belg.

Um tjáningu nodeAffinity sömu ráð er hægt að gefa: reyndu að hafa reglurnar einfaldar og rökréttar, ekki reyna að ofhlaða belgforskriftinni með flóknu setti reglna. Það er mjög auðvelt að búa til reglu sem passar ekki við skilyrði klasans, sem setur aukaálag á tímaáætlunina og rýrir heildarframmistöðu.

7. Blekkir og umburðarlyndi

Það er önnur leið til að stjórna tímaáætluninni. Ef þú ert með stóran þyrping með hundruðum hnúta og þúsundum örþjónustu er mjög erfitt að koma í veg fyrir að ákveðnir hnútar hýsi ákveðna belg.

Fyrirkomulagið á blettum - banna reglur - hjálpar við þetta. Til dæmis geturðu komið í veg fyrir að ákveðnir hnútar keyri belg í ákveðnum tilfellum. Notaðu valkostinn til að beita blett á tiltekinn hnút taint í kubectl. Tilgreindu lykil og gildi og snerti svo NoSchedule eða NoExecute:

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

Það er líka athyglisvert að blettunarbúnaðurinn styður þrjú megináhrif: NoSchedule, NoExecute и PreferNoSchedule.

  • NoSchedule þýðir að þar til samsvarandi færsla er í belgforskriftinni tolerations, ekki er hægt að dreifa því á hnútinn (í þessu dæmi node10).

  • PreferNoSchedule - einfölduð útgáfa NoSchedule. Í þessu tilviki mun tímaáætlunarmaðurinn reyna að úthluta ekki belgjum sem hafa ekki samsvarandi færslu. tolerations á hvern hnút, en þetta eru ekki erfið mörk. Ef það eru engin tilföng í þyrpingunni, þá byrja fræbelgirnir að dreifa á þessum hnút.

  • NoExecute - þessi áhrif koma af stað tafarlausri rýmingu fræbelgja sem hafa ekki samsvarandi færslu tolerations.

Forvitnilegt er að hægt er að afturkalla þessa hegðun með því að nota þolkerfi. Þetta er þægilegt þegar „bannaður“ hnútur er til staðar og þú þarft aðeins að setja innviðaþjónustu á hann. Hvernig á að gera það? Leyfið aðeins þá fræbelg sem hæfilegt þol er fyrir.

Svona myndi pod-forskriftin líta út:

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

Þetta þýðir ekki að við næstu endurdreifingu muni belgurinn ná nákvæmlega þessum hnút, þetta er ekki Node Affinity vélbúnaðurinn og nodeSelector. En með því að sameina nokkra eiginleika geturðu náð mjög sveigjanlegri uppsetningu tímaáætlunar.

8. Stilltu forgang pod dreifingar

Bara vegna þess að þú hefur stillt belg-til-hnút bindingar þýðir það ekki að allir belg ætti að meðhöndla með sama forgang. Til dæmis gætirðu viljað dreifa sumum pods á undan öðrum.

Kubernetes býður upp á mismunandi leiðir til að stilla Pod Priority og Preemption. Stillingin samanstendur af nokkrum hlutum: hlutur PriorityClass og svæðislýsingar priorityClassName í belgforskriftinni. Lítum á dæmi:

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 99999
globalDefault: false
description: "This priority class should be used for very important pods only"

Við sköpum PriorityClass, gefðu því nafn, lýsingu og gildi. Því hærra value, því meiri forgangur. Gildið getur verið hvaða 32-bita heiltala sem er minni en eða jafnt og 1. Hærri gildi eru frátekin fyrir verkefni mikilvæga kerfisbelg sem venjulega er ekki hægt að koma í veg fyrir. Brottreksturinn mun aðeins eiga sér stað ef forgangsbelgurinn hefur hvergi að snúa við, þá verða sumir af belgunum frá tilteknum hnút rýmdir. Ef þetta kerfi er of stíft fyrir þig, þá geturðu bætt við valkostinum preemptionPolicy: Never, og þá verður engin forsala, belgurinn verður fyrstur í röðinni og bíður eftir að tímaáætlunarmaðurinn finni ókeypis úrræði fyrir hann.

Næst búum við til fræbelg þar sem við tilgreinum nafnið 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
          

Þú getur búið til eins marga forgangsflokka og þú vilt, þó mælt sé með því að láta þetta ekki skipta sér af þessu (td takmarkaðu þig við lágan, miðlungs og mikinn forgang).

Þannig, ef nauðsyn krefur, geturðu aukið skilvirkni við að dreifa mikilvægum þjónustu, svo sem nginx-ingress-controller, coredns, osfrv.

9. Fínstilltu ETCD klasann þinn

Níu Kubernetes árangursráð

ETCD má kalla heila alls klasans. Það er mjög mikilvægt að viðhalda rekstri þessa gagnagrunns á háu stigi, þar sem hraði aðgerða í "Cube" fer eftir því. Nokkuð staðlað, og á sama tíma, góð lausn væri að halda ETCD klasa á aðalhnútum til að hafa lágmarks töf á kube-apiserver. Ef þetta er ekki mögulegt, þá skaltu setja ETCD eins nálægt og hægt er, með góðri bandbreidd á milli þátttakenda. Athugaðu einnig hversu margir hnútar frá ETCD geta dottið út án þess að skaða klasann.

Níu Kubernetes árangursráð

Hafðu í huga að óhófleg fjölgun þátttakenda í klasanum getur aukið bilanaþol á kostnað frammistöðu, allt á að vera í hófi.

Ef við tölum um að setja upp þjónustuna, þá eru nokkrar tillögur:

  1. Hafa góðan vélbúnað, byggt á stærð klasans (þú getur lesið hér).

  2. Lagaðu nokkrar breytur ef þú hefur dreift þyrpingu á milli par af DCs eða netkerfisins þíns og diskar skilja eftir mikið að óska ​​(þú getur lesið hér).

Ályktun

Þessi grein lýsir þeim atriðum sem teymið okkar reynir að fara eftir. Þetta er ekki skref-fyrir-skref lýsing á aðgerðum, heldur valkostir sem geta verið gagnlegir til að hámarka yfirkostnað klasa. Það er ljóst að hver klasi er einstakur á sinn hátt og stillingarlausnir geta verið mjög mismunandi, svo það væri áhugavert að fá viðbrögð frá þér: hvernig fylgist þú með Kubernetes klasanum þínum, hvernig bætirðu árangur hans. Deildu reynslu þinni í athugasemdunum, það verður áhugavert að vita það.

Heimild: www.habr.com