10 mienskiplike flaters by it brûken fan Kubernetes

Noat. transl.: De skriuwers fan dit artikel binne yngenieurs fan in lyts Tsjechysk bedriuw, pipetail. Se wisten in prachtige list gear te setten fan [soms banale, mar dochs] heul driuwende problemen en misferstannen yn ferbân mei de wurking fan Kubernetes-klusters.

10 mienskiplike flaters by it brûken fan Kubernetes

Yn 'e rin fan' e jierren fan it brûken fan Kubernetes hawwe wy wurke mei in grut oantal klusters (sawol beheard as net beheard - op GCP, AWS en Azure). Nei ferrin fan tiid, wy begûn te merken dat guon flaters waarden hieltyd werhelle. Dêr is lykwols gjin skande yn: wy hawwe de measte sels dien!

It artikel befettet de meast foarkommende flaters en neamt ek hoe't jo se korrigearje.

1. Resources: fersiken en grinzen

Dit item fertsjinnet perfoarst it tichtste oandacht en earste plak op 'e list.

CPU fersyk meastentiids of hielendal net oantsjutte of hat in tige lege wearde (om safolle mooglik pods op elke node te pleatsen). Sa wurde de knooppunten oerladen. Yn tiden fan hege lading wurdt de ferwurkingskrêft fan 'e knooppunt folslein benut en in bepaalde wurkdruk ûntfangt allinich wat it "frege" troch CPU throttling. Dit liedt ta ferhege tapassingslatinsje, time-outs en oare onaangename gefolgen. (Lês mear hjiroer yn ús oare resinte oersetting: "CPU-grinzen en agressive throttling yn Kubernetes"- ca. oerset.)

BestEffort (ekstreem net oanrikkemandearre):

resources: {}

Ekstreem leech CPU-oanfraach (ekstreem net oanrikkemandearre):

   resources:
      Requests:
        cpu: "1m"

Oan 'e oare kant kin de oanwêzigens fan in CPU-limyt liede ta ûnferstannich oerslaan fan kloksyklusen troch pods, sels as de knooppuntprosessor net folslein laden is. Nochris kin dit liede ta ferhege fertragingen. Kontrovers bliuwt om 'e parameter CPU CFS kwota yn de Linux kernel en CPU throttling ôfhinklik fan de ynstelde grinzen, likegoed as it útskeakeljen fan de CFS kwota ... Och, CPU grinzen kinne feroarsaakje mear problemen as se kinne oplosse. Mear ynformaasje oer dit is te finen op de link hjirûnder.

Oermjittige seleksje (oerlêst) ûnthâld problemen kinne liede ta gruttere problemen. It berikken fan 'e CPU-limyt omfettet it oerslaan fan kloksyklusen, wylst it berikken fan' e ûnthâldlimyt it fermoardzjen fan 'e pod meibringt. Hawwe jo ea observearre OOMkill? Ja, dat is krekt wêr't wy it oer hawwe.

Wolle jo de kâns dat dit bart minimalisearje? Net oerallokearje ûnthâld en brûk Guaranteed QoS (Quality of Service) troch it ûnthâldfersyk op 'e limyt te setten (lykas yn it foarbyld hjirûnder). Lês mear oer dit yn Henning Jacobs presintaasjes (Lead Engineer by Zalando).

Burstable (hegere kâns om OOMkilled te wurden):

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

Guarantee:

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

Wat sil mooglik helpe by it ynstellen fan boarnen?

Mei help fan metrics-tsjinner jo kinne it hjoeddeistige CPU-boarneferbrûk en ûnthâldgebrûk sjen troch pods (en konteners dêryn). Meast wierskynlik brûke jo it al. Rin gewoan de folgjende kommando's út:

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

Se litte lykwols allinich aktueel gebrûk sjen. It kin jo in rûch idee jaan fan 'e folchoarder fan grutte, mar úteinlik sille jo nedich wêze skiednis fan feroaringen yn metriken oer de tiid (om fragen te beantwurdzjen lykas: "Wat wie de peak CPU-load?", "Wat wie de lading justermoarn?", ensfh.). Hjirfoar kinne jo brûke Prometheus, DataDog en oare ark. Se krije gewoan metriken fan metrics-server en bewarje se, en de brûker kin se opfreegje en se neffens plotje.

