10 Oftaj Eraroj Uzante Kubernetes

Notu. transl.: La aŭtoroj de ĉi tiu artikolo estas inĝenieroj de malgranda ĉeĥa firmao, pipetail. Ili sukcesis kunmeti mirindan liston de [kelkfoje banalaj, sed tamen] tre urĝaj problemoj kaj miskomprenoj rilate al la funkciado de Kubernetes-grupoj.

10 Oftaj Eraroj Uzante Kubernetes

Tra la jaroj de uzado de Kubernetes, ni laboris kun granda nombro da aretoj (kaj administritaj kaj neadministrataj - sur GCP, AWS kaj Azure). Kun la tempo, ni komencis rimarki, ke iuj eraroj konstante ripetiĝis. Tamen ne estas honto pri tio: la plimulton ni mem faris!

La artikolo enhavas la plej oftajn erarojn kaj ankaŭ mencias kiel korekti ilin.

1. Rimedoj: petoj kaj limoj

Ĉi tiu objekto certe meritas la plej proksiman atenton kaj unuan lokon en la listo.

CPU-peto kutime aŭ tute ne specifita aŭ havas tre malaltan valoron (por meti kiel eble plej multajn podojn sur ĉiu nodo). Tiel, la nodoj iĝas troŝarĝitaj. Dum tempoj de alta ŝarĝo, la pretigpotenco de la nodo estas plene utiligita kaj speciala laborkvanto ricevas nur tion, kion ĝi "petis" de CPU-strango. Ĉi tio kondukas al pliigita aplika latenteco, tempoforpasoj kaj aliaj malagrablaj sekvoj. (Legu pli pri tio en nia alia lastatempa traduko: "CPU-limoj kaj agresema estrangilo en Kubernetes"- ĉ. traduk.)

Plej bona penado (ekstreme ne rekomendita):

resources: {}

Ege malalta CPU-peto (ekstreme ne rekomendita):

   resources:
      Requests:
        cpu: "1m"

Aliflanke, la ĉeesto de CPU-limo povas konduki al senracia transsaltado de horloĝcikloj de balgoj, eĉ se la nodprocesoro ne estas plene ŝarĝita. Denove, ĉi tio povas konduki al pliigitaj prokrastoj. Konflikto daŭras ĉirkaŭ la parametro CPU CFS-kvoto en la Linukso-kerno kaj CPU-streĉo depende de la fiksitaj limoj, same kiel malŝalti la CFS-kvoton... Ve, CPU-limoj povas kaŭzi pli da problemoj ol ili povas solvi. Pliaj informoj pri tio troveblas ĉe la suba ligilo.

Troa elekto (superengaĝiĝo) memorproblemoj povas konduki al pli grandaj problemoj. Atingi la CPU-limon implicas transsalti horloĝciklojn, dum atingi la memorlimon implicas mortigi la balgon. Ĉu vi iam observis OOMkill? Jes, ĝuste pri tio ni parolas.

Ĉu vi volas minimumigi la probablecon de tio okazi? Ne troasignu memoron kaj uzu Garantiitan QoS (Kvalito de Servo) metante la memorpeton al la limo (kiel en la ekzemplo sube). Legu pli pri tio en prezentoj de Henning Jacobs (ĈefInĝeniero ĉe Zalando).

Burstable (pli alta ŝanco esti OOMmortigita):

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

Garantiita:

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

Kio eble helpos kiam starigo de rimedoj?

Kun la helpo de metriko-servilo vi povas vidi la nunan CPU-rimedonkonsumon kaj memoruzon per balgoj (kaj ujoj ene de ili). Plej verŝajne, vi jam uzas ĝin. Nur rulu la sekvajn komandojn:

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

Tamen ili nur montras aktualan uzadon. Ĝi povas doni al vi malglatan ideon pri la grandordo, sed finfine vi bezonos historio de ŝanĝoj en metriko laŭlonge de la tempo (por respondi demandojn kiel: "Kio estis la pinta CPU-ŝarĝo?", "Kia estis la ŝarĝo hieraŭ matene?", ktp.). Por tio vi povas uzi Prometeo, DataDog kaj aliaj iloj. Ili simple ricevas metrikojn de metriko-servilo kaj stokas ilin, kaj la uzanto povas pridemandi ilin kaj grafiki ilin laŭe.

