
Tere kĂ”igile! Minu nimi on Oleg Sidorenkov ja ma töötan ettevĂ”ttes DomKlik infrastruktuuri meeskonna juhina. Oleme juba ĂŒle kolme aasta kasutanud 'Kuubikut' tootmises ning selle aja jooksul oleme selle kasutamisel kogenud palju erinevaid huvitavaid hetki. TĂ€na rÀÀgin teile, kuidas Ă”ige lĂ€henemise korral saate 'tavalise' Kubernetesest veelgi rohkem jĂ”udlust oma klastrile vĂ€lja pigistada. Valmis, juba!
Te kĂ”ik teate, et Kubernetes on skaleeritav avatud lĂ€htekoodiga sĂŒsteem konteinerite orkestreerimiseks; vĂ”i nagu 5 binaari, mis loovad maagia, hallates teie mikroteenuste elutsĂŒkli serverikeskkonnas. See on ka ĂŒsna paindlik tööriist, mida saab koguda nagu Lego klotsid, et maksimeerida kohandamist erinevate ĂŒlesannete jaoks.
Ja tundub, et kĂ”ik on hĂ€sti: viska serverid klastrisse nagu kĂŒttepuid ahju ja Ă€ra muretse. Kuid kui hoolid keskkonnast, siis mĂ”tle: 'Kuidas ma saan ahjus tuld hoida ja metsa sÀÀsta?'. TeisisĂ”nu, kuidas leida viise infrastruktuuri parandamiseks ja kulude kĂ€rpimiseks.
1. JĂ€lgige meeskondade ja rakenduste ressursse

Ăks kĂ”ige mĂ”istlikumaid, kuid tĂ”husamaid meetodeid on requests/limits'i rakendamine. Jagage rakendusi nimedega ruumidesse ja nimetage ruumid arendusmeeskondade jĂ€rgi. MÀÀrake rakendusele enne juurutamist protsessori aja, mĂ€lu ja ajutise salvestusruumi tarbimise vÀÀrtused.
resources:
requests:
memory: 2Gi
cpu: 250m
limits:
memory: 4Gi
cpu: 500mKogemuste pĂ”hjal oleme jĂ”udnud jĂ€reldusele, et ei tasu ĂŒletada soove piiridele rohkem kui kahekordse erinevusega. Klasteri maht arvutatakse soovide pĂ”hjal ja kui mÀÀrate rakendustele ressursivahe, nĂ€iteks 5â10 korda, siis kujutage ette, mis juhtub teie sĂ”lmega, kui see tĂ€itub podidega ja saab jĂ€rsku koormuse. Mitte midagi head. Minimaalselt throttling, maksimaalselt hĂŒvasti töötajaga ja hakkate saama tsĂŒklilist koormust teistele sĂ”lmedele pĂ€rast seda, kui podid hakkavad liikuma.
Lisaks saab abil limitranges vÔite alguses mÀÀrata konteinerile ressursivÀÀrtused - minimaalsed, maksimaalsed ja vaikevÀÀrtused:
â ~ 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Ărge unustage piirata nimede ruumi ressursse, et ĂŒks meeskond ei saaks kĂ”ik klastrite ressursid endale vĂ”tta:
â ~ 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 0Nagu nÀha on kirjelduse kohaselt resourcequotas, kui ops meeskond soovib vÀlja lasta pod'e, mis tarvitavad veel 10 cpu, siis ajakava ei luba seda teha ja tagastab vea:
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=10Sarnaste probleemide lahendamiseks vÔib kirjutada tööriista, nÀiteks nagu , mis suudab salvestada ja commit'ida meeskonna ressursse.
2. Valige optimaalne failihaldus

