10 gabime të zakonshme kur përdorni Kubernetes

Shënim. përkth.: Autorët e këtij artikulli janë inxhinierë nga një kompani e vogël çeke, pipetail. Ata arritën të mbledhin një listë të mrekullueshme të problemeve [ndonjëherë banale, por ende] shumë të ngutshme dhe keqkuptimeve në lidhje me funksionimin e grupimeve Kubernetes.

10 gabime të zakonshme kur përdorni Kubernetes

Gjatë viteve të përdorimit të Kubernetes, ne kemi punuar me një numër të madh grupimesh (të menaxhuara dhe të pamenaxhuara - në GCP, AWS dhe Azure). Me kalimin e kohës, filluam të vëmë re se disa gabime përsëriten vazhdimisht. Sidoqoftë, nuk ka turp në këtë: shumicën e tyre i kemi bërë vetë!

Artikulli përmban gabimet më të zakonshme dhe gjithashtu përmend se si t'i korrigjoni ato.

1. Burimet: kërkesat dhe kufijtë

Ky artikull padyshim meriton vëmendjen më të afërt dhe vendin e parë në listë.

Kërkesa CPU zakonisht ose nuk specifikohet fare ose ka një vlerë shumë të ulët (për të vendosur sa më shumë bishtaja në secilën nyje). Kështu, nyjet mbingarkohen. Gjatë kohës së ngarkesës së lartë, fuqia përpunuese e nyjës përdoret plotësisht dhe një ngarkesë e caktuar merr vetëm atë që "kërkohet" nga Mbyllja e CPU-së. Kjo çon në rritjen e vonesës së aplikimit, ndërprerjet kohore dhe pasoja të tjera të pakëndshme. (Lexo më shumë rreth kësaj në përkthimin tonë të fundit: "Kufijtë e CPU dhe mbytja agresive në Kubernetes" - përafërsisht. përkth.)

Përpjekja më e mirë (jashtëzakonisht jo rekomandohet):

resources: {}

Kërkesë jashtëzakonisht e ulët për CPU (jashtëzakonisht jo rekomandohet):

   resources:
      Requests:
        cpu: "1m"

Nga ana tjetër, prania e një kufiri të CPU-së mund të çojë në kapërcim të paarsyeshëm të cikleve të orës nga pods, edhe nëse procesori i nyjeve nuk është plotësisht i ngarkuar. Përsëri, kjo mund të çojë në rritje të vonesave. Mosmarrëveshjet vazhdojnë rreth parametrit Kuota CPU CFS në frenimin e kernelit Linux dhe CPU-së në varësi të kufijve të caktuar, si dhe çaktivizimin e kuotës CFS... Mjerisht, kufijtë e CPU-së mund të shkaktojnë më shumë probleme sesa mund të zgjidhin. Më shumë informacion rreth kësaj mund të gjeni në linkun e mëposhtëm.

Përzgjedhja e tepërt (përkushtimi i tepërt) problemet e kujtesës mund të çojnë në probleme më të mëdha. Arritja e kufirit të CPU-së përfshin kapërcimin e cikleve të orës, ndërsa arritja e kufirit të memories nënkupton vrasjen e pod. A keni vëzhguar ndonjëherë OOMkill? Po, pikërisht për këtë po flasim.

Dëshironi të minimizoni gjasat që kjo të ndodhë? Mos e mbi-shpërndani memorien dhe përdorni QoS të Garantuar (Cilësia e Shërbimit) duke vendosur kërkesën për memorie në kufi (si në shembullin më poshtë). Lexoni më shumë rreth kësaj në Prezantimet e Henning Jacobs (Inxhinieri kryesor Zalando).