VertikalaPodAutoscaler permesas al aŭtomatigi ĉi tiu procezo. Ĝi spuras la historion de uzado de CPU kaj memoro kaj starigas novajn petojn kaj limojn surbaze de ĉi tiu informo.

Uzi komputikpotencon efike ne estas facila tasko. Estas kiel ludi Tetrison la tutan tempon. Se vi pagas tro multe por komputa potenco kun malalta averaĝa konsumo (diru ~10%), ni rekomendas rigardi produktojn bazitajn sur AWS Fargate aŭ Virtuala Kubelet. Ili estas konstruitaj sur senservila/pago laŭ-uzo-faktura modelo, kiu povas rezulti pli malmultekosta en tiaj kondiĉoj.

2. Sondoj pri viveco kaj preteco

Defaŭlte, kontroloj pri viveco kaj preteco ne estas ebligitaj en Kubernetes. Kaj foje ili forgesas ŝalti ilin...

Sed kiel alie vi povas komenci servon rekomencas en kazo de fatala eraro? Kaj kiel la ŝarĝbalancilo scias, ke pod pretas akcepti trafikon? Aŭ ke ĝi povas trakti pli da trafiko?

Ĉi tiuj provoj ofte estas konfuzitaj unu kun la alia:

  • Vivo — "supervivebleco" kontrolo, kiu rekomencas la pod se ĝi malsukcesas;
  • Preteco — preteca kontrolo, se ĝi malsukcesas, ĝi malkonektas la pod de la Kubernetes-servo (ĉi tio povas esti kontrolita per kubectl get endpoints) kaj trafiko ne alvenas al ĝi ĝis la sekva kontrolo estas sukcese finita.

Ambaŭ ĉi tiuj ĉekoj PRENDITAD DUM LA TUTA VIVOCIKO DE LA PODO. Ĝi estas tre grava.

Ofta miskompreniĝo estas, ke pretecaj enketoj funkcias nur ĉe ekfunkciigo tiel ke la ekvilibristo povas scii ke la balgo estas preta (Ready) kaj povas komenci prilabori trafikon. Tamen, ĉi tio estas nur unu el la ebloj por ilia uzo.

Alia estas la ebleco ekscii, ke la trafiko sur la podo estas troa kaj troŝarĝas ĝin (aŭ la balgo faras rimed-intensajn kalkulojn). En ĉi tiu kazo, la preteca kontrolo helpas reduktu la ŝarĝon sur la balgo kaj "malvarigu" ĝin. Sukcesa kompletigo de preteca kontrolo en la estonteco permesas pliigi la ŝarĝon sur la pod denove. En ĉi tiu kazo (se la pretectesto malsukcesas), fiasko de la vivectesto estus tre malutila. Kial rekomenci pod kiu estas sana kaj laboranta?

Tial, en iuj kazoj, neniu kontrolo estas pli bona ol ebligi ilin per malĝuste agorditaj parametroj. Kiel dirite supre, se liveness check kopias readyness check, tiam vi havas grandan problemon. Ebla opcio estas agordi nur preteco-testokaj danĝera viveco lasu flanken.

Ambaŭ specoj de kontroloj ne devus malsukcesi kiam oftaj dependecoj malsukcesas, alie tio kondukos al kaskada (lavango-simila) fiasko de ĉiuj balgoj. Alivorte, ne damaĝu vin mem.

3. LoadBalancer por ĉiu HTTP-servo

Plej verŝajne, vi havas HTTP-servojn en via areto, kiujn vi ŝatus plusendi al la ekstera mondo.

Se vi malfermas la servon kiel type: LoadBalancer, ĝia regilo (depende de la servoprovizanto) provizos kaj negocos eksteran LoadBalancer (ne nepre funkcianta sur L7, sed prefere eĉ sur L4), kaj tio povas influi la koston (ekstera statika IPv4-adreso, komputa potenco, sekunda fakturado). ) pro la bezono krei grandan nombron da tiaj rimedoj.