Siin sooviksin puudutada pĂŒsivate mahtude ja Kubernetes worker-node diskisĂŒsteemi teemat. Loodan, et keegi ei kasuta âKuberneeteâ HDD-l, kuid vahel ei ole tavaline SSD enam piisav. Oleme avanud probleemi, kus logid tapavad ketast sisend-vĂ€ljund toimingute tĂ”ttu, ja siin pole lahendusi eriti palju:
Kasutage kÔrgtehnoloogilisi SSD-sid vÔi minge NVMe (kui te ise hallate oma riistvara).
VĂ€hendage logimise taset.
Tehke ânutikasâ pod'ide tasakaalustus, mis koormavad ketast (
podAntiAffinity).
Ălemine ekraan nĂ€itab, mis juhtub nginx-ingress-controller'i all, kui access_logs logimine on sisse lĂŒlitatud (~12 tuhat logi/sekundis). Selline olukord vĂ”ib loomulikult viia kĂ”igi selle nodi rakenduste halvenemiseni.
Mis puutub PV-desse, siis kahjuks ei ole ma proovinud kĂ”iki PĂŒsivad mahud. Kasutage parimat varianti, mis teile sobib. Meil on ajalooliselt nii kujunenud, et vĂ€ike osa teenustest vajab RWX-mahuteid ning kaua aega tagasi hakati selle töö jaoks kasutama NFS-mĂ€lukohta. Odav ja⊠piisab. Loomulikult oleme sellega palju jama nĂ€inud â ole terve, kuid oleme Ă”ppinud seda hÀÀlestama ning pea enam ei valuta. Ja kui vĂ”imalik, minge ĂŒle objektihoidlatele S3.
3. Koguge optimeeritud pilte

Parim on kasutada konteineritele optimeeritud pilte, et Kubernetes saaks neid kiiremini hankida ja tĂ”husamalt kĂ€itada.Â
Optimeeritus tÀhendab, et pildid:
sisaldavad ainult ĂŒhte rakendust vĂ”i tĂ€idavad ainult ĂŒhte funktsiooni;
on vÀikese suurusega, sest suured pildid edastatakse vÔrgus halvemini;
omavad lÔpp-punkte töökindluse ja valmiduse kontrollimiseks, mille abil Kubernetes saab ettevÔtta samme hÀirete korral;
kasutavad konteinerisĂ”bralikke operatsioonisĂŒsteeme (nt Alpine vĂ”i CoreOS), mis on konfigureerimisvigade suhtes vastupidavamad;
kasutavad mitmeastmelisi kogumisi, et saaksite juurutada ainult kompileeritud rakendusi, mitte kaasnevaid lÀhtekoode.
On palju tööriistu ja teenuseid, mis vÔimaldavad pilte jooksvalt kontrollida ja optimeerida. Oluline on hoida neid alati ajakohasena ja turvalisuse mÔttes kontrollituna. LÔpuks saate:
VÔrgu koormuse vÀhendamine kogu klastril.
Konteineri kĂ€ivitamise aja lĂŒhendamine.
Teie kogu Docker registry vÀiksem maht.
4. Kasutage DNS-i vahemÀlu

Kui rÀÀkida kĂ”rgest koormusest, siis ilma klastrite DNS-sĂŒsteemi hÀÀlestamiseta on elu ĂŒsna vilets. Kui kunagi ammu toetasid Kubernetes arendajad oma lahendust kube-dns. See rakendus paigaldati ka meile, kuid seda tarkvara ei hÀÀlestatud eriti ja see ei andnud vajalikku jĂ”udlust, kuigi ĂŒlesanne tundus olevat lihtne. Siis ilmus coredns, millele me ĂŒle lĂ€ksime ja muretsesime vĂ€hem, sellest sai ka K8s-i vaikimisi DNS-teenus. Ăhel hetkel jĂ”udsime 40 000 rps DNS-sĂŒsteemi ja sellest lahendusest ei piisanud enam. Aga Ă”nnelikul juhusel ilmus Nodelocaldns, tuntud ka kui node local cache, samuti .
Miks me seda kasutame? Linuxi tuumas on viga, mis mitme korraga NAT-i kaudu UDP-ile juurdepÀÀsemisel viib ĂŒhtlase koondumise tabelisse ja osa NAT-i kaudu liiklusest kaob (iga teenuse kĂŒlastamine on NAT). Nodelocaldns lahendab selle probleemi, eemaldades NAT-i ja vĂ€rskendades ĂŒhendust TCP kaudu kĂ”rgemale DNS-ile, samuti kohaliku vahemĂ€luga DNS-pĂ€ringutele kĂ”rgemate (sealhulgas lĂŒhike 5-sekundiline negatiivne vahemĂ€lu).
5. Skaalake pod'ide horisontaalset ja vertikaalset automaatset skaleerimist

