Viis viga esmakordse rakenduse kasutusele vÔtmisel Kubernetesis

Viis viga esmakordse rakenduse kasutusele vÔtmisel KubernetesisAris-Dreamer'i ebaÔnnestumine

Paljud arvavad, et piisab rakenduse migreerimisest Kubernetesesse (kas siis Helm'i abil vĂ”i kĂ€sitsi) — ja kĂ”ik on hĂ€sti. Aga asi ei ole nii lihtne.

Meeskond Mail.ru Cloud Solutions TÔlkis DevOps-inseneri Julian Gindi artikkel. Ta rÀÀgib, milliste takistustega tema ettevÔte migratsiooni kÀigus silmitsi seisis, et te ei langeks samadesse lÔksudesse.

Esimene samm: podi pÀringute ja piirangute seadistamine

Alustame puhta keskkonna seadistamisest, kus meie podid töötavad. Kubernetes tegeleb podide planeerimise ja tĂ”rgete töötlemisega suurepĂ€raselt. Kuid selgus, et mĂ”nikord ei suuda planeerija podi paigutada, kui tal on keeruline hinnata, kui palju ressursse on vajalik eduka toimimise jaoks. Just siinkohal ilmnevad ressursipĂ€ringute ja piirangute seadistamise kĂŒsimused. Selle ĂŒle kĂ€ib palju arutelusid parima lĂ€henemisviisi osas, aeg-ajalt tundub, et see on pigem kunst kui teadus. See on meie lĂ€henemine.

Podide pÀringud on peamine vÀÀrtus, mida planeerija kasutab podi optimaalse paigutuse mÀÀramiseks.

Uusimad Kubernetes'i dokumentatsioonis: filtreerimise etapis mÀÀratakse node'ite komplekt, kus saab plaanida pod'i. NÀiteks filtril PodFitsResources kontrollitakse, kas node'il on piisavalt ressursse, et rahuldada konkreetse pod'i ressursinÔudmisi.

Rakenduste nÔudmisi kasutame selliselt, et neid saaks hinnata, kui palju ressursse tÔepoolest rakendus vajab normaalseks tööks. Nii suudab planijate realistlikult paigutada node'id. Alguses soovisime seada nÔudmisi reservides, et garanteerida iga pod'i jaoks piisavalt ressursse, kuid mÀrkisime, et planeerimisaeg suurenes oluliselt ning mÔned pod'id ei olnud kunagi tÀielikult plaanitud, nagu ei oleks nende jaoks ressursinÔudmisi esitatud.

Sellisel juhul „vĂ€ljastas” planeerija sageli pod'e ja ei suutnud neid uuesti planeerida, kuna juhtimisplaadil polnud aimugi, kui palju ressursse rakendus vajab, ja see on planeerimise algoritmi vĂ”tmekomponent.

Pod'i piirangud (pod limits) on selgem piirang pod'i jaoks. See on maksimaalne ressursikulu, mille klaster eraldab konteinerile.

JĂ€lle, alates ametlikus dokumentatsioonis: kui konteineril on mÀÀratud mĂ€lulimiit 4 GiB, siis veebiserver (ja konteineri kĂ€ituskeskkond) sundimisega kasutab seda limiiti. KĂ€ituskeskkond ei luba konteineril kasutada rohkem ressursse, kui see limiit on mÀÀratud. NĂ€iteks kui konteineris olev protsess ĂŒritab kasutada rohkem lubatud mĂ€lu, lĂ”petab sĂŒsteemi tuum selle protsessi „vĂ€lja mĂ€lu” (OOM) veaga.

Konteiner saab alati kasutada rohkem ressursse kui ressursitaotluses mÀÀratud, kuid ei tohi kunagi ĂŒletada mÀÀratud limiiti. Selle vÀÀrtuse Ă”ige seadmine on keeruline, kuid see on vĂ€ga oluline.

Ideaalis soovime, et pod'i ressursinĂ”uded muutuksid protsessi elutsĂŒkli jooksul, segamata teisi sĂŒsteemis töötavaid protsesse – see on piiride seadmise eesmĂ€rk.

Kahjuks ei saa ma anda konkreetseid juhiseid, millised vÀÀrtused seadistada, kuid jÀrgime ise jÀrgmisi reegleid:

  1. Kasuta koormustestimise tööriista, et modelleerida pÔhitaseme liiklust ja jÀlgida pod'i ressursikasutust (mÀlu ja protsessor).
  2. Seame podi pÀringud ja seadistame need juhuslikult madalale tasemele (ressursside piiranguga, mis on umbes 5 korda suurem kui pÀringute tase) ja jÀlgime olukorda. Kui pÀringud on liiga madalal tasemel, ei saa protsess alata, mis tihtipeale pÔhjustab kummalisi Go jooksuaja vigu.

Soovin mÀrkida, et kÔrgemad ressursipiirangud muudavad planeerimise keerulisemaks, kuna pod vajab sihtsÔlme, kus on piisavalt ressursse saadaval.

Kujutage ette olukorda, kus teil on kergekaaluline veebiserver vÀga kÔrgete ressursipiirangutega, nÀiteks 4 GB mÀlu. TÔenÀoliselt tuleb seda protsessi horisontaalselt skaleerida ning iga uus moodul tuleb planeerida sÔlmesse, kus on saadaval vÀhemalt 4 GB mÀlu. Kui sellist sÔlme ei ole, peab klaster lisama uue sÔlme selle podi töötlemiseks, mis vÔib vÔtta aega. Oluline on saavutada minimaalne erinevus ressursipÀringute ja piirangute vahel, et tagada kiire ja sujuv skaleerimine.

Teine samm: Liveness ja Readiness testide seadistamine

See on veel ĂŒks peen teema, mis on sageli arutlusel Kubernetes'i kogukonnas. Oluline on hĂ€sti mĂ”ista elujĂ”udluse (Liveness) ja valmiduse (Readiness) teste, kuna need tagavad tarkvara stabiilse töömehhanismi ja vĂ€hendavad seismise aega. Siiski vĂ”ivad need tĂ”siselt kahjustada rakenduse jĂ”udlust, kui neid ei ole Ă”igesti seadistatud. Allpool on lĂŒhikokkuvĂ”te, mida mĂ”lemad proovid endast kujutavad.

ElujĂ”udlus nĂ€itab, kas konteiner töötab. Kui see ebaĂ”nnestub, tapab kubelet konteineri ja rakendatakse taaskĂ€ivitamise poliitikat. Kui konteineril ei ole elujĂ”udluse proovi, on vaikimisi olekuks edu — nii on öeldud Kubernetes'i dokumentatsioonis.

ElujÔudluse proovid peavad olema odavad, st nad ei tohi tarbida palju ressursse, kuna neid kÀivitakse sageli ja need peavad teavitama Kubernetes'i, et rakendus on kÀivitatud.

Kui seadistate parameetri kÀivitamiseks iga sekundi jÀrel, lisab see 1 pÀringu sekundis, seega pidage meeles, et selle liikluse töötlemiseks on vaja tÀiendavaid ressursse.

Meie ettevÔttes kontrollivad Liveness-testid rakenduse pÔhikomponente, isegi kui andmed (nÀiteks eemalt andmebaasilt vÔi vahemÀlust) ei ole tÀielikult kÀttesaadavad.

Oleme rakendustes seadistanud töökindluse lÔpp-punkti, mis lihtsalt tagastab vastuse koodi 200. See nÀitab, et protsess on kÀivitunud ja suudab töödelda pÀringuid (aga mitte veel liiklust).

Proov Valmidus nÀitab, kas konteiner on valmis pÀringute teenindamiseks. Kui valmiduse proov ebaÔnnestub, eemaldab lÔpp-punktide kontrollija podi IP-aadresse kÔikidega teenustega, mis vastavad podile. Seda on ka dokumentatsioonis kirjeldatud Kubernetes.

Valmiduse proovid tarbivad rohkem ressursse, kuna need peavad jÔudma backend'i viisil, et nÀidata rakenduse valmidust pÀringute vastuvÔtmiseks.

Kogukonnas kĂ€ib palju arutelu selle ĂŒle, kas otse andmebaasi pöörduda. Arvestades kulusid (kontrollimisi tehakse sageli, kuid neid saab reguleerida), oleme otsustanud, et teatud rakenduste jaoks loetakse liikluse teenindamise valmisolekuks, kui on kontrollitud, et andmebaasist tagastatakse kirjed. HĂ€sti lĂ€bi mĂ”eldud valmisoleku proovid tagavad kĂ”rgema kĂ€ttesaadavuse taseme ja kĂ”rvaldatakse seisakud juurutamise ajal.

Kui otsustate andmebaasi pÀringut kasutada rakenduse valmisoleku kontrollimiseks, veenduge, et see oleks vÔimalikult odav. Vaadakem sellist pÀringut:

SELECT small_item FROM table LIMIT 1

Siin on nÀide, kuidas me neid kahte vÀÀrtust Kuberneteses seadistame:

livenessProbe: 
 httpGet:   
   path: /api/liveness    
   port: http 
readinessProbe:  
 httpGet:    
   path: /api/readiness    
   port: http  periodSeconds: 2

VÔib lisada mÔned tÀiendavad konfiguratsiooniparametrid:

  • initialDelaySeconds — kui palju sekundeid möödub konteineri kĂ€ivitamisest kuni proovide kĂ€ivitamiseni.
  • periodSeconds — proovide kĂ€ivitamiste vahelise ootamise intervall.
  • timeoutSeconds — sekundeid, pĂ€rast mida loetakse konteiner defektseks. Tavaline ajapiirang.
  • failureThreshold — testide ebaĂ”nnete arv, enne kui konteiner saadab taaskĂ€ivitamise signaali.
  • successThreshold — edukate proovide arv, enne kui konteiner lĂ€heb valmisoleku staatusesse (pĂ€rast riket, kui konteiner kĂ€ivitatakse vĂ”i taastatakse).

Kolmas samm: konteineri vaikevÔrgupoliitikate seadistamine

Kuberneteses on „lamedat“ vĂ”rgu topoloogiat, vaikimisi suudavad kĂ”ik konteinerid omavahel otse suhelda. MĂ”nel juhul on see ebasoovitav.

VĂ”imalik turvaprobleem seisneb selles, et rĂŒndaja vĂ”ib kasutada ĂŒhte haavatavat rakendust, et suunata liiklust kĂ”ikidesse vĂ”rgu konteineritesse. Nagu paljudes turvavaldkondades, kehtib ka siin vĂ€himate privileegide printsiip. Ideaalis peaksid vĂ”rgu poliitikad selgelt mÀÀrama, millised ĂŒhendused konteinerite vahel on lubatud ja millised mitte.

NĂ€iteks on allpool lihtne poliitika, mis keelab kogu sissetuleva liikluse konkreetse nimede ruumi jaoks:

---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:  
 name: default-deny-ingress
spec:  
 podSelector: {}  
 policyTypes:  
   - Ingress

Selle konfiguratsiooni visualiseerimine:

Viis viga esmakordse rakenduse kasutusele vÔtmisel Kubernetesis
(https://miro.medium.com/max/875/1*-eiVw43azgzYzyN1th7cZg.gif)
Üksikasjalikumalt siit.

Neljas samm: kohandatud kÀitumine hookide ja init-konteineritega

Üks meie peamisi ĂŒlesandeid oli tagada Kuberneteses juurutamiseks katkestusteta arendajatele. See on keeruline, kuna on palju vĂ”imalusi rakenduste sulgemiseks ja nende kasutatud ressursside vabastamiseks.

Eriti raskused tekkisid Nginx. Me mĂ€rkisime, et nendel pod’ide jĂ€rjestikusel juurutamisel katkestati aktiivsed ĂŒhendused enne edukat lĂ”petamist.

PĂ€rast ulatuslikku uurimist internetis selgus, et Kubernetes ei oota, kuni Nginxi ĂŒhendused on ammendunud, enne kui pod’i sulgeb. Pre-stop hook’i abil integreerisime sellise funktsionaalsuse ja pÀÀsesime tĂ€ielikult katkestusest:

lifecycle: 
 preStop:
   exec:
     command: ["/usr/local/bin/nginx-killer.sh"]

Ja siin on nginx-killer.sh:

#!/bin/bash
sleep 3
PID=$(cat /run/nginx.pid)
nginx -s quit
while [ -d /proc/$PID ]; do
   echo "Waiting while shutting down nginx..."
   sleep 10
done

Veel kasulik on kasutada init-konteinereid konkreetsete rakenduste kÀivitamiseks. See on eriti kasulik, kui teil on ressursimahukas andmebaasi migreerimise protsess, mille peate kÀivitama enne rakenduse tÔstmist. Selle protsessi jaoks saate lÀbi viia ka kÔrgema ressursside piiri, ilma et peaksite selle piiri seadma pÔhiraamatule.

Teine levinud skeem on juurdepÀÀs saladustele init-konteineris, mis edastab need mandaadid pÔhikomponendile, vÀltides seelÀbi pÔhikomponendi rakenduse kaudu saladustele volitamata juurdepÀÀsu.

Nagu tavaliselt, tsitaat dokumentatsioonist: init-konteinerid kĂ€ivitavad kasutaja koodi vĂ”i utiliite turvaliselt, mis muidu vĂ€hendaks rakenduse konteineri pildi turvalisust. Hoides eraldi tarbetuid tööriistu, piirate rakenduse konteineri pildi rĂŒnnaku pindala.

Viies samm: tuuma seadistamine

LÔpetuseks rÀÀgime edasijÔudnud tehnikast.

Kubernetes on ÀÀrmiselt paindlik platvorm, mis vĂ”imaldab teil töökoormusi hallata just niimoodi, nagu te soovite. Meil on mitmeid kĂ”rgjĂ”udlusega rakendusi, mis nĂ”uavad vĂ€ga palju ressursse. PĂ”hjalike koormustestide kĂ€igus oleme avastanud, et ĂŒks rakendus vaevab end oodatava liikluse koormusega, kui kehtivad Kubernetes'e vaikeseaded.

Kuid Kubernetes vĂ”imaldab kĂ€ivitada privileegitud konteineri, mis muudab tuumaparameetreid ainult konkreetse pod'i jaoks. Sedasi muutisime avatud ĂŒhenduste maksimumarvu:

initContainers:
  - name: sysctl
     image: alpine:3.10
     securityContext:
         privileged: true
      command: ['sh', '-c', "sysctl -w net.core.somaxconn=32768"]

See on arenenum tehnika, mis ei pruugi alati vajalik olla. Kuid kui teie rakendus vaevleb suure koormuse all, vĂ”ite proovida mĂ”ningaid neist parameetritest seadistada. Üksikasjalikumat teavet selle protsessi ja erinevate vÀÀrtuste seadistamise kohta leiate — nagu alati ametlikust dokumentatsioonist.

KokkuvÔtteks

Kuigi Kubernetes vÔib tunduda kui valmis lahendus "karbist vÀlja", on rakenduste sujuvaks toimimiseks vajalikud mitmed olulised sammud.

Kogu Kubernetesesse migreerimise vĂ€ltel on oluline jĂ€rgida "koormustestimise tsĂŒklit": kĂ€ivitage rakendus, testige seda koormuse all, jĂ€lgige mÔÔdikute ja kĂ€itumise muutusi skaleerimise ajal, seadistage konfiguratsioon vastavalt nendele andmetele ning korrake seda tsĂŒklit.

Hinnake realistlikult oodatavat liiklust ja proovige sellest ĂŒle astuda, et nĂ€ha, millised komponendid purunevad esimesena. Sellise iteratiivse lĂ€henemisviisi puhul vĂ”ivad mĂ”ned nimetatud soovitustest olla piisavad eduks. VĂ”ib-olla on vajalik sĂŒgavam seadistamine.

KĂŒsi endalt alati jĂ€rgmisi kĂŒsimusi:

  1. Kui palju ressursse rakendused kasutavad ja kuidas see maht muutub?
  2. Millised on reaalsed skaleerimisnÔuded? Kui palju liiklust suudab rakendus keskmiselt kÀidelda? Ent kuidas on olukord tipplÀbilaske korral?
  3. Kui tihti vajab teenus horisontaalset skaleerimist? Kui kiiresti tuleb uusi pod'e kÀiku lasta, et liiklust vastu vÔtta?
  4. Kuidas pod'id lĂ”petavad oma töö? Kas see on ĂŒldse vajalik? Kas saab saavutada juurutamist ilma seisakuteta?
  5. Kuidas minimeerida turvariske ja piirata kahju, mis tuleneb mistahes kompromiteeritud pod'idest? Kas mÔni teenus omab Ôigusi vÔi juurdepÀÀse, mis pole vajalikud?

Kubernetes pakub uskumatut platvormi, mis vÔimaldab kasutada parimaid tavasid tuhande teenuse juurutamiseks klastris. Siiski on kÔik rakendused erinevad. MÔnikord vajab juurutamine veidi rohkem tööd.

Õnneks pakub Kubernetes vajalikud seadistused kĂ”igi tehniliste eesmĂ€rkide saavutamiseks. Kasutades ressursside nĂ”udeid ja piire, Liveness ja Readiness probe'e, init-konteinereid, vĂ”rgu poliitikaid ja kohandatud tuuma konfiguratsiooni, on vĂ”imalik saavutada kĂ”rge jĂ”udlus koos talitluskindluse ja kiire skaleeritavusega.

Mida veel lugeda:

  1. Parimad praktikad ja soovitused konteinerite ja Kubernetes'i kÀitamiseks tootmisringkondades..
  2. 90+ kasulikku tööriista Kubernetes'ile: juurutamine, haldamine, jÀlgimine, turvalisus ja mitte ainult.
  3. Meie kanal Kubernetesest Telegramis.

Allikas: habr.com

Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster