10 levinumat viga Kubernetese kasutamisel

Märge. tõlge: Selle artikli autorid on väikese Tšehhi ettevõtte pipetail insenerid. Neil õnnestus kokku panna imeline nimekiri [mõnikord banaalsetest, kuid siiski] väga aktuaalsetest probleemidest ja eksiarvamustest, mis on seotud Kubernetese klastrite toimimisega.

10 levinumat viga Kubernetese kasutamisel

Kubernetese kasutamise aastate jooksul oleme töötanud suure hulga klastritega (nii hallatud kui ka haldamata – GCP, AWS ja Azure'is). Aja jooksul hakkasime märkama, et mõned vead kordusid pidevalt. Selles pole aga häbi: enamiku oleme ise teinud!

Artikkel sisaldab levinumaid vigu ja mainib ka nende parandamist.

1. Ressursid: taotlused ja piirangud

See ese väärib kindlasti kõige suuremat tähelepanu ja esikohta nimekirjas.

CPU taotlus tavaliselt kas pole üldse täpsustatud või on väga väikese väärtusega (et igale sõlmele võimalikult palju kaunasid asetada). Seega on sõlmed ülekoormatud. Suure koormuse ajal kasutatakse sõlme töötlemisvõimsust täielikult ära ja konkreetne töökoormus saab ainult seda, mida ta "nõuab" CPU drossel. See suurendab rakenduse latentsust, aegumist ja muid ebameeldivaid tagajärgi. (Lugege selle kohta lisateavet meie teisest hiljutisest tõlkest: "Protsessori piirangud ja agressiivne piiramine Kubernetesis"- ca. tõlge.)

BestEffort (äärmiselt ei soovitatav):

resources: {}

Äärmiselt madal protsessori taotlus (äärmiselt ei soovitatav):

   resources:
      Requests:
        cpu: "1m"

Teisest küljest võib protsessori piirangu olemasolu põhjustada kellatsüklite ebamõistlikku vahelejätmist kaustade poolt, isegi kui sõlmeprotsessor pole täielikult laetud. Jällegi võib see põhjustada viivitusi. Vaidlused parameetri ümber jätkuvad CPU CFS kvoot Linuxi kerneli ja CPU drosselimine olenevalt seatud piirangutest, samuti CFS-kvoodi keelamine... Paraku võivad protsessori piirangud tekitada rohkem probleeme kui lahendada. Lisateavet selle kohta leiate allolevalt lingilt.

Liigne valik (üle pühendumine) mäluprobleemid võivad põhjustada suuremaid probleeme. Protsessori limiidi saavutamine tähendab kellatsüklite vahelejätmist, mälulimiidi saavutamine aga seadme tapmist. Kas olete kunagi täheldanud OOMkill? Jah, see on täpselt see, millest me räägime.

Kas soovite selle juhtumise tõenäosust minimeerida? Ärge eraldage mälu üle ja kasutage garanteeritud QoS-i (teenuse kvaliteet), määrates mälupäringu limiidile (nagu allolevas näites). Lisateavet selle kohta leiate artiklist Henning Jacobsi ettekanded (Zalando juhtivinsener).

Pursutav (suurem võimalus OOM-tappe saada):

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

Tagatud:

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

Mis võib ressursside seadistamisel aidata?

Koos mõõdikud-server näete praegust protsessori ressursitarbimist ja mälukasutust kaustade (ja nende sees olevate konteinerite) kaupa. Tõenäoliselt kasutate seda juba. Lihtsalt käivitage järgmised käsud:

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

Kuid need näitavad ainult praegust kasutust. See võib anda teile ligikaudse ettekujutuse suurusjärgust, kuid lõpuks vajate mõõdikute muutuste ajalugu aja jooksul (vastamaks küsimustele nagu: "Milline oli CPU tippkoormus?", "Milline oli eile hommikul koormus?" jne). Selleks saate kasutada Prometheus, DataDog ja muud tööriistad. Nad lihtsalt võtavad mõõdikud metrics-serverist ja salvestavad need ning kasutaja saab neid päringuid teha ja vastavalt joonistada.

VerticalPodAutoscaler võimaldab automatiseerida seda protsessi. See jälgib protsessori- ja mälukasutuse ajalugu ning seab selle teabe põhjal uued päringud ja piirangud.

Arvutusvõimsuse tõhus kasutamine ei ole lihtne ülesanne. See on nagu kogu aeg Tetris mängimine. Kui maksate väikese keskmise tarbimisega (näiteks ~10%) arvutusvõimsuse eest liiga palju, soovitame vaadata AWS Fargate'il või Virtual Kubeletil põhinevaid tooteid. Need on üles ehitatud serverita/kasutuspõhisele arveldusmudelile, mis võib sellistes tingimustes odavamaks osutuda.

2. Elavduse ja valmisoleku sondid

Vaikimisi pole Kubernetesis elavuse ja valmisoleku kontrollimine lubatud. Ja mõnikord unustavad nad need sisse lülitada...

Aga kuidas muidu saate saatusliku vea korral teenuse taaskäivitamist käivitada? Ja kuidas koormuse tasakaalustaja teab, et pod on valmis liiklust vastu võtma? Või et see suudab suurema liiklusega hakkama?

Neid teste aetakse sageli omavahel segamini:

  • Elavus — „ellujäämise” kontroll, mis ebaõnnestumise korral taaskäivitab podi;
  • Valmisolek — valmisoleku kontroll, kui see ebaõnnestub, ühendab see podi Kubernetese teenusest lahti (seda saab kontrollida kasutades kubectl get endpoints) ja liiklus ei jõua sinna enne, kui järgmine kontroll on edukalt lõpule viidud.

Mõlemad kontrollid TEHTUD KOGU PODI ELUTSEKLI AJAL. See on väga tähtis.

Levinud eksiarvamus on, et valmisolekusonde käivitatakse ainult käivitamisel, et tasakaalustaja saaks teada, et pod on valmis (Ready) ja saab alustada liikluse töötlemist. See on aga vaid üks nende kasutamise võimalustest.

Teine on võimalus välja selgitada, et liiklus on podil liigne ja koormab seda üle (või pod teeb ressursimahukaid arvutusi). Sel juhul aitab valmisoleku kontroll vähendage kauna koormust ja "jahutage" seda. Valmisolekukontrolli edukas läbimine tulevikus võimaldab suurendage kauna koormust uuesti. Sel juhul (kui valmisoleku test ebaõnnestub) oleks elujõulisuse testi ebaõnnestumine väga kahjulik. Miks taaskäivitada terve ja kõvasti töötav pod?

Seetõttu on mõnel juhul kontrollimata jätmine parem kui nende lubamine valesti konfigureeritud parameetritega. Nagu eespool öeldud, kui elavuse kontroll koopiad valmisoleku kontroll, siis olete suures hädas. Võimalik variant on konfigureerimine ainult valmisoleku testJa ohtlik elu kõrvale jätta.

Mõlemat tüüpi kontrollid ei tohiks ebaõnnestuda, kui tavalised sõltuvused ebaõnnestuvad, vastasel juhul põhjustab see kõigi kaustade kaskaadse (laviinilaadse) rikke. Teisisõnu, ära tee endale haiget.

3. LoadBalancer iga HTTP-teenuse jaoks

Tõenäoliselt on teie klastris HTTP-teenused, mida soovite välismaailmale edastada.

Kui avate teenuse kui type: LoadBalancer, pakub selle kontroller (olenevalt teenusepakkujast) ja peab läbirääkimisi välise LoadBalanceri üle (mis ei tööta tingimata L7-l, vaid pigem isegi L4-l) ning see võib mõjutada kulusid (väline staatiline IPv4-aadress, arvutusvõimsus, sekundipõhine arveldus). ), kuna on vaja luua suur hulk selliseid ressursse.