VerticalPodAutoscaler stiet ta automatisearje dit proses. It folget CPU- en ûnthâldgebrûkskiednis en stelt nije oanfragen en grinzen op basearre op dizze ynformaasje.

It effisjint gebrûk fan komputerkrêft is gjin maklike taak. It is as hieltyd Tetris spielje. As jo ​​​​tefolle betelje foar rekkenkrêft mei leech gemiddelde konsumpsje (sizze ~ 10%), riede wy oan om te sjen nei produkten basearre op AWS Fargate of Virtual Kubelet. Se binne boud op in serverless / pay-per-usage billing model, dat kin blike te wêzen goedkeaper yn sokke omstannichheden.

2. Liveness en reewilligens probes

Standert binne kontrôles foar liveness en reewilligens net ynskeakele yn Kubernetes. En soms ferjitte se se oan te setten...

Mar hoe kinne jo oars in tsjinst opnij starte yn gefal fan in fatale flater? En hoe wit de load balancer dat in pod ree is om ferkear te akseptearjen? Of dat it mear ferkear oan kin?

Dizze tests wurde faak betize mei elkoar:

  • Libben - kontrôle "oerlibjen", dy't de pod opnij starte as it mislearret;
  • Readiness - kontrôle fan 'e reewilligens, as it mislearret, skeakelt it de pod los fan' e Kubernetes-tsjinst (dit kin wurde kontrolearre mei kubectl get endpoints) en ferkear komt der net by oant de folgjende kontrôle mei súkses foltôge is.

Beide fan dizze kontrôles OPTREDEN YN DE HELE LIVENSSYKLUS FAN DE POD. It is tige wichtich.

In mienskiplike misfetting is dat reewilligensprobes allinich rinne by it opstarten, sadat de balancer kin witte dat de pod klear is (Ready) en kin begjinne mei it ferwurkjen fan ferkear. Dit is lykwols mar ien fan 'e opsjes foar har gebrûk.

In oar is de mooglikheid om út te finen dat it ferkear op 'e pod is oermjittich en oerladen it (of de pod docht boarne-yntinsive berekkeningen). Yn dit gefal helpt de reewilligenskontrôle ferminderje de lading op 'e pod en "cool" it. Súksesfol foltôgjen fan in reewilligenskontrôle yn 'e takomst makket it mooglik fergrutsje de lading op 'e pod wer. Yn dit gefal (as de reewilligenstest mislearret), soe it mislearjen fan 'e libbenstest tige kontraproduktyf wêze. Wêrom in pod opnij starte dy't sûn is en hurd wurket?

Dêrom, yn guon gefallen, hielendal gjin kontrôles is better dan ynskeakelje se mei ferkeard ynsteld parameters. Lykas sein hjirboppe, as liveness check kopyen readiness check, dan bist yn grutte problemen. Mooglike opsje is om te konfigurearjen allinne reewilligens testen gefaarlik liveness oan 'e kant litte.

Beide soarten kontrôles moatte net mislearje as mienskiplike ôfhinklikens mislearje, oars sil dit liede ta in cascadearjende (lawine-like) mislearring fan alle pods. Mei oare wurden, doch dysels net kwea.

3. LoadBalancer foar eltse HTTP tsjinst

Meast wierskynlik hawwe jo HTTP-tsjinsten yn jo kluster dy't jo wolle trochstjoere nei de bûtenwrâld.

