10 dažniausiai pasitaikančių klaidų naudojant „Kubernetes“.

Pastaba. vert.: Šio straipsnio autoriai yra inžinieriai iš nedidelės Čekijos įmonės pipetail. Jiems pavyko sudaryti nuostabų sąrašą [kartais banalių, bet vis tiek] labai aktualių problemų ir klaidingų nuomonių, susijusių su Kubernetes klasterių veikla.

10 dažniausiai pasitaikančių klaidų naudojant „Kubernetes“.

Per daugelį „Kubernetes“ naudojimo metų dirbome su daugybe grupių (tiek valdomų, tiek nevaldomų – ​​GCP, AWS ir Azure). Laikui bėgant pradėjome pastebėti, kad kai kurios klaidos nuolat kartojasi. Tačiau dėl to nėra gėdos: daugumą jų padarėme patys!

Straipsnyje pateikiamos dažniausiai pasitaikančios klaidos ir nurodoma, kaip jas ištaisyti.

1. Ištekliai: užklausos ir limitai

Šis daiktas tikrai nusipelno didžiausio dėmesio ir pirmosios sąrašo vietos.

CPU užklausa paprastai arba visai nenurodyta, arba turi labai mažą reikšmę (kad ant kiekvieno mazgo būtų kuo daugiau ankščių). Taigi mazgai yra perkrauti. Didelės apkrovos metu mazgo apdorojimo galia yra visiškai išnaudojama ir konkretus darbo krūvis gauna tik tai, ko „prašė“ CPU droselis. Tai padidina taikymo delsą, laiką ir kitas nemalonias pasekmes. (Daugiau apie tai skaitykite kitame mūsų naujausiame vertime: „CPU apribojimai ir agresyvus Kubernetes droselis“ – apytiksliai. vertimas.)

BestEffort (itin ne Rekomenduojamas):

resources: {}

Itin žema procesoriaus užklausa (labai ne Rekomenduojamas):

   resources:
      Requests:
        cpu: "1m"

Kita vertus, procesoriaus apribojimas gali lemti nepagrįstą laikrodžio ciklų praleidimą, net jei mazgo procesorius nėra visiškai įkeltas. Vėlgi, tai gali padidinti vėlavimą. Ginčai dėl parametro tęsiasi CPU CFS kvota Linux branduolyje ir procesoriaus droselis, priklausomai nuo nustatytų limitų, taip pat CFS kvotos išjungimas... Deja, procesoriaus limitai gali sukelti daugiau problemų nei gali išspręsti. Daugiau informacijos apie tai galite rasti žemiau esančioje nuorodoje.

Per didelis pasirinkimas (per didelis įsipareigojimas) atminties sutrikimai gali sukelti didesnių problemų. Pasiekus procesoriaus ribą, reikia praleisti laikrodžio ciklus, o pasiekus atminties ribą, reikia užmušti podėlį. Ar kada nors pastebėjote OOMkill? Taip, kaip tik apie tai ir kalbame.

Ar norite sumažinti tikimybę, kad taip nutiks? Neperskirkite atminties ir naudokite garantuotą QoS (paslaugų kokybę), nustatydami atminties užklausos ribą (kaip toliau pateiktame pavyzdyje). Daugiau apie tai skaitykite Henning Jacobs pristatymai (Zalando vadovaujantis inžinierius).

Plyštantis (didesnė tikimybė būti nužudytam OOM):

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

Garantija:

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

Kas gali padėti nustatant išteklius?

naudojant metrika-serveris galite matyti dabartinį procesoriaus išteklių suvartojimą ir atminties naudojimą pagal blokus (ir juose esančius konteinerius). Labiausiai tikėtina, kad jūs jau naudojate jį. Tiesiog paleiskite šias komandas:

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

Tačiau jie rodo tik dabartinį naudojimą. Tai gali suteikti jums apytikslį supratimą apie dydį, bet galiausiai jums to prireiks metrikos pokyčių istorija laikui bėgant (atsakyti į tokius klausimus kaip: „Kokia buvo didžiausia procesoriaus apkrova?“, „Kokia apkrova vakar ryte?“ ir t. t.). Tam galite naudoti Prometėjas, DataDog ir kiti įrankiai. Jie paprasčiausiai gauna metrikas iš metrikų serverio ir juos išsaugo, o vartotojas gali pateikti užklausą ir atitinkamai jas nubraižyti.