Sel juhul on palju loogilisem kasutada ühte välist koormuse tasakaalustajat, avades teenused kui type: NodePort. Või veel parem, laiendage midagi sarnast nginx-ingress-kontroller (Või traefik), kes jääb ainsaks Sõlme port välise koormuse tasakaalustajaga seotud lõpp-punkt ja suunab liikluse klastrisse kasutades sissepääs-Kubernetese ressursid.

Teised klastrisisesed (mikro)teenused, mis omavahel suhtlevad, saavad suhelda, kasutades selliseid teenuseid nagu KlastriIP ja sisseehitatud teenuse avastamise mehhanism DNS-i kaudu. Lihtsalt ärge kasutage nende avalikku DNS-i/IP-d, kuna see võib mõjutada latentsust ja suurendada pilveteenuste maksumust.

4. Klastri automaatne skaleerimine ilma selle funktsioone arvesse võtmata

Klastris sõlmede lisamisel ja sealt eemaldamisel ei tohiks te tugineda mõnele põhimõõdikule, nagu nende sõlmede protsessori kasutus. Kaunade planeerimisel tuleb arvestada paljudega piirangud, nagu kausta/sõlme afiinsus, kahjustused ja taluvused, ressursipäringud, QoS jne. Välise automaatskaalari kasutamine, mis ei võta neid nüansse arvesse, võib põhjustada probleeme.