En ĉi tiu kazo, estas multe pli logike uzi unu eksteran ŝarĝbalancilon, malfermante servojn kiel type: NodePort. Aŭ pli bone ankoraŭ, vastigu ion similan nginx-ingress-controller (aŭ traefik), kiu estos la sola NodePort finpunkto asociita kun la ekstera ŝarĝbalancilo kaj direktos trafikon en la areto uzante eniro-Rimedoj de Kubernetes.

Aliaj intra-grupoj (mikro)servoj kiuj interagas unu kun la alia povas "komuniki" uzante servojn kiel ClusterIP kaj enkonstruita servo-malkovra mekanismo per DNS. Nur ne uzu ilian publikan DNS/IP, ĉar ĉi tio povas influi latencian kaj pliigi la koston de nubaj servoj.

4. Aŭtoskalo de areto sen konsideri ĝiajn trajtojn

Aldonante nodojn kaj forigante ilin de areto, vi ne devus fidi iujn bazajn metrikojn kiel CPU-uzado sur tiuj nodoj. Podplanado devas konsideri multajn restriktoj, kiel balgo/nodo-afineco, makuloj kaj toleremoj, rimedpetoj, QoS, ktp. Uzado de ekstera aŭtoskalilo, kiu ne konsideras ĉi tiujn nuancojn, povas konduki al problemoj.

Imagu, ke certa podulo estu planita, sed la tuta disponebla CPU-potenco estas petita/malmuntita kaj la podo restas blokita en stato Pending. Ekstera aŭtoskalilo vidas la mezan nunan CPU-ŝarĝon (ne la petitan) kaj ne iniciatas vastiĝon (malgrandiĝo) - ne aldonas alian nodon. Kiel rezulto, ĉi tiu pod ne estos planita.

En ĉi tiu kazo, inversa skalo (skalo enen) — forigi nodon el areto estas ĉiam pli malfacile efektivigebla. Imagu, ke vi havas staton pod (kun konstanta stokado konektita). Konstantaj volumoj kutime apartenas al specifa havebleca zono kaj ne estas reproduktitaj en la regiono. Tiel, se ekstera aŭtoskalilo forigas nodon kun ĉi tiu pod, tiam la planisto ne povos plani ĉi tiun pod sur alia nodo, ĉar tio povas esti farita nur en la havebleczono kie la konstanta stokado situas. La balgo estos blokita en la ŝtato Pending.

Tre populara en la komunumo Kubernetes cluster-autoscaler. Ĝi funkcias per areto, subtenas API-ojn de ĉefaj nubaj provizantoj, konsideras ĉiujn limigojn kaj povas grimpi en ĉi-supraj kazoj. Ĝi ankaŭ povas grimpi enen konservante ĉiujn fiksitajn limojn, tiel ŝparante monon (kiu alie estus elspezita por neuzata kapacito).

5. Neglektante IAM/RBAC-kapablojn

Gardu vin uzi IAM-uzantojn kun konstantaj sekretoj por maŝinoj kaj aplikoj. Organizu provizoran aliron uzante rolojn kaj servokontojn (servokontoj).

Ni ofte renkontas la fakton, ke alirŝlosiloj (kaj sekretoj) estas malmola koditaj en la aplika agordo, kaj ankaŭ neglektas la rotacion de sekretoj malgraŭ havi aliron al Cloud IAM. Uzu IAM-rolojn kaj servokontojn anstataŭ uzantojn kie konvene.

10 Oftaj Eraroj Uzante Kubernetes