VerticalPodAutoscaler leidžia automatizuoti šis procesas. Jis seka procesoriaus ir atminties naudojimo istoriją ir pagal šią informaciją nustato naujas užklausas bei apribojimus.

Efektyviai naudoti skaičiavimo galią nėra lengva užduotis. Tai tarsi visą laiką žaisti „Tetris“. Jei mokate per daug už skaičiavimo galią su mažu vidutiniu suvartojimu (tarkim, ~10%), rekomenduojame pažvelgti į produktus, pagrįstus AWS Fargate arba Virtual Kubelet. Jie sukurti pagal atsiskaitymo be serverio / mokėjimo už naudojimą modelį, kuris tokiomis sąlygomis gali pasirodyti pigesnis.

2. Gyvumo ir parengties zondai

Pagal numatytuosius nustatymus „Kubernetes“ aktyvumo ir parengties patikros neįjungtos. O kartais pamiršta juos įjungti...

Bet kaip kitaip galite inicijuoti paslaugos paleidimą iš naujo įvykus mirtinai klaidai? Ir kaip apkrovos balansuotojas žino, kad podas yra pasirengęs priimti srautą? Arba gali valdyti didesnį srautą?

Šie testai dažnai painiojami vienas su kitu:

  • Gyvenimas — „išgyvenamumo“ patikra, kuri iš naujo paleidžia bloką, jei nepavyksta;
  • Pasirengimas — parengties patikrinimas, jei nepavyksta, jis atjungia podą nuo Kubernetes paslaugos (tai galima patikrinti naudojant kubectl get endpoints) ir eismas į jį neatvyksta, kol nebus sėkmingai atliktas kitas patikrinimas.

Abu šie patikrinimai ATLIKTA PER VISĄ ANKLĖS GYVŪNIMO CIKLU. Tai labai svarbu.

Paplitusi klaidinga nuomonė, kad parengties zondai paleidžiami tik paleidžiant, kad balansavimo priemonė žinotų, kad podas yra paruoštas (Ready) ir gali pradėti apdoroti srautą. Tačiau tai tik viena iš jų naudojimo galimybių.

Kitas yra galimybė sužinoti, kad srautas ant pod yra per didelis ir jį perkrauna (arba podas atlieka daug išteklių reikalaujančius skaičiavimus). Tokiu atveju padeda pasirengimo patikrinimas sumažinti ankšties apkrovą ir „atvėsti“.. Sėkmingas pasirengimo patikrinimas ateityje leidžia vėl padidinkite ankšties apkrovą. Tokiu atveju (jei pasirengimo testas nepavyksta), gyvumo testo nesėkmė būtų labai priešinga. Kam iš naujo paleisti sveiką ir sunkiai dirbančią ankštį?

Todėl kai kuriais atvejais geriau nevykdyti patikrinimų, nei įjungti juos su neteisingai sukonfigūruotais parametrais. Kaip minėta aukščiau, jei gyvumo patikros kopijos parengties patikra, tada jūs turite didelių problemų. Galimas variantas yra konfigūruoti tik pasirengimo testasIr pavojingas gyvumas palikite nuošalyje.

Abiejų tipų patikros neturėtų žlugti, kai nepavyksta įprastų priklausomybių, kitaip tai sukels pakopinį (panašų į laviną) visų grupių gedimą. Kitaip tariant, nekenki sau.

3. LoadBalancer kiekvienai HTTP paslaugai

Greičiausiai jūsų klasteryje yra HTTP paslaugų, kurias norėtumėte persiųsti išoriniam pasauliui.

Jei atidarysite paslaugą kaip type: LoadBalancer, jo valdiklis (priklausomai nuo paslaugos teikėjo) pateiks ir derės dėl išorinio „LoadBalancer“ (nebūtinai veikiančio L7, o veikiau net L4), ir tai gali turėti įtakos sąnaudoms (išorinis statinis IPv4 adresas, skaičiavimo galia, atsiskaitymas už sekundę). ) dėl būtinybės sukurti daug tokių išteklių.

Šiuo atveju daug logiškiau naudoti vieną išorinį apkrovos balansavimo įrenginį, atidarymo paslaugas kaip type: NodePort. Arba dar geriau, išplėsti kažką panašaus nginx-ingress-controller (Arba traefik), kuris bus vienintelis „NodePort“ galinis taškas, susietas su išoriniu apkrovos balansavimo įrenginiu, ir nukreips srautą į klasterį naudojant patekimas-Kubernetes ištekliai.