Kujutage ette, et teatud pod tuleks ajastada, kuid kogu saadaolev protsessori võimsus küsitakse/lahti võetakse ja pod jääb olekusse kinni Pending. Väline automaatskaalaja näeb keskmist praegust protsessori koormust (mitte nõutavat) ega algata laiendamist (suurendada) - ei lisa teist sõlme. Selle tulemusel seda podi ei planeerita.

Sel juhul vastupidine skaleerimine (suurendamine) — sõlme eemaldamine klastrist on alati keerulisem. Kujutage ette, et teil on olekupõhine pod (millega on ühendatud püsisalvestus). Püsivad mahud tavaliselt kuuluvad konkreetne saadavuse tsoon ja neid selles piirkonnas ei korrata. Seega, kui väline automaatne skaleerija kustutab selle podiga sõlme, ei saa planeerija seda podi teise sõlme ajastada, kuna seda saab teha ainult saadavuse tsoonis, kus asub püsimälu. Kaun jääb olekusse kinni Pending.

Väga populaarne Kubernetese kogukonnas klastri-automaatne skaleerija. See töötab klastris, toetab suuremate pilveteenuse pakkujate API-sid, võtab arvesse kõiki piiranguid ja võib ülalnimetatud juhtudel skaleerida. Samuti on see võimeline laienema, säilitades samal ajal kõik seatud piirangud, säästes seeläbi raha (mis muidu kuluks kasutamata võimsusele).

5. IAM/RBAC võimaluste eiramine

Hoiduge kasutamast püsivate saladustega IAM-i kasutajaid masinad ja rakendused. Korraldage ajutist juurdepääsu rollide ja teenusekontode abil (teenuste kontod).

Sageli puutume kokku tõsiasjaga, et juurdepääsuvõtmed (ja saladused) on rakenduse konfiguratsioonis kõvasti kodeeritud, samuti jäetakse tähelepanuta saladuste pööramine, hoolimata juurdepääsust Cloud IAM-ile. Kasutage vajaduse korral kasutajate asemel IAM-rolle ja teenusekontosid.

10 levinumat viga Kubernetese kasutamisel