Forgesu pri kube2iam kaj iru rekte al IAM-roloj por servokontoj (kiel priskribite en noto de la sama nomo Š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

Unu komentario. Ne tiom malfacile, ĉu ne?

Ankaŭ, ne donu privilegiojn pri servokontoj kaj instancprofiloj admin и cluster-adminse ili ne bezonas ĝin. Ĉi tio estas iom pli malfacile efektivigi, precipe en RBAC K8s, sed certe valoras la penon.

6. Ne fidu je aŭtomata kontraŭ-afineco por podoj

Imagu, ke vi havas tri kopiojn de iu deplojo sur nodo. La nodo falas, kaj kune kun ĝi ĉiuj kopioj. Malagrabla situacio, ĉu ne? Sed kial ĉiuj kopioj estis sur la sama nodo? Ĉu Kubernetes ne supozas provizi altan haveblecon (HA)?!

Bedaŭrinde, la planilo de Kubernetes, laŭ sia propra iniciato, ne plenumas la regulojn de aparta ekzisto. (kontraŭ-afineco) por balgoj. Ili devas esti eksplicite deklaritaj:

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

Tio estas ĉio. Nun podoj estos planitaj sur malsamaj nodoj (ĉi tiu kondiĉo estas kontrolita nur dum planado, sed ne dum ilia funkciado - do requiredDuringSchedulingIgnoredDuringExecution).

Ĉi tie ni parolas podAntiAffinity sur malsamaj nodoj: topologyKey: "kubernetes.io/hostname", - kaj ne pri malsamaj haveblecaj zonoj. Por efektivigi plenan HA, vi devos profundigi ĉi tiun temon.

7. Ignorante PodDisruptionBudgets

Imagu, ke vi havas produktadŝarĝon sur Kubernetes-grupo. Periode, nodoj kaj la areto mem devas esti ĝisdatigitaj (aŭ malmenditaj). PodDisruptionBudget (PDB) estas io kiel servo-garantia interkonsento inter cluster-administrantoj kaj uzantoj.

PDB ebligas al vi eviti servointerrompojn kaŭzitajn de manko de nodoj:

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

En ĉi tiu ekzemplo, vi, kiel uzanto de la cluster, deklaras al la administrantoj: "He, mi havas zookeeper-servon, kaj negrave kion vi faras, mi ŝatus ke almenaŭ 2 kopioj de ĉi tiu servo estu disponeblaj ĉiam. .”

Vi povas legi pli pri ĉi tio tie.

8. Multoblaj uzantoj aŭ medioj en komuna areto

Kubernetes nomspacoj (nomspacoj) ne provizas fortan izoladon.

Ofta miskompreniĝo estas ke se vi deplojas ne-produktan ŝarĝon en unu nomspacon kaj prod-ŝarĝon en alian, tiam ili neniel influos unu la alian... Tamen, certa nivelo de izolado povas esti atingita uzante rimedpetojn/limigojn, fiksante kvotojn, kaj fiksante prioritatajn Klasojn. Iu "fizika" izoliteco en la datenaviadilo estas disponigita per afinecoj, toleremoj, makuloj (aŭ nodeselektiloj), sed tia apartigo estas sufiĉe. malfacila efektivigi.

Tiuj, kiuj bezonas kombini ambaŭ specojn de laborŝarĝoj en la sama areto, devos trakti kompleksecon. Se ne ekzistas tia bezono, kaj vi povas pagi havi tian unu plia areto (diru, en publika nubo), tiam estas pli bone fari tion. Ĉi tio atingos multe pli altan nivelon de izolado.

9. eksteraTrafficPolicy: Areto

Tre ofte ni observas, ke la tuta trafiko ene de la grapolo venas per servo kiel NodePort, por kiu la defaŭlta politiko estas agordita. externalTrafficPolicy: Cluster... Ĝi signifas tion NodePort estas malfermita sur ĉiu nodo en la areto, kaj vi povas uzi iun ajn el ili por interagi kun la dezirata servo (aro da balgoj).

10 Oftaj Eraroj Uzante Kubernetes

Samtempe, realaj podoj asociitaj kun la supre menciita NodePort-servo kutime disponeblas nur ĉe certa subaro de ĉi tiuj nodoj. Alivorte, se mi konektas al nodo kiu ne havas la bezonatan pod, ĝi plusendos trafikon al alia nodo, aldonante salteton kaj kreskanta latenteco (se nodoj situas en malsamaj haveblecaj zonoj/datumcentroj, la latenteco povas esti sufiĉe alta; krome, elirtrafikkostoj pliiĝos).

Aliflanke, se certa Kubernetes-servo havas politikan aron externalTrafficPolicy: Local, tiam NodePort malfermiĝas nur sur tiuj nodoj, kie la postulataj podoj efektive funkcias. Kiam vi uzas eksteran ŝarĝbalancilon, kiu kontrolas la staton (sankontrolo) finpunktoj (kiel ĝi fartas AWS ELB), Li sendos trafikon nur al la necesaj nodoj, kiu havos utilan efikon al prokrastoj, komputadbezonoj, elirfakturoj (kaj ordinara prudento diktas la samon).

Estas alta ŝanco ke vi jam uzas ion similan traefiknginx-ingress-controller kiel NodePort-finpunkto (aŭ LoadBalancer, kiu ankaŭ uzas NodePort) por direkti HTTP-enirtrafikon, kaj agordi ĉi tiun opcion povas signife redukti la latentecon por tiaj petoj.

В ĉi tiu publikigado Vi povas lerni pli pri ekstera TrafficPolicy, ĝiaj avantaĝoj kaj malavantaĝoj.

10. Ne ligu al aretoj kaj ne misuzu la kontrolaviadilon

Antaŭe, estis kutime voki servilojn per propraj nomoj: Anton, HAL9000 kaj Colossus... Hodiaŭ ili estis anstataŭigitaj per hazarde generitaj identigiloj. Tamen, la kutimo restis, kaj nun propraj nomoj iras al aretoj.

Tipa rakonto (bazita sur realaj eventoj): ĉio komenciĝis per pruvo de koncepto, do la areto havis fieran nomon. testado… Jaroj pasis kaj ĝi estas ANKORE uzata en produktado, kaj ĉiuj timas tuŝi ĝin.

Estas nenio amuza pri aretoj iĝi dorlotbestoj, do ni rekomendas forigi ilin periode dum ekzercado katastrofa reakiro (ĉi tio helpos kaosa inĝenierado - ĉ. traduk.). Krome, ne malutilus labori sur la kontroltavolo (kontrolaviadilo). Timi tuŝi lin ne estas bona signo. Ktp. mortinta? Knaboj, vi vere havas problemojn!

Aliflanke, vi ne devas lasi sin pri manipulado de ĝi. Kun la tempo la kontroltavolo povas fariĝi malrapida. Plej verŝajne, tio estas pro granda nombro da objektoj kreitaj sen ilia rotacio (ofta situacio kiam oni uzas Helm kun defaŭltaj agordoj, tial ĝia stato en konfiguracioj/sekretoj ne estas ĝisdatigita - kiel rezulto, miloj da objektoj amasiĝas en la kontroltavolo) aŭ kun konstanta redaktado de kube-api-objektoj (por aŭtomata skalo, por CI/KD, por monitorado, okazaĵprotokoloj, regiloj ktp.).

Krome, ni rekomendas kontroli la SLA/SLO-interkonsentojn kun la administrita Kubernetes-provizanto kaj atenti la garantiojn. La vendisto povas garantii kontroli tavolo havebleco (aŭ ĝiaj subkomponentoj), sed ne la p99 prokrasto de petoj, kiujn vi sendas al ĝi. Alivorte, vi povas eniri kubectl get nodes, kaj ricevu respondon nur post 10 minutoj, kaj ĉi tio ne estos malobservo de la kondiĉoj de la serva interkonsento.

11. Gratifiko: uzante la lastan etikedon

Sed ĉi tio jam estas klasikaĵo. Lastatempe ni trovis ĉi tiun teknikon malpli ofte, ĉar multaj, lerninte el amara sperto, ĉesis uzi la etikedon. :latest kaj komencis alpingli versiojn. Hura!

ECR konservas neŝanĝeblecon de bildaj etikedoj; Ni rekomendas, ke vi konatiĝu kun ĉi tiu rimarkinda funkcio.

Resumo

Ne atendu, ke ĉio funkcios dum la nokto: Kubernetes ne estas panaceo. Malbona programo restos tiel eĉ en Kubernetes (kaj verŝajne ĝi plimalboniĝos). Nezorgemo kondukos al troa komplekseco, malrapida kaj streĉa laboro de la kontroltavolo. Aldone, vi riskas resti sen katastrofa reakiro. Ne atendu, ke Kubernetes provizos izolecon kaj altan haveblecon el la skatolo. Pasigu iom da tempo farante vian aplikon vere nuba indiĝena.

Vi povas konatiĝi kun la malsukcesaj spertoj de diversaj teamoj en ĉi tiu kolekto de rakontoj de Henning Jacobs.

Tiuj, kiuj deziras aldoni al la listo de eraroj donitaj en ĉi tiu artikolo, povas kontakti nin en Twitter (@MarekBartik, @MstrsObserver).

PS de tradukisto

Legu ankaŭ en nia blogo:

fonto: www.habr.com

Aldoni komenton