Kitos klasterio (mikro) paslaugos, kurios sąveikauja viena su kita, gali „bendrauti“ naudodamos tokias paslaugas kaip „ClusterIP“ ir įtaisytas paslaugų aptikimo mechanizmas per DNS. Tiesiog nenaudokite jų viešojo DNS / IP, nes tai gali turėti įtakos delsai ir padidinti debesies paslaugų kainą.

4. Automatinis klasterio mastelio keitimas neatsižvelgiant į jo ypatybes

Pridėdami mazgus prie klasterio ir pašalindami juos iš jų, neturėtumėte pasikliauti kai kuriomis pagrindinėmis metrikomis, pvz., procesoriaus naudojimu tuose mazguose. Planuojant ankštį reikia atsižvelgti į daugelį apribojimai, pvz., pod/mazgo giminingumas, nešvarumai ir tolerancijos, išteklių užklausos, QoS ir kt. Naudojant išorinį automatinį skalavimą, kuris neatsižvelgia į šiuos niuansus, gali kilti problemų.

Įsivaizduokite, kad tam tikras modulis turėtų būti suplanuotas, bet reikalaujama/išardoma visa turima procesoriaus galia ir įstringa būsenoje Pending. Išorinis automatinis skaleris mato vidutinę esamą procesoriaus apkrovą (ne reikalaujamą) ir nepradeda plėtimo (padidinti) - neprideda kito mazgo. Dėl to šis podas nebus suplanuotas.

Šiuo atveju atvirkštinis mastelio keitimas (padidintas) — pašalinti mazgą iš klasterio visada yra sunkiau įgyvendinti. Įsivaizduokite, kad turite būseną turintį bloką (su prijungta nuolatine saugykla). Nuolatiniai tomai paprastai priklauso speciali prieinamumo zona ir regione nėra atkartojami. Taigi, jei išorinis automatinis mastelio įrankis ištrina mazgą su šiuo bloku, planuoklis negalės suplanuoti šio bloko kitame mazge, nes tai galima padaryti tik pasiekiamumo zonoje, kurioje yra nuolatinė saugykla. Ankštis bus įstrigusi būsenoje Pending.

Labai populiarus Kubernetes bendruomenėje klasteris-automatinis skaleris. Jis veikia klasteryje, palaiko pagrindinių debesų paslaugų teikėjų API, atsižvelgia į visus apribojimus ir gali būti padidintas aukščiau nurodytais atvejais. Jis taip pat gali būti padidintas išlaikant visas nustatytas ribas ir taip sutaupant pinigų (kurie kitu atveju būtų išleisti nepanaudotiems pajėgumams).

5. IAM/RBAC galimybių nepaisymas

Saugokitės IAM naudotojų, turinčių nuolatines paslaptis mašinos ir programos. Tvarkykite laikiną prieigą naudodami vaidmenis ir paslaugų paskyras (paslaugų sąskaitos).

Dažnai susiduriame su tuo, kad prieigos raktai (ir paslaptys) yra užkoduoti programos konfigūracijoje, taip pat nepaisome paslapčių pasukimo, nepaisant to, kad turime prieigą prie debesies IAM. Jei reikia, naudokite IAM vaidmenis ir paslaugų paskyras, o ne naudotojus.

10 dažniausiai pasitaikančių klaidų naudojant „Kubernetes“.

