10 Errori cumuni quandu si usa Kubernetes

Nota. transl.: L'autori di stu articulu sò ingegneri di una piccula cumpagnia ceca, pipetail. Anu riesciutu à cullà una lista maravigliosa di [a volte banali, ma ancu] prublemi assai pressanti è cuncepzioni sbagliate ligati à l'operazione di clusters Kubernetes.

10 Errori cumuni quandu si usa Kubernetes

Nantu à l'anni di usu di Kubernetes, avemu travagliatu cù un gran numaru di clusters (sia amministrati sia micca gestiti - in GCP, AWS è Azure). À u tempu, avemu cuminciatu à nutà chì certi sbagli sò sempre ripetuti. Tuttavia, ùn ci hè micca vergogna in questu: avemu fattu a maiò parte di elli stessu!

L'articulu cuntene l'errori più cumuni è ammenta ancu cumu per correggerli.

1. Risorse : dumande è limiti

Questu articulu meriteghja definitamente l'attenzione più vicinu è u primu postu in a lista.

Di solitu dumanda CPU o ùn hè micca specificatu à tutti o hà un valore assai bassu (per mette quant'è pods nantu à ogni node pussibule). Cusì, i nodi diventanu sovraccarichi. Durante i tempi di carica alta, a putenza di trasfurmazioni di u nodu hè cumplettamente utilizata è una carica di travagliu particulari riceve solu ciò chì "demanda" da throttling CPU. Questu porta à una latenza di l'applicazione aumentata, timeouts, è altre cunsequenze spiacevoli. (Leghjite più nantu à questu in a nostra altra traduzzione recente: "Limiti di CPU è throttling aggressivu in Kubernetes"- ca. trad.)

Best Effort (estremamente ùn cunsigliatu):

resources: {}

Richiesta CPU estremamente bassa (estremamente ùn cunsigliatu):

   resources:
      Requests:
        cpu: "1m"

Per d 'altra banda, a presenza di un limitu di CPU pò purtà à saltà irragionevule di i cicli di clock per pods, ancu s'ellu u processatore di u nodu ùn hè micca cumplettamente carricu. In novu, questu pò purtà à ritardi aumentati. A cuntruversia cuntinueghja intornu à u paràmetru Quota CPU CFS in u kernel Linux è u throttling di CPU sicondu i limiti stabiliti, è ancu di disattivà a quota CFS... Ai, i limiti di CPU ponu causà più prublemi di ciò chì ponu risolve. Più infurmazione nantu à questu pò esse truvata à u ligame sottu.

Scelta eccessiva (sopravvissu) i prublemi di memoria pò purtà à prublemi più grande. Aghjunghje u limitu di CPU implica saltà i cicli di clock, mentre chì ghjunghje à u limitu di memoria implica uccidendu u pod. Avete mai osservatu OOMkill? Iè, hè esattamente ciò chì parlemu.

Vulete minimizzà a probabilità di questu succede? Ùn over-allocate memoria è utilizate Guaranteed QoS (Quality of Service) mettendu a dumanda di memoria à u limitu (cum'è in l'esempiu sottu). Leghjite più nantu à questu in Presentazioni di Henning Jacobs (Lead Engineer à Zalando).

Burstable (più probabilità di esse OOMkilled):

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

Guaranteed:

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

Chì puderia aiutà à creà risorse?

Cù l'aiutu di metrics-server pudete vede u cunsumu attuale di risorse di CPU è l'usu di memoria per pods (è cuntenituri in elli). Probabilmente, avete digià aduprà. Basta eseguite i seguenti cumandamenti:

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

Tuttavia, mostranu solu l'usu attuale. Puderà dà una idea grossa di l'ordine di grandezza, ma in fine, avete bisognu storia di cambiamenti in metrica à u tempu (per risponde à e dumande cum'è: "Chì era a carica massima di CPU?", "Chì era a carica ieri matina?", etc.). Per questu pudete aduprà Prometheus, DataDog è altri arnesi. Simply ottennu metriche da metrics-server è li almacenanu, è l'utilizatore pò interrugalli è tracciali in cunseguenza.

VerticalPodAutoscaler si permette di automatizà stu prucessu. Traccia u CPU è a storia di l'usu di a memoria è stabilisce novi richieste è limiti basati nantu à sta informazione.

Utilizà a putenza di computing in modu efficiente ùn hè micca un compitu faciule. Hè cum'è ghjucà à Tetris tuttu u tempu. Se paghete troppu per a putenza di calculu cù un cunsumu mediu bassu (per dì ~ 10%), ricumandemu di circà i prudutti basati in AWS Fargate o Virtual Kubelet. Sò custruiti nantu à un mudellu di fattura senza servitore / pagamentu per usu, chì pò esse più prezzu in tali cundizioni.

2. Sonde di vivacità è di prontezza

Per automaticamente, i cuntrolli di vivacità è di prontezza ùn sò micca attivati ​​​​in Kubernetes. È qualchì volta si scurdanu di accendeli...

Ma cumu altru pudete inizià un riavviu di serviziu in casu d'errore fatale? È cumu u bilanciu di carica sapi chì un pod hè prontu à accettà u trafficu? O chì pò trattà di più trafficu?

Sti testi sò spessu cunfusi cù l'altri:

  • Vita - verificazione di "survivability", chì riavvia u pod si falla;
  • Preparazione - verificazione di prontezza, se falla, disconnects the pod from the Kubernetes service (questu pò esse verificatu usendu kubectl get endpoints) è u trafficu ùn ghjunghje micca finu à chì u prossimu cuntrollu hè cumpletu cù successu.

Tramindui sti cuntrolli REALIZZATA DURANTE TUTTI U CICLU DI VITA DI U POD. Hè assai impurtante.

Un misconception cumuni hè chì e sonde di prontezza sò eseguite solu à l'iniziu per chì l'equilibratore pò sapè chì u pod hè prontu (Ready) è pò cumincià à trattà u trafficu. Tuttavia, questu hè solu una di l'opzioni per u so usu.

Un altru hè a pussibilità di scopre chì u trafficu nantu à u pod hè eccessivu è si sovraccarica (o u pod esegue calculi intensivi di risorse). In questu casu, u cuntrollu di prontezza aiuta riduce a carica nantu à u podu è "cool".. U cumpletu successu di un cuntrollu di prontezza in u futuru permette aumentà a carica nantu à u pod di novu. In questu casu (se a prova di prontezza falla), u fallimentu di a prova di vita seria assai contraproducente. Perchè riavvia un pod chì hè sanu è chì travaglia dura?

Dunque, in certi casi, nisun cuntrolli in tuttu hè megliu cà l'attivazione cù paràmetri incorrectamente cunfigurati. Cum'è dettu sopra, se verificazione di vivacità copie verificazione di prontezza, tandu sì in grossi guai. L'opzione pussibule hè di cunfigurà prova di prontezza solue vitalità periculosa lasciate da parte.

I dui tipi di cuntrolli ùn deve micca fallu quandu i dependenzii cumuni fallenu, altrimente questu portarà à un fallimentu in cascata (avalanche-like) di tutti i podi. In altre parolle, ùn fate micca male.

3. LoadBalancer per ogni serviziu HTTP

Probabilmente, avete servizii HTTP in u vostru cluster chì vulete trasmette à u mondu esternu.

Sè vo apre u serviziu cum'è type: LoadBalancer, u so controller (sicondu u fornitore di serviziu) furnisce è negozià un LoadBalancer esternu (micca necessariamente in esecuzione in L7, ma ancu in L4), è questu pò influenzà u costu (indirizzu IPv4 staticu esternu, putenza di computing, fattura per seconda). ) per via di a necessità di creà un gran numaru di tali risorse.

In questu casu, hè assai più logicu di utilizà un balancer di carica esterna, aprendu servizii cum'è type: NodePort. O megliu ancu, espansione qualcosa cum'è nginx-ingress-controller (o traefic), chì serà u solu NodePort endpoint assuciatu cù u bilanciatore di carica esterna è indirizzerà u trafficu in u cluster usendu ingress-Risorse Kubernetes.

Altri servizii intra-cluster (micro) chì interagiscenu cù l'altri ponu "communicà" cù servizii cum'è ClusterIP è un mecanismu di scuperta di serviziu integratu via DNS. Solu ùn aduprate micca u so DNS / IP publicu, postu chì questu pò influenzà a latenza è aumentà u costu di i servizii di nuvola.

4. Autoscaling un cluster senza piglià in contu e so funziunalità

Quandu aghjunghjenu nodi è sguassate da un cluster, ùn deve micca s'appoghjanu in certi metrichi basi cum'è l'usu di CPU in quelli nodi. A pianificazione di pod deve piglià in contu parechji restrizioni, cum'è l'affinità di pod / node, taints and tolerations, richieste di risorse, QoS, etc. Utilizà un autoscaler esternu chì ùn piglia micca questi sfumature in contu pò purtà à prublemi.

Imagine chì un certu pod deve esse pianificatu, ma tutta a putenza CPU dispunibile hè dumandata / disassemblata è u pod si ferma in un statu Pending. L'autoscaler esternu vede a carica media di CPU attuale (micca quella dumandata) è ùn principia micca l'espansione (scale-out) - ùn aghjunghje micca un altru node. In u risultatu, stu pod ùn serà micca pianificatu.

In questu casu, scala inversa (scala in) - caccià un node da un cluster hè sempre più difficiuli di implementà. Imagine chì avete un pod stateful (cù almacenamiento persistente cunnessu). Volumi persistenti di solitu appartene à zona di dispunibilità specifica è ùn sò micca replicati in a regione. Cusì, se un autoscaler esternu sguassate un node cù questu pod, u pianificatore ùn serà micca capaci di pianificà stu pod in un altru node, postu chì questu pò esse fattu solu in a zona di dispunibilità induve si trova u almacenamiento persistente. Pod sarà stuck in statu Pending.

Moltu populari in a cumunità Kubernetes cluster-autoscaler. Funziona nantu à un cluster, sustene l'API da i principali fornitori di nuvola, piglia in contu tutte e restrizioni è pò scala in i casi sopra. Hè ancu capace di scale-in mantenendu tutti i limiti stabiliti, risparmiendu cusì soldi (chì altrimenti si spenderebbe in capacità inutilizata).

5. Trascurate e capacità IAM / RBAC

Attenti à aduprà utilizatori IAM cù secreti persistenti per macchine è applicazioni. Organizzà l'accessu tempurale utilizendu roli è cunti di serviziu (conti di serviziu).

Avemu spessu scontru u fattu chì i chjavi d'accessu (è i sicreti) sò codificati in a cunfigurazione di l'applicazione, è ancu di trascuratà a rotazione di sicreti malgradu avè accessu à Cloud IAM. Aduprate roli IAM è cunti di serviziu invece di utilizatori induve apprupriati.

10 Errori cumuni quandu si usa Kubernetes

Scurdate di kube2iam è andate direttamente à i roli IAM per i cunti di serviziu (cum'è descrittu in nota di u listessu nome Š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

Una annotazione. Ùn hè cusì difficiule, nò?

Inoltre, ùn cuncede micca privilegi di cunti di serviziu è profili di istanza admin и cluster-admins'ellu ùn anu micca bisognu. Questu hè un pocu più difficiuli di implementà, in particulare in RBAC K8s, ma sicuramente vale a pena u sforzu.

6. Ùn s'appoghjanu micca in l'anti-affinità automatica per i pods

Imagine chì avete trè repliche di qualchì implementazione nantu à un node. U node casca, è cun ellu tutte e rèpliche. Situazione spiacevole, nò? Ma perchè eranu tutte e rèpliche nantu à u stessu node? Kubernetes ùn hè micca suppostu di furnisce alta dispunibilità (HA) ?!

Sfurtunatamente, u pianificatore Kubernetes, per a so propria iniziativa, ùn rispetta micca e regule di esistenza separata. (anti-affinità) per i baccelli. Deve esse esplicitamente dichjarati:

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

Eccu tuttu. Avà i pods seranu pianificati in diversi nodi (sta cundizione hè verificata solu durante a pianificazione, ma micca durante u so funziunamentu - dunque requiredDuringSchedulingIgnoredDuringExecution).

Quì avemu parlatu podAntiAffinity nantu à diversi nodi: topologyKey: "kubernetes.io/hostname", - è micca nantu à e diverse zone di dispunibilità. Per implementà un HA cumpletu, avete da scavà più in questu tema.

7. Ignore PodDisruptionBudgets

Imagine chì avete una carica di produzzione nantu à un cluster Kubernetes. Periodicamente, i nodi è u cluster stessu anu da esse aghjurnatu (o decommissioned). PodDisruptionBudget (PDB) hè qualcosa cum'è un accordu di garanzia di serviziu trà amministratori di cluster è utilizatori.

PDB permette di evità interruzioni di serviziu causate da una mancanza di nodi:

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

In questu esempiu, voi, cum'è utilizatore di u cluster, dite à l'amministratori: "Ehi, aghju un serviziu di zookeeper, è ùn importa ciò chì fate, vogliu avè almenu 2 repliche di stu serviziu sempre dispunibule".

Pudete leghje più nantu à questu ccà.

8. Utenti multipli o ambienti in un cluster cumunu

Spazi di nomi Kubernetes (spazi di nomi) ùn furnisce micca un insulamentu forte.

Un misconception cumuni hè chì se implementate una carica non-prod in un spaziu di nomi è una carica prod in un altru, allora ùn s'influenzeranu in ogni modu... In ogni casu, un certu livellu di isolamentu pò esse ottenutu usendu richieste di risorse / limitazioni, stabilisce quote, è stabilisce classi di priorità. Qualchì isolamentu "fisicu" in u pianu di dati hè furnitu da affinità, tollerazioni, taints (o nodeselettori), ma una tale separazione hè abbastanza. cumplicatu implementà.

Quelli chì anu bisognu di cumminà i dui tipi di carichi di travagliu in u stessu cluster anu da affruntà a cumplessità. Se ùn ci hè micca bisognu, è pudete permette di avè unu un cluster in più (per dì, in una nuvola publica), allora hè megliu per fà. Questu uttene un livellu assai più altu di insulazione.

9. externalTrafficPolicy: Cluster

Assai spessu vedemu chì tuttu u trafficu in u cluster passa per un serviziu cum'è NodePort, per quale a pulitica predeterminata hè stabilita. externalTrafficPolicy: Cluster... Vole dì què NodePort hè apertu nantu à ogni node in u cluster, è pudete aduprà qualsiasi di elli per interagisce cù u serviziu desideratu (set of pods).

10 Errori cumuni quandu si usa Kubernetes

À u listessu tempu, i baccelli veri assuciati cù u serviziu NodePort sopra-mintuatu sò generalmente dispunibuli solu nantu à un certu sottogruppu di sti nodi. In altre parolle, se mi cunnetta à un node chì ùn hà micca u podu necessariu, trasmetterà u trafficu à un altru node, aghjunghje un hop è cresce a latenza (se i nodi sò situati in diverse zoni di dispunibilità / centri di dati, a latenza pò esse abbastanza alta; in più, i costi di u trafficu di egressu aumentanu).

Per d 'altra banda, se un certu serviziu di Kubernetes hà un settore di pulitica externalTrafficPolicy: Local, allora NodePort si apre solu nantu à quelli nodi induve i pods necessarii sò in realtà in esecuzione. Quandu si usa un balancer di carica esterna chì verifica u statu (controlu di salute) endpoints (cumu si faci AWS ELB), ellu mandarà u trafficu solu à i nodi necessarii, chì avarà un effettu benefizièvule nantu à i ritardi, i bisogni di l'informatica, i bills di egressu (è u sensu cumunu dicta u stessu).

Ci hè una alta probabilità chì site digià aduprà qualcosa simili traefic o nginx-ingress-controller cum'è un endpoint NodePort (o LoadBalancer, chì usa ancu NodePort) per indirizzà u trafficu di ingressu HTTP, è stabilisce sta opzione pò riduce significativamente a latenza per tali richieste.

В sta publicazione Pudete amparà di più nantu à u TrafficPolicy esternu, i so vantaghji è i disadvantages.

10. Ùn avete micca ligatu à clusters è ùn abusate micca di u pianu di cuntrollu

Nanzu, era abitudine di chjamà i servitori cù nomi propiu: Anton, HAL9000 è Colossus... Oghje sò stati rimpiazzati da identificatori generati aleatoriamente. Tuttavia, l'abitudine restava, è avà i nomi propiu vanu à clusters.

Una storia tipica (basata nantu à avvenimenti veri): tuttu principia cù una prova di cuncettu, cusì u cluster avia un nome fieru essai... L'anni sò passati è hè sempre usatu in a produzzione, è tutti anu a paura di tuccà.

Ùn ci hè nunda di divertimentu nantu à i clusters chì si trasformanu in animali domestici, cusì ricumandemu di caccià periodicamente mentre pratica ripresa di disastru (questu aiuterà ingegneria di caos - ca. trad.). Inoltre, ùn saria micca male à travaglià nantu à a capa di cuntrollu (pianu di cuntrollu). A paura di tuccallu ùn hè micca un bonu signu. Etc. mortu ? Ragazzi, site veramente in guai !

Per d 'altra banda, ùn deve micca esse purtatu cù a manipulazione. Cù u tempu a strata di cuntrollu pò esse lentu. Hè assai prubabile, questu hè duvuta à un gran numaru d'uggetti chì sò creati senza a so rotazione (una situazione cumuna quandu si usa Helm cù paràmetri predeterminati, chì hè per quessa chì u so statu in configmaps / secreti ùn hè micca aghjurnatu - in u risultatu, millaie d'uggetti s'accumulanu in a strata di cuntrollu) o cù l'edizione constante di l'uggetti kube-api (per scaling automaticu, per CI / CD, per monitoring, logs di eventi, controller, etc.).

Inoltre, ricumandemu di verificà l'accordi SLA / SLO cù u fornitore Kubernetes gestitu è ​​attente à e garanzie. U venditore pò guarantiscia cuntrullà a dispunibilità di strati (o i so subcomponenti), ma micca u ritardu p99 di e dumande chì vi mandate. In altre parolle, pudete entre kubectl get nodes, è riceve una risposta solu dopu à 10 minuti, è questu ùn serà micca una violazione di i termini di l'accordu di serviziu.

11. Bonus: cù l 'ultimu tag

Ma questu hè digià un classicu. Ultimamente avemu scontru cù sta tecnica menu spessu, postu chì parechji, avendu amparatu da una sperienza amara, anu cessatu di utilizà l'etichetta. :latest è hà cuminciatu à pinning versioni. Eura!

ECR mantene l'immutabilità di e tag di l'imaghjini; Hè ricumandemu di familiarizàvi cù sta funzione notevuli.

Resumen

Ùn aspettate micca chì tuttu u travagliu da a notte: Kubernetes ùn hè micca una panacea. Bad app fermarà cusì ancu in Kubernetes (è probabilmente peghju). A trascuranza portarà à una cumplessità eccessiva, u travagliu lento è stressante di a capa di cuntrollu. Inoltre, rischiate di esse lasciatu senza una strategia di ricuperazione di disastru. Ùn aspettate micca chì Kubernetes furnisce isolamentu è alta dispunibilità fora di a scatula. Passate un pocu di tempu rendendu a vostra applicazione veramente nativa in nuvola.

Pudete cunnosce l'esperienze senza successu di diverse squadre in sta cullizzioni di storie di Henning Jacobs.

Quelli chì vulianu aghjunghje à a lista di l'errori datu in questu articulu ponu cuntattateci in Twitter (@MarekBartik, @MstrsObserver).

PS da u traduttore

Leghjite puru nant'à u nostru blog:

Source: www.habr.com

Add a comment