I plasur (shanse më të larta për t'u vrarë OOM):

   resources:
      requests:
        memory: "128Mi"
        cpu: "500m"
      limits:
        memory: "256Mi"
        cpu: 2

Garantuar:

   resources:
      requests:
        memory: "128Mi"
        cpu: 2
      limits:
        memory: "128Mi"
        cpu: 2

Çfarë do të ndihmojë potencialisht gjatë krijimit të burimeve?

Me metrikë-server ju mund të shihni konsumin aktual të burimit të CPU-së dhe përdorimin e memories nga pods (dhe kontejnerët brenda tyre). Me shumë mundësi, ju tashmë jeni duke e përdorur atë. Thjesht ekzekutoni komandat e mëposhtme:

kubectl top pods
kubectl top pods --containers
kubectl top nodes

Megjithatë, ato tregojnë vetëm përdorimin aktual. Mund t'ju japë një ide të përafërt të rendit të madhësisë, por në fund do t'ju duhet historia e ndryshimeve në metrikë me kalimin e kohës (për t'iu përgjigjur pyetjeve të tilla si: "Sa ishte ngarkesa maksimale e CPU?", "Sa ishte ngarkesa dje në mëngjes?", etj.). Për këtë ju mund të përdorni Prometeu, DataDog dhe mjete të tjera. Ata thjesht marrin metrika nga serveri metrics dhe i ruajnë ato, dhe përdoruesi mund t'i kërkojë ato dhe t'i vizatojë ato në përputhje me rrethanat.

VerticalPodAutoscaler Kjo i lejon automatizoj këtë proces. Ai gjurmon historinë e përdorimit të CPU-së dhe kujtesës dhe vendos kërkesa dhe kufizime të reja bazuar në këtë informacion.

Përdorimi efikas i fuqisë kompjuterike nuk është një detyrë e lehtë. Është si të luash Tetris gjatë gjithë kohës. Nëse po paguani shumë për fuqinë llogaritëse me konsum mesatar të ulët (të themi ~10%), ju rekomandojmë të shikoni produktet e bazuara në AWS Fargate ose Virtual Kubelet. Ato janë ndërtuar mbi një model faturimi pa server/pay-per-use, i cili mund të rezultojë të jetë më i lirë në kushte të tilla.

2. Sondat e gjallërisë dhe gatishmërisë

Si parazgjedhje, kontrollet e gjallërisë dhe gatishmërisë nuk janë të aktivizuara në Kubernetes. Dhe ndonjëherë ata harrojnë t'i ndezin ato ...

Por si tjetër mund të filloni një rifillim të shërbimit në rast të një gabimi fatal? Dhe si e di balancuesi i ngarkesës që një pod është gati të pranojë trafikun? Apo se mund të përballojë më shumë trafik?

Këto teste shpesh ngatërrohen me njëra-tjetrën:

  • Gjallëri — Kontrolli i "mbijetueshmërisë", i cili rinis podin nëse dështon;
  • gatishmëri — kontrolli i gatishmërisë, nëse dështon, shkëput podin nga shërbimi Kubernetes (kjo mund të kontrollohet duke përdorur kubectl get endpoints) dhe trafiku nuk arrin tek ai derisa kontrolli tjetër të përfundojë me sukses.

Të dyja këto kontrolle E KRYERUAR GJATË TË GJITHË CIKLIT JETËSOR TË POD. Eshte shume e rendesishme.

Një keqkuptim i zakonshëm është se sondat e gatishmërisë funksionojnë vetëm në fillim, në mënyrë që balancuesi të mund të dijë se pod është gati (Ready) dhe mund të fillojë përpunimin e trafikut. Sidoqoftë, kjo është vetëm një nga opsionet për përdorimin e tyre.

Një tjetër është mundësia për të zbuluar se trafiku në pod është i tepruar dhe e mbingarkon atë (ose pod kryen llogaritje intensive të burimeve). Në këtë rast, kontrolli i gatishmërisë ndihmon zvogëloni ngarkesën në pod dhe "ftohni" atë. Përfundimi me sukses i një kontrolli gatishmërie në të ardhmen lejon rrisni përsëri ngarkesën në pod. Në këtë rast (nëse testi i gatishmërisë dështon), dështimi i testit të gjallërisë do të ishte shumë kundërproduktiv. Pse të rifilloni një pod që është i shëndetshëm dhe që punon shumë?

Prandaj, në disa raste, asnjë kontroll është më i mirë sesa aktivizimi i tyre me parametra të konfiguruar gabimisht. Siç u tha më lart, nëse kontrolli i gjallërisë kopjon kontrollin e gatishmërisë, atëherë jeni në telashe të mëdha. Opsioni i mundshëm është konfigurimi vetëm test gatishmërieDhe gjallëri e rrezikshme lini mënjanë.

Të dy llojet e kontrolleve nuk duhet të dështojnë kur dështojnë varësitë e zakonshme, përndryshe kjo do të çojë në një dështim të kaskadës (si orteku) të të gjitha podeve. Me fjale te tjera, mos e demto veten.

3. LoadBalancer për çdo shërbim HTTP

Me shumë mundësi, ju keni shërbime HTTP në grupin tuaj që dëshironi t'i përcillni në botën e jashtme.

Nëse e hapni shërbimin si type: LoadBalancer, kontrolluesi i tij (në varësi të ofruesit të shërbimit) do të sigurojë dhe do të negociojë një LoadBalancer të jashtëm (jo domosdoshmërisht funksionon në L7, por madje edhe në L4), dhe kjo mund të ndikojë në kosto (adresa e jashtme statike IPv4, fuqia kompjuterike, faturimi për sekondë ) për shkak të nevojës për të krijuar një numër të madh burimesh të tilla.

Në këtë rast, është shumë më logjike të përdoret një balancues i jashtëm i ngarkesës, duke hapur shërbime si type: NodePort. Ose më mirë akoma, zgjeroni diçka të tillë nginx-hyrje-kontrollues (Ose trafik), i cili do të jetë i vetmi Porta e nyjeve Pika përfundimtare e lidhur me balancuesin e jashtëm të ngarkesës dhe do të drejtojë trafikun në grup duke përdorur hyj-Burimet e Kubernetes.

Shërbime të tjera brenda grupit (mikro) që ndërveprojnë me njëri-tjetrin mund të "komunikojnë" duke përdorur shërbime si p.sh. ClusterIP dhe një mekanizëm të integruar të zbulimit të shërbimit nëpërmjet DNS. Thjesht mos përdorni DNS/IP-në e tyre publike, pasi kjo mund të ndikojë në vonesën dhe të rrisë koston e shërbimeve cloud.

4. Përshkallëzimi automatik i një grupi pa marrë parasysh veçoritë e tij

Kur shtoni nyje dhe hiqni ato nga një grup, nuk duhet të mbështeteni në disa metrikë bazë si përdorimi i CPU-së në ato nyje. Planifikimi i pod duhet të marrë parasysh shumë kufizimet, të tilla si afiniteti i pod/nyjeve, njollat ​​dhe tolerimet, kërkesat për burime, QoS, etj. Përdorimi i një shkallëzuesi automatik të jashtëm që nuk i merr parasysh këto nuanca mund të çojë në probleme.

Imagjinoni që një pod i caktuar duhet të planifikohet, por e gjithë fuqia e disponueshme e CPU-së kërkohet/çmontohet dhe pod ngec në një gjendje Pending. Shkallëzuesi automatik i jashtëm shikon ngarkesën mesatare aktuale të CPU-së (jo atë të kërkuar) dhe nuk fillon zgjerimin (shkallëzim) - nuk shton një nyje tjetër. Si rezultat, ky pod nuk do të planifikohet.

Në këtë rast, shkallëzimi i kundërt (në shkallë) — heqja e një nyje nga një grup është gjithmonë më e vështirë për t'u zbatuar. Imagjinoni që keni një pod statusor (me ruajtje të vazhdueshme të lidhur). Vëllime të vazhdueshme zakonisht i përkasin zona specifike e disponueshmërisë dhe nuk përsëriten në rajon. Kështu, nëse një shkallëzues automatik i jashtëm fshin një nyje me këtë pod, planifikuesi nuk do të jetë në gjendje ta planifikojë këtë pod në një nyje tjetër, pasi kjo mund të bëhet vetëm në zonën e disponueshmërisë ku ndodhet ruajtja e vazhdueshme. Bishtaja do të ngecë në gjendje Pending.

Shumë popullor në komunitetin Kubernetes grup-autoshkallëzues. Ai funksionon në një grup, mbështet API-të nga ofruesit kryesorë të cloud, merr parasysh të gjitha kufizimet dhe mund të shkallëzohet në rastet e mësipërme. Ai është gjithashtu në gjendje të shkallëzohet duke ruajtur të gjitha kufijtë e vendosur, duke kursyer kështu para (të cilat përndryshe do të shpenzoheshin në kapacitet të papërdorur).

5. Neglizhimi i aftësive IAM/RBAC

Kujdes nga përdorimi i përdoruesve të IAM me sekrete të vazhdueshme për makinat dhe aplikacionet. Organizoni aksesin e përkohshëm duke përdorur rolet dhe llogaritë e shërbimit (llogaritë e shërbimit).

Shpesh hasim faktin që çelësat e aksesit (dhe sekretet) janë të koduar në konfigurimin e aplikacionit, si dhe neglizhimin e rrotullimit të sekreteve pavarësisht se kemi akses në Cloud IAM. Përdorni rolet dhe llogaritë e shërbimit IAM në vend të përdoruesve kur është e përshtatshme.

10 gabime të zakonshme kur përdorni Kubernetes

Harrojeni kube2iam dhe shkoni direkt te rolet IAM për llogaritë e shërbimit (siç përshkruhet në shënim me të njëjtin emër Štěpán Vraný):

apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-app-role
  name: my-serviceaccount
  namespace: default

Një shënim. Jo aq e vështirë, apo jo?

Gjithashtu, mos u jepni privilegje llogarive të shërbimit dhe profileve të shembullit admin и cluster-adminnëse nuk kanë nevojë për të. Kjo është pak më e vështirë për t'u zbatuar, veçanërisht në RBAC K8, por padyshim ia vlen përpjekja.

6. Mos u mbështetni në anti-afinitetin automatik për bishtajat

Imagjinoni që keni tre kopje të disa vendosjes në një nyje. Nyja bie, dhe së bashku me të të gjitha kopjet. Situatë e pakëndshme, apo jo? Por pse ishin të gjitha kopjet në të njëjtën nyje? A nuk supozohet që Kubernetes të ofrojë disponueshmëri të lartë (HA)?!

Fatkeqësisht, planifikuesi Kubernetes, me iniciativën e tij, nuk përputhet me rregullat e ekzistencës së veçantë (anti-afiniteti) për bishtajat. Ato duhet të shprehen qartë:

// опущено для краткости
      labels:
        app: zk
// опущено для краткости
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: "app"
                    operator: In
                    values:
                    - zk
              topologyKey: "kubernetes.io/hostname"

Kjo eshte e gjitha. Tani podet do të planifikohen në nyje të ndryshme (kjo gjendje kontrollohet vetëm gjatë planifikimit, por jo gjatë funksionimit të tyre - prandaj requiredDuringSchedulingIgnoredDuringExecution).

Këtu po flasim për podAntiAffinity në nyje të ndryshme: topologyKey: "kubernetes.io/hostname", - dhe jo për zona të ndryshme disponueshmërie. Për të zbatuar një HA të plotë, do të duhet të gërmoni më thellë në këtë temë.

7. Injorimi i PodDisruptionBudgets

Imagjinoni që keni një ngarkesë prodhimi në një grupim Kubernetes. Periodikisht, nyjet dhe vetë grupi duhet të përditësohen (ose çaktivizohen). PodDisruptionBudget (PDB) është diçka si një marrëveshje garancie shërbimi midis administratorëve dhe përdoruesve të grupimeve.

PDB ju lejon të shmangni ndërprerjet e shërbimit të shkaktuara nga mungesa e nyjeve:

apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
  name: zk-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: zookeeper

Në këtë shembull, ju, si përdorues i grupit, u deklaroni administratorëve: "Hej, unë kam një shërbim të kujdestarit të kopshtit zoologjik dhe pavarësisht se çfarë bëni ju, unë do të doja të kisha të paktën 2 kopje të këtij shërbimi gjithmonë në dispozicion."

Ju mund të lexoni më shumë për këtë këtu.

8. Përdorues të shumtë ose mjedise në një grup të përbashkët

Hapësirat e emrave të Kubernetes (hapësirat e emrave) nuk ofrojnë izolim të fortë.

Një keqkuptim i zakonshëm është se nëse vendosni një ngarkesë jo-produese në një hapësirë ​​emri dhe një ngarkesë prod në një tjetër, atëherë ata nuk do të ndikojnë në asnjë mënyrë njëri-tjetrin... Megjithatë, një nivel i caktuar izolimi mund të arrihet duke përdorur kërkesat/kufizimet e burimeve, vendosjen e kuotave dhe vendosjen e klasave prioritare. Njëfarë izolimi "fizik" në rrafshin e të dhënave sigurohet nga afinitetet, tolerimet, njollat ​​(ose zgjedhësit e nyjeve), por një ndarje e tillë është mjaft. i vështirë zbatojnë.

Ata që duhet të kombinojnë të dy llojet e ngarkesave të punës në të njëjtin grup do të duhet të përballen me kompleksitetin. Nëse nuk ka nevojë të tillë, dhe ju mund të përballoni ta keni një të tillë një grup më shumë (të themi, në një re publike), atëherë është më mirë ta bëni këtë. Kjo do të arrijë një nivel shumë më të lartë të izolimit.

9. Politika e Trafikut të Jashtëm: Cluster

Shumë shpesh shohim që i gjithë trafiku brenda grupit vjen përmes një shërbimi si NodePort, për të cilin është vendosur politika e paracaktuar externalTrafficPolicy: Cluster... Do të thotë se Porta e nyjeve është i hapur në çdo nyje në grup dhe mund të përdorni cilindo prej tyre për të bashkëvepruar me shërbimin e dëshiruar (bashkësi me pods).

10 gabime të zakonshme kur përdorni Kubernetes

Në të njëjtën kohë, pods reale të lidhura me shërbimin e sipërpërmendur NodePort janë zakonisht të disponueshme vetëm në një të caktuar nëngrupi i këtyre nyjeve. Me fjalë të tjera, nëse lidhem me një nyje që nuk ka podin e kërkuar, ajo do të përcjellë trafikun në një nyje tjetër, duke shtuar një hop dhe vonesë në rritje (nëse nyjet ndodhen në zona/qendra të ndryshme të disponueshmërisë së të dhënave, vonesa mund të jetë mjaft e lartë; përveç kësaj, kostot e trafikut në dalje do të rriten).

Nga ana tjetër, nëse një shërbim i caktuar Kubernetes ka një grup politikash externalTrafficPolicy: Local, atëherë NodePort hapet vetëm në ato nyje ku podet e kërkuara po funksionojnë në të vërtetë. Kur përdorni një balancues të jashtëm të ngarkesës që kontrollon gjendjen (kontrolli i shëndetit) pikat fundore (si funksionon AWS ELB), Ai do të dërgojë trafik vetëm në nyjet e nevojshme, e cila do të ketë një efekt të dobishëm në vonesat, nevojat kompjuterike, faturat e daljes (dhe arsyeja e shëndoshë dikton të njëjtën gjë).

Ka një shans të lartë që ju tashmë jeni duke përdorur diçka të tillë trafik ose nginx-hyrje-kontrollues si një pikë fundore e NodePort (ose LoadBalancer, e cila përdor gjithashtu NodePort) për të drejtuar trafikun hyrës të HTTP, dhe vendosja e këtij opsioni mund të reduktojë ndjeshëm vonesën për kërkesa të tilla.

В këtë botim Mund të mësoni më shumë për Politikën e Trafikut të Jashtëm, avantazhet dhe disavantazhet e saj.

10. Mos u lidhni me grupime dhe mos abuzoni me rrafshin e kontrollit

Më parë, ishte zakon të thirreshin serverët me emrat e duhur: Anton, HAL9000 dhe Colossus... Sot ato janë zëvendësuar nga identifikues të krijuar rastësisht. Sidoqoftë, zakoni mbeti, dhe tani emrat e duhur shkojnë në grupime.

Një histori tipike (bazuar në ngjarje reale): gjithçka filloi me një provë të konceptit, kështu që grupi kishte një emër krenar testimi… Kanë kaluar vite dhe përdoret ende në prodhim, dhe të gjithë kanë frikë ta prekin.

Nuk ka asgjë argëtuese që grupet të kthehen në kafshë shtëpiake, kështu që ju rekomandojmë t'i hiqni ato në mënyrë periodike gjatë praktikës rikuperimi nga fatkeqësitë (kjo do të ndihmojë inxhinieri kaosi - përafërsisht. përkth.). Përveç kësaj, nuk do të dëmtonte të punoni në shtresën e kontrollit (avioni i kontrollit). Të kesh frikë ta prekësh nuk është një shenjë e mirë. etj i vdekur? Djema, ju jeni vërtet në telashe!

Nga ana tjetër, nuk duhet të tërhiqesh duke e manipuluar. Me kohë shtresa e kontrollit mund të bëhet e ngadaltë. Me shumë mundësi, kjo është për shkak të krijimit të një numri të madh objektesh pa rrotullimin e tyre (një situatë e zakonshme kur përdorni Helm me cilësimet e paracaktuara, kjo është arsyeja pse gjendja e tij në konfigurimet/sekretet nuk përditësohet - si rezultat, mijëra objekte grumbullohen në shtresa e kontrollit) ose me redaktim të vazhdueshëm të objekteve kube-api (për shkallëzim automatik, për CI/CD, për monitorim, regjistrat e ngjarjeve, kontrollorët, etj.).

Përveç kësaj, ne rekomandojmë të kontrolloni marrëveshjet SLA/SLO me ofruesin e menaxhuar të Kubernetes dhe t'i kushtoni vëmendje garancive. Shitësi mund të garantojë disponueshmëria e shtresës së kontrollit (ose nënkomponentët e tij), por jo vonesa p99 e kërkesave që i dërgoni. Me fjalë të tjera, ju mund të hyni kubectl get nodes, dhe merrni një përgjigje vetëm pas 10 minutash, dhe kjo nuk do të jetë shkelje e kushteve të marrëveshjes së shërbimit.

11. Bonusi: duke përdorur etiketën më të fundit

Por kjo tashmë është një klasik. Kohët e fundit ne e kemi hasur më rrallë këtë teknikë, pasi shumë, pasi kanë mësuar nga përvoja e hidhur, kanë ndaluar përdorimin e etiketës :latest dhe filloi të pinte versionet. Hora!

ECR ruan pandryshueshmërinë e etiketave të imazhit; Ne ju rekomandojmë që të njiheni me këtë veçori të jashtëzakonshme.

Përmbledhje

Mos prisni që gjithçka të funksionojë brenda natës: Kubernetes nuk është një ilaç. Aplikacion i keq do të mbetet kështu edhe në Kubernetes (dhe ndoshta do të përkeqësohet). Pakujdesia do të çojë në kompleksitet të tepruar, punë të ngadaltë dhe stresuese të shtresës së kontrollit. Për më tepër, rrezikoni të mbeteni pa një strategji të rimëkëmbjes nga fatkeqësitë. Mos prisni që Kubernetes të sigurojë izolim dhe disponueshmëri të lartë jashtë kutisë. Kaloni pak kohë duke e bërë aplikacionin tuaj vërtetë vendas në cloud.

Ju mund të njiheni me përvojat e pasuksesshme të ekipeve të ndryshme në këtë koleksion tregimesh nga Henning Jacobs.

Ata që dëshirojnë të shtojnë në listën e gabimeve të dhëna në këtë artikull mund të na kontaktojnë në Twitter (@MarekBartik, @MstrsObserver).

PS nga përkthyesi

Lexoni edhe në blogun tonë:

Burimi: www.habr.com

Shto një koment