Pamirškite apie kube2iam ir eikite tiesiai į paslaugų paskyrų IAM vaidmenis (kaip aprašyta to paties pavadinimo užrašas Š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

Viena anotacija. Ne taip sunku, tiesa?

Be to, nesuteikite paslaugų paskyroms ir egzempliorių profilių privilegijų admin и cluster-adminjei jiems to nereikia. Tai šiek tiek sunkiau įgyvendinti, ypač RBAC K8, bet tikrai verta pastangų.

6. Nepasikliaukite automatiniu anti-afinitetu ankštims

Įsivaizduokite, kad mazge turite tris tam tikro diegimo kopijas. Nukrenta mazgas, o kartu su juo ir visos kopijos. Nemaloni situacija, tiesa? Bet kodėl visos kopijos buvo tame pačiame mazge? Ar ne „Kubernetes“ turėtų užtikrinti aukštą prieinamumą (HA)?!

Deja, Kubernetes planuotojas savo iniciatyva nesilaiko atskiro egzistavimo taisyklių (prieš giminystę) ankštims. Jie turi būti aiškiai nurodyti:

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

Tai viskas. Dabar ankštys bus suplanuotos skirtinguose mazguose (ši sąlyga tikrinama tik planuojant, bet ne jų veikimo metu – taigi requiredDuringSchedulingIgnoredDuringExecution).

Čia mes kalbame apie podAntiAffinity skirtinguose mazguose: topologyKey: "kubernetes.io/hostname", - o ne apie skirtingas prieinamumo zonas. Norėdami įgyvendinti visavertį HA, turėsite įsigilinti į šią temą.

7. PodDisruptionBudgets ignoravimas

Įsivaizduokite, kad turite gamybos apkrovą Kubernetes klasteryje. Periodiškai mazgai ir pats klasteris turi būti atnaujinami (arba nutraukiami). PodDisruptionBudget (PDB) yra kažkas panašaus į paslaugų garantijos sutartį tarp klasterio administratorių ir vartotojų.

PBP leidžia išvengti paslaugų pertrūkių dėl mazgų trūkumo:

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

Šiame pavyzdyje jūs, kaip klasterio vartotojas, pareiškiate administratoriams: „Ei, aš turiu zoologijos sodo prižiūrėtojo paslaugą ir, kad ir ką darytumėte, norėčiau, kad bent 2 šios paslaugos kopijos būtų visada pasiekiamos. .

Daugiau apie tai galite paskaityti čia.

8. Keli vartotojai arba aplinkos bendrame klasteryje

„Kubernetes“ vardų erdvės (vardų erdvės) nesuteikia stiprios izoliacijos.

Paplitusi klaidinga nuomonė, kad jei į vieną vardų sritį įvedate ne gaminių apkrovą, o kitoje - gaminimo apkrovą, tada vienas kitam nedarys jokios įtakos... Tačiau tam tikrą izoliacijos lygį galima pasiekti naudojant išteklių užklausas / apribojimus, nustatant kvotas ir nustatant prioritetines klases. Tam tikrą „fizinę“ izoliaciją duomenų plokštumoje užtikrina giminingumas, tolerancijos, nešvarumai (arba mazgų parinkikliai), tačiau toks atskyrimas yra gana sunku įgyvendinti.

Tie, kuriems reikia derinti abiejų tipų darbo krūvius tame pačiame klasteryje, turės susidoroti su sudėtingumu. Jei tokio poreikio nėra, ir galite sau leisti tokį turėti dar vienas klasteris (tarkime, viešame debesyje), tada geriau tai padaryti. Taip bus pasiektas daug aukštesnis izoliacijos lygis.

9. išorinė eismo politika: klasteris

Labai dažnai matome, kad visas srautas klasterio viduje ateina per tokią paslaugą kaip „NodePort“, kuriai nustatyta numatytoji politika externalTrafficPolicy: Cluster... Tai reiškia kad „NodePort“ yra atidarytas kiekviename klasterio mazge, ir jūs galite naudoti bet kurį iš jų, kad galėtumėte sąveikauti su norima paslauga (padėčių rinkiniu).

10 dažniausiai pasitaikančių klaidų naudojant „Kubernetes“.

Tuo pačiu metu tikrosios grupės, susijusios su aukščiau minėta „NodePort“ paslauga, paprastai pasiekiamos tik tam tikruose įrenginiuose šių mazgų pogrupis. Kitaip tariant, jei prisijungsiu prie mazgo, kuriame nėra reikiamo bloko, jis perduos srautą į kitą mazgą, pridedant apynį ir didėjanti delsa (jei mazgai yra skirtingose ​​pasiekiamumo zonose / duomenų centruose, delsa gali būti gana didelė; be to, padidės išėjimo srauto išlaidos).

Kita vertus, jei tam tikra Kubernetes paslauga turi politiką externalTrafficPolicy: Local, tada „NodePort“ atsidaro tik tuose mazguose, kuriuose iš tikrųjų veikia reikalingi blokai. Naudojant išorinį apkrovos balansavimo įrenginį, kuris tikrina būseną (sveikatos patikrinimas) galutiniai taškai (kaip tai veikia AWS ELB), Jis srautą siųs tik į reikiamus mazgus, o tai turės teigiamos įtakos vėlavimui, skaičiavimo poreikiams, išėjimo sąskaitoms (ir sveikas protas diktuoja tą patį).

Didelė tikimybė, kad jau naudojate kažką panašaus traefik arba nginx-ingress-controller kaip NodePort galutinį tašką (arba „LoadBalancer“, kuris taip pat naudoja „NodePort“) HTTP įėjimo srautui nukreipti, o šios parinkties nustatymas gali žymiai sumažinti tokių užklausų delsą.

В šį leidinį Galite sužinoti daugiau apie išorinę eismo politiką, jos pranašumus ir trūkumus.

10. Neprisiriškite prie klasterių ir nepiktnaudžiaukite valdymo plokštuma

Anksčiau serverius buvo įprasta vadinti tinkamais vardais: Antonas, HAL9000 ir Colossus... Šiandien juos pakeitė atsitiktinai sugeneruoti identifikatoriai. Tačiau įprotis išliko, o dabar tikriniai vardai pereina į grupes.

Tipiška istorija (pagrįsta tikrais įvykiais): viskas prasidėjo nuo koncepcijos įrodymo, todėl klasteris turėjo išdidų pavadinimą bandymai... Prabėgo metai ir VIS DABAR naudojamas gamyboje, ir visi bijo liesti.

Nėra nieko įdomaus, kai klasteriai virsta naminiais gyvūnais, todėl rekomenduojame juos periodiškai pašalinti atliekant pratimus. atkūrimas nelaimės atveju (tai padės chaoso inžinerija - apytiksliai vertimas.). Be to, nepakenktų dirbti su valdymo sluoksniu (valdymo plokštuma). Bijoti jį liesti nėra geras ženklas. ir kt miręs? Vaikinai, jūs tikrai bėdoje!

Kita vertus, jūs neturėtumėte tuo manipuliuoti. Su laiku valdymo sluoksnis gali tapti lėtas. Greičiausiai taip yra dėl to, kad daug objektų sukuriama be jų pasukimo (dažna situacija naudojant Helm su numatytaisiais nustatymais, todėl jo būsena konfigūracijos žemėlapiuose/paslaptyse neatnaujinama – dėl to kaupiasi tūkstančiai objektų valdymo sluoksnis) arba nuolat redaguojant kube-api objektus (automatiniam mastelio keitimui, CI/CD, stebėjimui, įvykių žurnalams, valdikliams ir kt.).

Be to, rekomenduojame patikrinti SLA/SLO sutartis su valdomu Kubernetes tiekėju ir atkreipti dėmesį į garantijas. Pardavėjas gali garantuoti kontroliuoti sluoksnio prieinamumą (ar jo sudedamąsias dalis), bet ne jam siunčiamų užklausų p99 delsą. Kitaip tariant, galite įvesti kubectl get nodes, o atsakymą gauti tik po 10 minučių, ir tai nebus paslaugų sutarties sąlygų pažeidimas.

11. Premija: naujausios žymos naudojimas

Bet tai jau klasika. Pastaruoju metu su šia technika susiduriame rečiau, nes daugelis, pasimokę iš karčios patirties, nustojo naudoti žymą :latest ir pradėjo prisegti versijas. Sveika!

P palaiko vaizdo žymų nekintamumą; Rekomenduojame susipažinti su šia nuostabia savybe.

Santrauka

Nesitikėkite, kad viskas veiks per naktį: „Kubernetes“ nėra panacėja. Bloga programa toks išliks net Kubernetes (ir tikriausiai bus dar blogiau). Neatsargumas sukels per didelį sudėtingumą, lėtą ir įtemptą valdymo sluoksnio darbą. Be to, rizikuojate likti be atkūrimo strategijos po nelaimės. Nesitikėkite, kad „Kubernetes“ užtikrins izoliaciją ir aukštą pasiekiamumą. Praleiskite šiek tiek laiko, kad jūsų programa tikrai būtų natūrali.

Galite susipažinti su nesėkminga įvairių komandų patirtimi šis pasakojimų rinkinys pateikė Henningas Jacobsas.

Tie, kurie nori papildyti šiame straipsnyje pateiktą klaidų sąrašą, gali susisiekti su mumis Twitter (@MarekBartik, @MstrsObserver).

PS iš vertėjo

Taip pat skaitykite mūsų tinklaraštyje:

Šaltinis: www.habr.com

Добавить комментарий