Kas saate kindlalt öelda, et kĂ”ik teie mikroteenused on valmis kahekordseks vĂ”i kolmeks koormuse kasvuks? Kuidas mÀÀrata Ă”igesti oma rakendustele ressursse? Kaks pod'i, mis töötavad ĂŒle koormuse, vĂ”ivad osutuda liigseks, kuid kitsas hoidmine tĂ€hendab, et olete riskis teenusele Ă€kilise suure liikluse tĂ”ttu seisaku saamisega. KuldeesmĂ€rki aitavad saavutada skaleerimist teenuseid, nagu ja .
VPA vĂ”imaldab automaatset tĂ”stmist teie konteinerite requests/limits pod'is vastavalt tegelikule kasutusele. Kuidas see vĂ”ib olla kasulik? Kui teil on pod'e, mida mingil pĂ”hjusel ei saa horisontaalselt skaleerida (mis ei ole eriti usaldusvÀÀrne), siis vĂ”ite proovida usaldada VPA-le oma ressursside muutmist. Selle eripĂ€ra seisneb soovituste sĂŒsteemis, mis pĂ”hineb ajaloolistel ja praegustel andmetel metric-serverist, seega kui te ei soovi automaatselt muuta requests/limits, saate lihtsalt jĂ€lgida soovitatud ressursse oma konteinerite jaoks ja optimeerida seadeid, et sÀÀsta protsessorit ja mĂ€lu klastris.
Pilt on saadud aadressilt https://levelup.gitconnected.com/kubernetes-autoscaling-101-cluster-autoscaler-horizontal-pod-autoscaler-and-vertical-pod-2a441d9ad231
Kubernetes'i planifikaator pĂ”hineb alati requests'il. Olgu see, mis tahes vÀÀrtus, mida te sinna panete, planifikaator otsib sobivat sĂ”lme vastavalt sellele. Limit'i vÀÀrtused on vajalikud kĂŒblile, et mĂ”ista, millal piirata vĂ”i tappa pod. Kuna ainus oluline parameeter on requests'i vÀÀrtus, töötab VPA sellega. Iga kord, kui mÀÀrate oma rakendusele vertikaalse skaleerimise, mÀÀrate, millised peaksid olema requests'id. Aga mis saab siis limit'itest? See parameeter skaleeritakse proportsionaalselt.
NĂ€iteks siin on tavalised pod'i seaded:
ressursid:
taotlused:
mÀlu: 250Mi
cpu: 200m
piirangud:
mÀlu: 500Mi
cpu: 350mSoovitusmehhanism mÀÀrab, et teie rakendusele on vajalik normaalne tööks 300m CPU ja 500Mi. Te saate jÀrgmised seaded:
ressursid:
taotlused:
mÀlu: 500Mi
cpu: 300m
piirangud:
mÀlu: 1000Mi
cpu: 525mNagu eelnevalt mainitud, on see proportsionaalne skaleerimine, mis pÔhineb taotluste/piirangute suhte mansiifis:
CPU: 200m â 300m: suhe 1:1.75;
MĂ€lu: 250Mi â 500Mi: suhe 1:2.
Mis puudutab HPA, siis siin töömehhanism on lĂ€bipaistvam. Seatud on kĂŒnnise vÀÀrtused mÔÔdikute jaoks, nagu nĂ€iteks CPU ja mĂ€lu, ja kui kĂ”ikide replikate keskmine vÀÀrtus ĂŒletab kĂŒnnise, skaleeritakse rakendus +1 podini, kuni vÀÀrtus langeb kĂŒnnisest madalamale vĂ”i kuni maksimaalne replikate arv on saavutatud.
Pilt on saadud aadressilt https://levelup.gitconnected.com/kubernetes-autoscaling-101-cluster-autoscaler-horizontal-pod-autoscaler-and-vertical-pod-2a441d9ad231
Lisaks tavapĂ€rastele mÔÔdikutele, nagu CPU ja mĂ€lu, saate seada kĂŒnniseid oma kohandatud mÔÔdikutele Prometheuses ja töötada nendega, kui arvate, et see on kĂ”ige tĂ€psem mÀÀratlemine, kui tuleb teie rakendust skaleerida. Kui rakendus stabiliseerub mÀÀratud mÔÔdiku alla, hakkab HPA skaleerima pode allapoole minimaalse replikate arvuni vĂ”i kuni olek, mil koormus vastab mÀÀratud kĂŒnnisele.
6. Ărge unustage Node Affinity ja Pod Affinity