As jo ​​iepenje de tsjinst as type: LoadBalancer, sil syn controller (ôfhinklik fan 'e tsjinstferliener) in eksterne LoadBalancer leverje en ûnderhannelje (net needsaaklikerwize op L7, mar leaver sels op L4), en dit kin de kosten beynfloedzje (ekstern statysk IPv4-adres, kompjûterkrêft, per-sekonde fakturearring ) fanwege de needsaak om in grut tal fan sokke middels te meitsjen.

Yn dit gefal is it folle logysker in gebrûk ien eksterne load balancer, iepening tsjinsten as type: NodePort. Of better noch, útwreidzje wat as nginx-ingress-controller (of traefik), wa sil de ienige wêze NodePort einpunt ferbûn mei de eksterne load balancer en sil rûte ferkear yn it kluster mei help ingress-Kubernetes boarnen.

Oare intra-cluster (mikro) tsjinsten dy't ynteraksje mei elkoar kinne "kommunisearje" mei help fan tsjinsten lykas ClusterIP en in ynboude tsjinst ûntdekkingsmeganisme fia DNS. Brûk gewoan har iepenbiere DNS / IP net, om't dit de latency kin beynfloedzje en de kosten fan wolktsjinsten ferheegje.

4. Autoscaling in kluster sûnder rekken hâldend mei syn funksjes

As jo ​​​​knooppunten tafoegje oan en fuortsmite fan in kluster, moatte jo net fertrouwe op guon basismetriken lykas CPU-gebrûk op dy knopen. Podplanning moat in protte rekken hâlde beheinings, lykas pod/node-affiniteit, tinzen en toleraasjes, boarne-oanfragen, QoS, ensfh. It brûken fan in eksterne autoscaler dy't gjin rekken hâldt mei dizze nuânses kin liede ta problemen.

Stel jo foar dat in bepaalde pod pland wurde moat, mar alle beskikbere CPU-krêft wurdt oanfrege/demonteare en de pod komt fêst yn in steat Pending. Eksterne autoscaler sjocht de gemiddelde hjoeddeistige CPU-lading (net de frege) en begjint gjin útwreiding (útskaal) - foeget gjin oare knooppunt ta. As gefolch sil dizze pod net pland wurde.

Yn dit gefal, reverse skaalfergrutting (skaal yn) - it fuortsmiten fan in knooppunt út in kluster is altyd dreger te ymplementearjen. Stel jo foar dat jo in steatlike pod hawwe (mei oanhâldende opslach ferbûn). Persistente folumes meastentiids hearre ta spesifike beskikberens sône en wurde net replikearre yn 'e regio. Sa, as in eksterne autoscaler wisket in knooppunt mei dizze pod, de scheduler sil net by steat wêze om te plannen dizze pod op in oare node, sûnt dit kin allinnich dien wurde yn de beskikberens sône dêr't de persistente opslach leit. Pod sil fêst yn steat Pending.

Hiel populêr yn 'e Kubernetes-mienskip kluster-autoscaler. It rint op in kluster, stipet API's fan grutte wolkproviders, hâldt rekken mei alle beheiningen en kin yn 'e boppesteande gefallen skaalje. It is ek yn steat om yn te skaaljen, wylst alle ynstelde grinzen behâlden wurde, en dêrmei jild besparje (dat oars soe wurde bestege oan net brûkte kapasiteit).

5. Negearje IAM / RBAC mooglikheden

Pas op foar it brûken fan IAM brûkers mei oanhâldende geheimen foar masines en applikaasjes. Organisearje tydlike tagong mei rollen en tsjinstakkounts (tsjinstakkounts).

Wy komme faak tsjin it feit dat tagongskaaien (en geheimen) hardcoded binne yn 'e applikaasjekonfiguraasje, en ek negearje de rotaasje fan geheimen nettsjinsteande tagong ta Cloud IAM. Brûk IAM-rollen en tsjinstakkounts ynstee fan brûkers wêr passend.

10 mienskiplike flaters by it brûken fan Kubernetes

Ferjit oer kube2iam en gean direkt nei IAM-rollen foar tsjinstakkounts (lykas beskreaun yn notysje mei deselde namme Š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

Ien annotaasje. Net sa dreech, toch?

Jou ek gjin privileezjes foar tsjinstakkounts en eksimplaarprofilen admin и cluster-adminas se it net nedich hawwe. Dit is in bytsje dreger om te fieren, benammen yn RBAC K8s, mar perfoarst de muoite wurdich.

6. Fertrouwe net op automatyske anty-affiniteit foar pods

Stel jo foar dat jo trije replika's hawwe fan wat ynset op in knooppunt. It knooppunt falt, en tegearre mei it alle replika's. Onaangename situaasje, krekt? Mar wêrom wiene alle replika's op deselde knooppunt? Moat Kubernetes net hege beskikberens (HA) leverje?!

Spitigernôch foldocht de Kubernetes-planner op eigen inisjatyf net oan de regels fan apart bestean (anti-affiniteit) foar poddestuollen. Se moatte eksplisyt oanjûn wurde:

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

Da's alles. No sille pods wurde pland op ferskate knooppunten (dizze betingst wurdt allinich kontrolearre tidens skema, mar net tidens har wurking - dêrom requiredDuringSchedulingIgnoredDuringExecution).

Hjir hawwe wy it oer podAntiAffinity op ferskate knooppunten: topologyKey: "kubernetes.io/hostname", - en net oer ferskillende beskikberens sônes. Om in folweardige HA út te fieren, moatte jo djipper yn dit ûnderwerp grave.

7. Negearje PodDisruptionBudgets

Stel jo foar dat jo in produksjebelêsting hawwe op in Kubernetes-kluster. Periodyk moatte knopen en it kluster sels bywurke wurde (of útskeakele). PodDisruptionBudget (PDB) is sa'n ding as in tsjinst garânsje oerienkomst tusken klusterbehearders en brûkers.

PDB lit jo tsjinstûnderbrekkingen foarkomme troch in gebrek oan knopen:

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

Yn dit foarbyld sizze jo, as brûker fan it kluster, tsjin de admins: "Hey, ik haw in bistetúntsjinst, en wat jo ek dogge, ik wol graach op syn minst 2 replika's fan dizze tsjinst altyd beskikber hawwe."

Jo kinne hjir mear oer lêze hjir.

8. Meardere brûkers of omjouwings yn in mienskiplik kluster

Kubernetes nammeromten (nammeromten) jouwe gjin sterke isolaasje.

In mienskiplike misferstân is dat as jo in net-prod-load yn ien nammeromte ynsette en in prod-load yn in oare, dan sil op gjin inkelde manier inoar beynfloedzje... In bepaald nivo fan isolemint kin lykwols berikt wurde mei help fan oanfragen/beheiningen foar boarnen, it ynstellen fan kwota's en it ynstellen fan prioriteitsklassen. Guon "fysike" isolemint yn it gegevensfleantúch wurdt levere troch affiniteiten, toleraasjes, tinzen (as nodeselektors), mar sa'n skieding is frijwat lestich útfiere.

Dejingen dy't beide soarten workloads moatte kombinearje yn itselde kluster sille te krijen hawwe mei kompleksiteit. As der gjin sa'n ferlet, en jo kinne betelje te hawwen ien noch ien kluster (sizze, yn in iepenbiere wolk), dan is it better om dat te dwaan. Dit sil in folle heger nivo fan isolaasje berikke.

9. externalTrafficPolicy: Cluster

Hiel faak observearje wy dat alle ferkear binnen it kluster komt troch in tsjinst lykas NodePort, wêrfoar it standertbelied is ynsteld externalTrafficPolicy: Cluster... It betsjut dat NodePort is iepen op elke knooppunt yn it kluster, en jo kinne elk fan har brûke om te ynteraksje mei de winske tsjinst (set fan pods).

10 mienskiplike flaters by it brûken fan Kubernetes

Tagelyk binne echte pods dy't ferbûn binne mei de hjirboppe neamde NodePort-tsjinst gewoanlik allinich beskikber op in bepaalde subset fan dizze knopen. Mei oare wurden, as ik ferbine mei in knooppunt dat net de fereaske pod hat, sil it ferkear trochstjoere nei in oare knooppunt, it tafoegjen fan in hop en tanimmende latency (as knopen lizze yn ferskate beskikberenssônes / datasintra, kin de latency frij heech wêze; Dêrneist sille útgongsferkearkosten tanimme).

Oan 'e oare kant, as in bepaalde Kubernetes-tsjinst in belied set hat externalTrafficPolicy: Local, dan iepenet NodePort allinich op dy knopen wêr't de fereaske pods eins rinne. By it brûken fan in eksterne load balancer dat kontrolearret de steat (sûnenskontrôle) einpunten (hoe docht it AWS ELB), Hy sil stjoere ferkear allinnich nei de nedige knopen, dat sil hawwe in geunstich effekt op fertraging, computing behoeften, egress rekkens (en sûn ferstân dictates itselde).

D'r is in grutte kâns dat jo al sa'n ding brûke traefik of nginx-ingress-controller as in NodePort-einpunt (of LoadBalancer, dy't ek NodePort brûkt) om HTTP-yngongsferkear te rûte, en it ynstellen fan dizze opsje kin de latency foar sokke fersiken signifikant ferminderje.

В dizze publikaasje Jo kinne mear leare oer externalTrafficPolicy, syn foardielen en neidielen.

10. Net krije bûn oan klusters en net misbrûke de kontrôle fleanmasine

Earder wie it gewoanlik om tsjinners te neamen mei eigennammen: Anton, HAL9000 en Colossus ... Hjoed binne se ferfongen troch willekeurich oanmakke identifiers. De gewoante bleau lykwols, en no geane eigennammen nei klusters.

In typysk ferhaal (basearre op echte foarfallen): it begon allegear mei in proof of concept, sadat it kluster in grutske namme hie testing... Jierren binne foarby en it wurdt NOG brûkt yn produksje, en elkenien is bang om it oan te raken.

D'r is neat leuks oer klusters dy't yn húsdieren wurde, dus wy riede oan om se periodyk te ferwiderjen by it oefenjen ramp herstel (dit sil helpe chaos engineering - ca. oerset.). Derneist soe it gjin sear dwaan om te wurkjen oan 'e kontrôlelaach (kontrôlefleantúch). Bang wêze om him oan te reitsjen is gjin goed teken. ensfh dea? Jonges, jim binne echt yn de problemen!

Oan 'e oare kant moatte jo net meidwaan mei it manipulearjen. Mei tiid de kontrôle laach kin wurden stadich. Meast wierskynlik is dit te tankjen oan in grut oantal objekten dy't makke binne sûnder har rotaasje (in gewoane situaasje by it brûken fan Helm mei standertynstellingen, dat is de reden wêrom't syn tastân yn configmaps/geheimen net bywurke wurdt - as gefolch sammelje tûzenen objekten yn de kontrôle laach) of mei konstante bewurkjen fan kube-api objekten (foar automatyske skaalfergrutting, foar CI / CD, foar tafersjoch, evenemint logs, controllers, ensfh).

Derneist riede wy oan om de SLA / SLO-ôfspraken te kontrolearjen mei de behearde Kubernetes-provider en omtinken te jaan oan de garânsjes. De ferkeaper kin garandearje control laach beskikberens (of syn subkomponinten), mar net de p99-fertraging fan oanfragen dy't jo dernei stjoere. Mei oare wurden, kinne jo ynfiere kubectl get nodes, en ûntfange in antwurd pas nei 10 minuten, en dit sil gjin ynbreuk op de betingsten fan de tsjinst oerienkomst.

11. Bonus: mei help fan de lêste tag

Mar dit is al in klassiker. De lêste tiid hawwe wy dizze technyk minder faak tsjinkaam, om't in protte, nei't se leard hawwe fan bittere ûnderfining, ophâlden mei it brûken fan it tag :latest en begûn pinning ferzjes. Hoera!

ECR behâldt ûnferoarlikens fan ôfbyldingstags; Wy riede oan dat jo josels fertroud meitsje mei dizze opmerklike funksje.

Gearfetting

Ferwachtsje net dat alles oernacht wurket: Kubernetes is gjin panacee. Slechte app sil dizze manier bliuwe, sels yn Kubernetes (en it sil wierskynlik slimmer wurde). Foarsichtigens sil liede ta oermjittige kompleksiteit, stadich en stressfolle wurk fan 'e kontrôlelaach. Derneist riskearje jo dat jo sûnder in strategy foar rampherstel efterlitten wurde. Ferwachtsje net dat Kubernetes isolaasje en hege beskikberens bûten it fak sil leverje. Besteegje wat tiid om jo applikaasje wirklik cloud native te meitsjen.

Jo kinne yn 'e kunde komme mei de mislearre ûnderfiningen fan ferskate teams yn dizze samling ferhalen by Henning Jacobs.

Wa't taheakje wolle oan 'e list mei flaters jûn yn dit artikel, kinne kontakt mei ús opnimme op Twitter (@MarekBartik, @MstrsObserver).

PS fan oersetter

Lês ek op ús blog:

Boarne: www.habr.com

Add a comment