Unustage kube2iam ja minge otse teenusekontode IAM-i rollide juurde (nagu on kirjeldatud jaotises samanimeline märkus Š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

Üks annotatsioon. Pole nii raske, eks?

Samuti ärge andke teenusekontodele ja eksemplariprofiilidele õigusi admin и cluster-adminkui nad seda ei vaja. Seda on veidi keerulisem rakendada, eriti RBAC K8s, kuid kindlasti tasub seda vaeva näha.

6. Ärge lootke kaunade automaatsele afiinsusele

Kujutage ette, et teil on sõlmes mõne juurutuse kolm koopiat. Sõlm langeb ja koos sellega kõik koopiad. Ebameeldiv olukord, eks? Aga miks olid kõik koopiad samas sõlmes? Kas Kubernetes ei peaks pakkuma kõrget kättesaadavust (HA)?!

Kahjuks ei vasta Kubernetese ajakava omal algatusel eraldi eksisteerimise reeglitele (afiinsuse vastane) kaunade jaoks. Need tuleb selgelt välja tuua:

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

See on kõik. Nüüd ajastatakse kaustad erinevatele sõlmedele (seda tingimust kontrollitakse ainult ajastamise ajal, kuid mitte nende töötamise ajal - seega requiredDuringSchedulingIgnoredDuringExecution).

Siin me räägime podAntiAffinity erinevatel sõlmedel: topologyKey: "kubernetes.io/hostname", - ja mitte erinevate saadavustsoonide kohta. Täieliku HA rakendamiseks peate sellesse teemasse süvenema.

7. PodDisruptionBudgetsi ignoreerimine

Kujutage ette, et teil on Kubernetese klastri tootmiskoormus. Sõlme ja klastrit tuleb perioodiliselt värskendada (või kasutusest kõrvaldada). PodDisruptionBudget (PDB) on umbes nagu teenusegarantii leping klastri administraatorite ja kasutajate vahel.

PDB võimaldab teil vältida sõlmede puudumisest tingitud teenusekatkestusi:

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

Selles näites ütlete klastri kasutajana administraatoritele: "Tere, mul on loomaaiahoidja teenus ja olenemata sellest, mida te teete, sooviksin, et vähemalt kaks selle teenuse koopiat oleks alati saadaval."

Selle kohta saate rohkem lugeda siin.

8. Mitu kasutajat või keskkonda ühises klastris

Kubernetese nimeruumid (nimeruumid) ei taga tugevat isolatsiooni.

Levinud eksiarvamus on, et kui juurutada mittetoodetav koormus ühte nimeruumi ja tootekoormus teise, siis ei mõjuta üksteist kuidagi... Teatud isolatsioonitaseme saab aga saavutada ressursitaotluste/piirangute, kvootide määramise ja priorityClasses seadmise abil. Teatavat "füüsilist" isolatsiooni andmetasandil pakuvad afiinsused, tolerantsid, kahjustused (või sõlmevalijad), kuid selline eraldatus on üsna raske rakendama.

Need, kes peavad kombineerima mõlemat tüüpi töökoormust samas klastris, peavad tegelema keerukusega. Kui sellist vajadust pole ja saate seda endale lubada veel üks klaster (ütleme avalikus pilves), siis on parem seda teha. See saavutab palju kõrgema isolatsioonitaseme.

9. externalTrafficPolicy: klaster

Väga sageli näeme, et kogu klastrisisene liiklus tuleb läbi sellise teenuse nagu NodePort, mille jaoks on määratud vaikepoliitika externalTrafficPolicy: Cluster... See tähendab et Sõlme port on avatud igas klastri sõlmes ja saate kasutada mis tahes neist soovitud teenusega suhtlemiseks (poodide komplekt).

10 levinumat viga Kubernetese kasutamisel

Samal ajal on ülalmainitud NodePort-teenusega seotud tõelised taskud tavaliselt saadaval ainult teatud seadmetel nende sõlmede alamhulk. Teisisõnu, kui ma ühendan sõlme, millel pole vajalikku pod, suunab see liikluse teisele sõlmele, humala lisamine ja latentsusaja suurendamine (kui sõlmed asuvad erinevates kättesaadavustsoonides/andmekeskustes, võib latentsusaeg olla üsna suur; lisaks suurenevad väljumisliikluse kulud).

Teisest küljest, kui teatud Kubernetese teenusele on seatud poliitika externalTrafficPolicy: Local, siis avaneb NodePort ainult nendes sõlmedes, kus vajalikud kaustad tegelikult töötavad. Välise koormuse tasakaalustaja kasutamisel, mis kontrollib olekut (tervisekontroll) lõpp-punktid (kuidas see toimib AWS ELB), Ta saadab liiklust ainult vajalikesse sõlmedesse, millel on kasulik mõju viivitustele, arvutusvajadustele, väljapääsuarvetele (ja terve mõistus dikteerib sama).

On suur tõenäosus, et kasutate juba midagi sarnast traefik või nginx-ingress-kontroller NodePorti lõpp-punktina (või LoadBalancerina, mis kasutab ka NodePorti) HTTP-sisendliikluse suunamiseks ja selle valiku seadistamine võib selliste päringute latentsusaega märkimisväärselt vähendada.

В see väljaanne Saate lisateavet välise liikluspoliitika, selle eeliste ja puuduste kohta.

10. Ära seo end klastritega ja ära kuritarvita juhtimistasandit

Varem oli tavaks kutsuda servereid õigete nimedega: Anton, HAL9000 ja Colossus... Tänapäeval on need asendatud juhuslikult genereeritud identifikaatoritega. Siiski jäi harjumus alles ja nüüd lähevad pärisnimed klastritesse.

Tüüpiline lugu (tõelistel sündmustel põhinev): kõik sai alguse kontseptsiooni tõestamisest, nii et klastril oli uhke nimi testimine… Aastad on möödunud ja seda kasutatakse IKKA tootmises ning kõik kardavad seda puudutada.

Kobaratest lemmikloomadeks muutumises pole midagi lõbusat, seega soovitame need harjutamise ajal aeg-ajalt eemaldada. katastroofiabi (see aitab kaosetehnika - u. tõlge.). Lisaks ei teeks haiget ka kontrollkihi kallal töötamine (juhttasand). Karda teda puudutada ei ole hea märk. jne surnud? Poisid, te olete tõesti hädas!

Teisest küljest ei tohiks te sellega manipuleerimisest end ära lasta. Ajaga kontrollkiht võib muutuda aeglaseks. Tõenäoliselt on selle põhjuseks suur hulk objekte, mis luuakse ilma nende pööramiseta (tavaline olukord Helmi kasutamisel vaikesätetega, mistõttu selle olekut konfiguratsioonikaartides/saladustes ei värskendata – selle tulemusena koguneb tuhandeid objekte juhtkiht) või kube-api objektide pideva redigeerimisega (automaatseks skaleerimiseks, CI/CD jaoks, monitooringuks, sündmuste logideks, kontrolleriteks jne).

Lisaks soovitame kontrollida SLA/SLO lepinguid hallatava Kubernetese pakkujaga ning pöörata tähelepanu garantiidele. Müüja võib garanteerida kontrolli kihi saadavust (või selle alamkomponendid), kuid mitte sellele saadetavate päringute p99 viivitus. Teisisõnu võite siseneda kubectl get nodes, ja saate vastuse alles 10 minuti pärast ning see ei ole teenuselepingu tingimuste rikkumine.

11. Boonus: uusima sildi kasutamine

Aga see on juba klassika. Viimasel ajal oleme selle tehnikaga harvemini kokku puutunud, kuna paljud on kibedast kogemusest õppust võttes märgi kasutamise lõpetanud :latest ja hakkas versioone kinnitama. Hurraa!

ECR säilitab pildimärgendite muutumatuse; Soovitame teil selle tähelepanuväärse funktsiooniga tutvuda.

Kokkuvõte

Ärge oodake, et kõik toimiks üleöö: Kubernetes pole imerohi. Halb rakendus jääb selliseks isegi Kubernetes (ja ilmselt läheb hullemaks). Ettevaatamatus põhjustab kontrollkihi liigset keerukust, aeglast ja pingelist tööd. Lisaks võite jääda ilma avariitaastestrateegiata. Ärge oodake, et Kubernetes pakuks isolatsiooni ja kõrget kättesaadavust. Kulutage aega, et muuta oma rakendus tõeliselt pilvepõhiseks.

Saate tutvuda erinevate meeskondade ebaõnnestunud kogemustega see lugude kogumik autor Henning Jacobs.

Need, kes soovivad käesolevas artiklis toodud vigade loendit täiendada, saavad meiega Twitteris ühendust võtta (@MarekBartik, @MstrsObserver).

PS tõlkijalt

Loe ka meie blogist:

Allikas: www.habr.com

Lisa kommentaar