KauglĂŒlitused, kus toimub töötlemine, ei tööta kĂ”ik ĂŒhesugustes seadmetes, ja mitte kĂ”ik podid ei pea jooksutama rakendusi, mis nĂ”uavad intensiivseid arvutusi. Kubernetes vĂ”imaldab mÀÀrata node'id ja podid spetsialiseerimisega. Node Affinity ja Pod Affinity.
Kui teil on node'id, mis sobivad intensiivsete arvutuste jaoks, on maksimaalse efektiivsuse tagamiseks parem siduda rakendused vastavatele node'idele. Selleks kasutage nodeSelector sildi mÀÀratluses.
Oletame, et teil on kaks node'i: ĂŒks, millel on CPUType=HIGHFREQ ja palju kiireid tuumasid, teine, millel on MemoryType=HIGHMEMORY palju mĂ€lu ja kĂ”rgem jĂ”udlus. Lihtsaim on mÀÀrata pod'i rakendamine node'ile HIGHFREQ, lisades jaotisesse spec selline valija:
âŠ
nodeSelector:
CPUType: HIGHFREQRohkem kulukas ja spetsiifiline viis seda teha on kasutada nodeAffinity vÀljal affinity jaotises spec. On kaks varianti:
requiredDuringSchedulingIgnoredDuringExecution: rangeerimine (planeerija rakendab pode ainult kindlates node'ides (ja mitte kuskil mujal));preferredDuringSchedulingIgnoredDuringExecution: pehme kohandamine (planifier pĂŒĂŒab juurutada konkreetsetele sĂ”lmedele ning kui see ei Ă”nnestu, siis pĂŒĂŒab ta juurutada jĂ€rgmisele saadaval olevale sĂ”lmele).
Saate mÀÀrata konkreetse sĂ”lme mĂ€rgendusjuhtimise sĂŒntaksit, nĂ€iteks In, NotIn, Exists, DoesNotExist, Gt vĂ”i Lt. Kuid pidage meeles, et keerulised meetodid pikkades mĂ€rgendusloendites aeglustavad kriitilistes olukordades otsuste tegemist. TeisisĂ”nu, Ă€rge keerake seda keeruliseks.
Kuidas mainitud, vÔimaldab Kubernetes mÀÀrata jooksvaid podide sidumisi. See tÀhendab, et saate seadistada teatud podide töötamise koos teiste podidega samas kÀttesaadavuse tsoonis (aktuaalne pilveteenustes) vÔi sÔlmedes.
Uues podAffinity vÀljad affinity jaotises spec on saadaval samad vÀljad nagu nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution ja preferredDuringSchedulingIgnoredDuringExecution. Ainus erinevus on see, et matchExpressions sidub podid sÔlmega, millel juba töötab pod sellise sildiga.
Kubernetes pakub ka vÀlja podAntiAffinity, mis seevastu ei seo podi teatud podidega olevate sÔlmega.
Mis puudutab vĂ€ljendeid, nodeAffinity on sama nĂ”uanne: pĂŒĂŒdke sĂ€ilitada lihtsust ja loogilisust regulaatsioonides, Ă€rge proovige ĂŒle koormata podide spetsiifikatsiooni keeruliste reeglite kogumiga. On vĂ€ga lihtne luua reegel, mis ei vasta klastritingimustele, luues lisakoormust planeerijale ja vĂ€hendades ĂŒldist jĂ”udlust.
7. Taints & Tolerations
On veel ĂŒks viis planeerija juhtimiseks. Kui teil on suur klaster, mis sisaldab sadu sĂ”lmi ja tuhandeid mikroteenuseid, on vĂ€ga keeruline mitte lubada teatud podide asukohaks teatud sĂ”lmed.
Sellele aitab kaasa taintide mehhanism â keeldude reeglid. NĂ€iteks vĂ”ib teatud stsenaariumites keelata teatud sĂ”lmedel oma podide kĂ€itamise. Tainti rakendamiseks konkreetsele sĂ”lmele peate kasutama valikut taint kubectl'is. MÀÀrake vĂ”ti ja vÀÀrtus ning seejĂ€rel taint nagu NoSchedule vĂ”i NoExecute:
$ kubectl taint nodes node10 node-role.kubernetes.io/ingress=true:NoScheduleSamuti on oluline mÀrkida, et taintide mehhanism toetab kolme pÔhiefekti: NoSchedule, NoExecute ja PreferNoSchedule.
NoSchedulesignifitseerib, et kuni podi spesifikatsioonis ei ole vastavat kirjettolerations, ei saa ta olla juurutatud sĂ”lmesse (selles nĂ€itesnode10).PreferNoScheduleâ lihtsustatud versioon.NoScheduleSel juhul pĂŒĂŒab planeerija mitte jaotada podisid, millel pole vastavat kirjettolerationssĂ”lmele, kuid see ei ole range piirang. Kui klastris ei ole ressursse, hakkavad podid sellel sĂ”lmel juurutama.NoExecuteâ see efektiga aktiveerib kohe sadamate evakueerimise, millel pole vastavat kirjettolerations.
Huvitav, et sellist kÀitumist saab tagasi vÔtta tolerantside mehhanismi abil. See on mugav, kui on olemas "keelatud" sÔlm ja teil on vaja paigutada sinna ainult infrastruktuuri teenuseid. Kuidas seda teha? Lubada ainult need sadamad, millel on sobiv tolerants.
Nii nÀeb vÀlja sadama spetsifikatsioon:
spec:
tolerations:
- key: "node-role.kubernetes.io\/ingress"
operator: "Equal"
value: "true"
effect: "NoSchedule"See ei tÀhenda, et jÀrgmise redeploy korral paigutatakse sadam just sellele sÔlmele, see ei ole Node Affinity mehhanism ja nodeSelector. Kuid kombineerides mitmeid funktsioone, vÔite saavutada vÀga painduva planeerija seadistuse.
8. Seadistage sadamate juurutamise prioriteet
See, et olete seadistanud sadamate sidumise sÔlmedega, ei tÀhenda, et kÔik sadamad peaksid olema töötlemisel sama prioriteediga. NÀiteks vÔite soovida juurutada teatud sadamaid varem kui teisi.
Kubernetes pakub erinevaid viise sadamate prioriteetide seadistamiseks (Pod Priority and Preemption). Seadistus koosneb mitmest osast: objektist PriorityClass ja vÀlja kirjeldusega priorityClassName sadama spetsifikatsioonis. Vaatame nÀidet:
apiVersion: scheduling.k8s.io\/v1
kind: PriorityClass
metadata:
name: high-priority
value: 99999
globalDefault: false
description: "See prioriteediklass peaks olema kasutusel ainult vĂ€ga oluliste sadamate jaoks"Loome PriorityClass, anname sellele nime, kirjelduse ja vÀÀrtuse. Mida kĂ”rgem value, seda kĂ”rgem prioriteet. VÀÀrtus vĂ”ib olla ĂŒkskĂ”ik milline 32-bitine tĂ€isarv, mis on vĂ€iksem vĂ”i vĂ”rdne 1 000 000 000. KĂ”rgemad vÀÀrtused on reserveeritud kriitiliselt olulistele sĂŒsteemi sadamatele, mida tavaliselt ei saa eemaldada. Eemaldamine toimub ainult siis, kui kĂ”rge prioriteediga sadamal pole kohta, kuhu juurutada, siis osa sadamatest teatud sĂ”lmel evakueeritakse. Kui see mehhanism on teie jaoks liiga rangetu, vĂ”ite lisada valiku preemptionPolicy: Never, ja siis ei toimu eemaldamisi, sadam ootab esimesena jĂ€rjekorras ja ootab, kuni planeerija leiab talle vabad ressursid.
Edasi loome sadama, kus mÀÀrame nime 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
Saate luua piiramatult prioriteediklasse, kuigi soovitatav on jÀÀda mÔÔdukaks (nÀiteks piirduda madala, keskmise ja kÔrge prioriteediga).
Seega, vajaduse korral suudate tÔsta kriitiliste teenuste, nagu nginx-ingress-controller, coredns jms, tÔhusust.
9. Optimeerige ETCD-klaster

ETCD-d vĂ”ib nimetada kogu klastriteks. On vĂ€ga oluline hoida selle andmebaasi töö kvaliteet kĂ”rge, kuna just temast sĂ”ltub operatsioonide kiirus 'Kubes'. Tavaline ja samas ĂŒsna mĂ”istlik lahendus on hoida ETCD klaster master-node'ides, et minimeerida latentsust kube-apiserverisse. Kui see ei ole vĂ”imalik, siis asetage ETCD vĂ”imalikult lĂ€hedale, tagades hea lĂ€bilaskevĂ”ime osalejate vahel. Samuti jĂ€lgige, kui palju ETCD sĂ”lmi vĂ”ib vĂ€lja kukkuda ilma, et klaster kannataks.

Pidage meeles, et ĂŒleliigne osalejate arvu suurendamine klastris vĂ”ib tĂ”sta jĂ€tkusuutlikkust tootlikkuse arvelt; kĂ”ik peaks olema mÔÔdukas.
Kui rÀÀkida teenuse seadistamisest, siis soovitusi on vÀhe:
Omama head riistvara vastavalt klastrite suurusele (vÔite lugeda ).
Reguleerida mÔningaid parameetreid, kui olete klastrit jaotanud mitme andmekeskuse vahel vÔi teie vÔrk ja kettad jÀtavad soovida (vÔite lugeda ).
KokkuvÔte
Selles artiklis kirjeldatakse punkte, mille jĂ€rgimist meie meeskond pĂŒĂŒab. See ei ole samm-sammuline tegevusjuhend, vaid vĂ”imalused, mis vĂ”ivad olla kasulikud klastrite haldamise kulude optimeerimiseks. Selge on, et iga klaster on omamoodi ainulaadne ja seadistuslahendused vĂ”ivad oluliselt erineda, seega oleks huvitav saada tagasisidet: kuidas te jĂ€lgite oma Kubernetes klastrit, mille abil te selle tööd parandate. Jagage oma kogemusi kommentaarides, oleks huvitav neid kuulda.
Allikas: habr.com
