Cinque miss quandu implementate a prima applicazione in Kubernetes

Cinque miss quandu implementate a prima applicazione in KubernetesFail di Aris-Dreamer

Parechje persone crede chì hè abbastanza per migrà l'applicazione à Kubernetes (sia cù Helm o manualmente) è seranu felici. Ma ùn hè micca cusì simplice.

squadra Mail.ru Soluzioni Cloud traduttu un articulu da l'ingegnere DevOps Julian Gindi. Ellu sparte ciò chì trappule chì a so cumpagnia hà scontru durante u prucessu di migrazione per ùn passà micca nantu à u listessu rake.

Primu Passu: Configurazione di e Demande di Pod è Limiti

Accuminciamu per stabilisce un ambiente pulitu in quale i nostri pods curriranu. Kubernetes face un grande travagliu di pianificazione di pods è di gestisce e cundizioni di fallimentu. Ma hè risultatu chì u pianificatore à volte ùn pò micca mette un pod s'ellu hè difficiule di stimà quante risorse hà bisognu à travaglià bè. Hè quì chì e richieste di risorse è limiti venenu. Ci hè assai dibattitu annantu à u megliu approcciu per stabilisce e dumande è i limiti. Calchì volta si sente veramente chì hè più arte chè scienza. Eccu u nostru approcciu.

richieste di pod - Questu hè u valore principale utilizatu da u pianificatore per mette in modu ottimale u pod.

Da Documentazione Kubernetes: U passu di filtrazione determina u settore di nodi induve u pod pò esse pianificatu. Per esempiu, u filtru PodFitsResources verifica se un node hà abbastanza risorse per suddisfà e richieste di risorse specifiche di un pod.

Utilizemu e dumande di l'applicazione in modu chì ponu esse aduprate per stima quante risorse in realtà L'applicazione hà bisognu à travaglià bè. In questu modu, u pianificatore pò mette i nodi in modu realisticu. Inizialmente, avemu vulsutu stabilisce e dumande cù un margine per assicurà chì ogni pod avia un numeru abbastanza grande di risorse, ma avemu nutatu chì i tempi di pianificazione anu aumentatu significativamente è alcuni pods ùn sò mai stati cumplettamente pianificati, cum'è s'ellu ùn era micca ricevutu richieste di risorse per elli.

In questu casu, u pianificatore spessu spingeva i pods è ùn puderia micca riprogrammà, perchè u pianu di cuntrollu ùn avia micca idea di quante risorse l'applicazione necessitava, un cumpunente chjave di l'algoritmu di pianificazione.

Limiti di pod - questu hè un limitu più chjaru per u pod. Rapprisenta a quantità massima di risorse chì u cluster attribuirà à u containeru.

Di novu, da documentazione ufficiale: Se un containeru hà un limite di memoria di 4 GiB stabilitu, allora u kubelet (è u cuntainer runtime) l'applicà. U runtime ùn permette micca u cuntinuu per utilizà più di u limitu di risorse specificata. Per esempiu, quandu un prucessu in un cuntainer prova di utilizà più di a quantità permessa di memoria, u kernel di u sistema termina u prucessu cù un errore "fora di memoria" (OOM).

Un cuntinuu pò sempre aduprà più risorse chì specificate in a dumanda di risorsa, ma ùn pò mai aduprà più di ciò chì specifica in u limitu. Stu valore hè difficiule di stabilisce currettamente, ma hè assai impurtante.

Ideale, vulemu chì i bisogni di risorse di un pod cambienu annantu à u ciclu di vita di un prucessu senza interferiscenu cù altri prucessi in u sistema - questu hè u scopu di stabilisce limiti.

Sfurtunatamente, ùn possu micca dà struzzioni specifiche nantu à i valori da stabilisce, ma noi stessi aderemu à e seguenti regule:

  1. Utilizendu un strumentu di teste di carica, simulemu un livellu di basa di trafficu è monitoremu l'usu di e risorse di pod (memoria è processore).
  2. Pudemu e dumande di pod à un valore arbitrariamente bassu (cù un limitu di risorse di circa 5 volte u valore di e dumande) è osservate. Quandu e dumande sò troppu bassu, u prucessu ùn pò micca inizià, spessu causendu misteriosi errori di runtime Go.

Nota chì i limiti di risorse più alti facenu a pianificazione più difficiule perchè u pod necessita un node di destinazione cù abbastanza risorse dispunibili.

Imagine una situazione induve avete un servitore web ligeru cù un limitu di risorse assai altu, dì 4 GB di memoria. Stu prucessu duverà esse scala orizontale, è ogni novu modulu duverà esse pianificatu nantu à un node cù almenu 4 GB di memoria dispunibule. Se un tali nodu ùn esiste micca, u cluster deve intruduce un novu node per processà quellu pod, chì pò piglià un pocu di tempu. Hè impurtante di mantene a diffarenza trà e dumande di risorse è i limiti à u minimu per assicurà una scala rapida è liscia.

Passu dui: stallà testi Liveness è Readiness

Questu hè un altru tema sottile chì hè spessu discututu in a cumunità Kubernetes. Hè impurtante per avè una bona cunniscenza di e teste di Liveness è Readiness, postu chì furniscenu un mecanismu per u software per eseguisce bè è minimizzà i tempi di inattività. Tuttavia, ponu causà un successu di rendiment seriu à a vostra applicazione se micca cunfigurata currettamente. Quì sottu hè un riassuntu di ciò chì sò i dui campioni.

Vita mostra se u containeru hè in esecuzione. Se falla, u kubelet uccide u containeru è una pulitica di riavvia hè attivata per questu. Se u cuntinuu ùn hè micca equipatu cù una sonda Liveness, allora u statu predeterminatu serà successu - questu hè ciò chì dice in Documentazione Kubernetes.

E sonde di Liveness duveranu esse economiche, vale à dì chì ùn deve micca cunsumà assai risorse, perchè funzionanu spessu è anu bisognu à informà Kubernetes chì l'applicazione hè in esecuzione.

Se stabilisce l'opzione per eseguisce ogni siconda, questu aghjunghje 1 dumanda per seconda, cusì sia cunzignatu chì risorse supplementari seranu necessarii per trattà stu trafficu.

À a nostra cumpagnia, i testi Liveness cuntrollanu i cumpunenti core di una applicazione, ancu s'è i dati (per esempiu, da una basa di dati remota o cache) ùn hè micca cumplettamente accessibile.

Avemu cunfiguratu l'applicazioni cù un endpoint "salute" chì solu torna un codice di risposta di 200. Questu hè un indicazione chì u prucessu hè in esecuzione è capace di processà e dumande (ma micca ancu trafficu).

Sample Preparazione indica se u containeru hè prontu à serve e dumande. Se a sonda di preparazione falla, u controller di u puntu finale elimina l'indirizzu IP di u pod da i punti finali di tutti i servizii chì currispondenu à u pod. Questu hè ancu dichjaratu in a documentazione di Kubernetes.

E sonde di preparazione cunsuma più risorse perchè devenu esse mandate à u backend in una manera chì indica chì l'applicazione hè pronta per accettà e dumande.

Ci hè assai dibattitu in a cumunità nantu à se accede direttamente à a basa di dati. In vista di l'overhead (i cuntrolli sò realizati spessu, ma ponu esse aghjustati), avemu decisu chì per alcune applicazioni, a prontezza à serve u trafficu hè cuntatu solu dopu avè verificatu chì i registri sò tornati da a basa di dati. E prove di preparazione ben cuncepite assicuravanu livelli più alti di dispunibilità è eliminanu i tempi di inattività durante l'implementazione.

Se decide di dumandà a basa di dati per pruvà a prontezza di a vostra applicazione, assicuratevi chì hè u più prezzu pussibule. Pigliemu sta dumanda:

SELECT small_item FROM table LIMIT 1

Eccu un esempiu di cumu cunfiguremu sti dui valori in Kubernetes:

livenessProbe: 
 httpGet:   
   path: /api/liveness    
   port: http 
readinessProbe:  
 httpGet:    
   path: /api/readiness    
   port: http  periodSeconds: 2

Pudete aghjunghje alcune opzioni di cunfigurazione supplementari:

  • initialDelaySeconds - quanti seconde passanu trà u lanciu di u containeru è u principiu di i campioni.
  • periodSeconds - intervallu d'attesa trà e teste di mostra.
  • timeoutSeconds - u numeru di seconde dopu chì l'unità hè cunsiderata una emergenza. Timeout regularmente.
  • failureThreshold - u numeru di fallimenti di teste prima chì un signalu di riavvia hè mandatu à u pod.
  • successThreshold - u nùmeru di sondi successi prima chì a poda entre in u statu prontu (dopu à un fallimentu, quandu u pod principia o recupera).

Passu trè: stabilisce e pulitiche di rete predeterminate per u pod

Kubernetes hà una topografia di rete "piatta"; per difettu, tutti i pods cumunicanu direttamente cù l'altri. In certi casi, questu ùn hè micca desideratu.

Un prublema di sicurezza potenziale hè chì un attaccante puderia usà una sola applicazione vulnerabile per mandà u trafficu à tutti i pods in a reta. Cum'è cù parechji spazii di sicurità, u principiu di u minimu privilegiu si applica quì. Ideale, e pulitiche di a rete anu da specificà esplicitamente quali cunnessione trà pods sò permessi è quali ùn sò micca.

Per esempiu, quì sottu hè una pulitica simplice chì denega tuttu u trafficu entrante per un spaziu di nome specificu:

---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:  
 name: default-deny-ingress
spec:  
 podSelector: {}  
 policyTypes:  
   - Ingress

Visualizazione di sta cunfigurazione:

Cinque miss quandu implementate a prima applicazione in Kubernetes
(https://miro.medium.com/max/875/1*-eiVw43azgzYzyN1th7cZg.gif)
More details ccà.

Quattru passu: cumpurtamentu persunalizatu cù ganci è cuntenituri init

Unu di i nostri scopi principali era di furnisce implementazioni à Kubernetes senza tempi di inattività per i sviluppatori. Questu hè difficiule perchè ci sò parechje opzioni per chjude l'applicazioni è liberà e risorse chì anu utilizatu.

Difficultà particulari sò ghjunti cun Nginx. Avemu nutatu chì quandu questi pods sò stati disposti in sequenza, e cunnessione attive sò state abbandunate prima di u cumpletu successu.

Dopu una ricerca estensiva in linea, risulta chì Kubernetes ùn aspetta micca chì e cunnessione Nginx si esauriscenu prima di finisce u pod. Utilizendu un ganciu pre-stop, avemu implementatu a seguente funziunalità è sguassate cumplettamente i tempi di inattività:

lifecycle: 
 preStop:
   exec:
     command: ["/usr/local/bin/nginx-killer.sh"]

Ma nginx-killer.sh:

#!/bin/bash
sleep 3
PID=$(cat /run/nginx.pid)
nginx -s quit
while [ -d /proc/$PID ]; do
   echo "Waiting while shutting down nginx..."
   sleep 10
done

Un altru paradigma estremamente utile hè l'usu di cuntenituri init per trattà l'iniziu di applicazioni specifiche. Questu hè sopratuttu utile si avete un prucessu di migrazione di basa di dati intensivi di risorse chì deve esse esecutatu prima chì l'applicazione principia. Pudete ancu specificà un limitu di risorse più altu per stu prucessu senza stabilisce un tali limitu per l'applicazione principale.

Un altru schema cumuni hè di accede à i secreti in un containeru init chì furnisce queste credenziali à u modulu principale, chì impedisce l'accessu micca autorizatu à i sicreti da u modulu di l'applicazione principale stessu.

Comu di solitu, cita da a documentazione: I cuntenituri di l'iniziu eseguinu in modu sicuru codice persunalizatu o utilità chì altrimenti riduceranu a sicurità di l'imaghjini di u containeru di l'applicazione. Mantenendu strumenti inutili separati, limitete a superficia di attaccu di l'imaghjini di u containeru di l'applicazione.

Passu Cinque: Configurazione di u Kernel

Infine, parlemu di una tecnica più avanzata.

Kubernetes hè una piattaforma estremamente flessibile chì vi permette di eseguisce carichi di travagliu cum'è vede bè. Avemu una quantità di applicazioni d'altu rendiment chì sò estremamente intensivi di risorse. Dopu avè realizatu una prova di carica estensiva, avemu scupertu chì una applicazione era in difficultà per trattà a carica di trafficu prevista quandu i paràmetri predeterminati di Kubernetes eranu in vigore.

Tuttavia, Kubernetes permette di eseguisce un containeru privilegiatu chì cambia i paràmetri di u kernel solu per un pod specificu. Eccu ciò chì avemu usatu per cambià u numeru massimu di cunnessione aperte:

initContainers:
  - name: sysctl
     image: alpine:3.10
     securityContext:
         privileged: true
      command: ['sh', '-c', "sysctl -w net.core.somaxconn=32768"]

Questa hè una tecnica più avanzata chì spessu ùn hè micca necessariu. Ma se a vostra applicazione hè in difficultà per affruntà una carica pesante, pudete pruvà à aghjustà alcune di queste paràmetri. Più dettagli nantu à stu prucessu è stabilisce valori diffirenti - cum'è sempre in a documentazione ufficiale.

In cunclusioni

Mentri Kubernetes pò sembrà una suluzione pronta fora di a scatula, ci sò uni pochi di passi chjave chì avete bisognu à fà per mantene e vostre applicazioni funzionanu bè.

In tutta a vostra migrazione Kubernetes, hè impurtante di seguità u "ciclu di prova di carica": lanciate l'applicazione, caricate a prova, osservate metrica è cumportamentu di scala, aghjustate a cunfigurazione basatu annantu à quelli dati, dopu ripetite u ciculu di novu.

Siate realistichi nantu à u vostru trafficu previstu è pruvate à spinghje oltre per vede quale cumpunenti si rompenu prima. Cù stu approcciu iterativu, solu uni pochi di i cunsiglii elencati ponu esse abbastanza per ottene u successu. O pò esse bisognu di una persunalizazione più profonda.

Fate sempre ste dumande:

  1. Quante risorse consumanu l'applicazioni è cumu cambierà stu voluminu?
  2. Chì sò i veri requisiti di scala? Quantu trafficu l'app gestirà in media? Chì ci hè u trafficu di punta?
  3. Quantu volte u serviziu hà bisognu di scala horizontale? Quantu rapidamente i novi pods anu da esse purtati in linea per riceve u trafficu?
  4. Cumu si chjude currettamente i pods? Hè questu necessariu in tuttu? Hè pussibule di ottene implementazione senza tempi di inattività?
  5. Cumu pudete minimizzà i risichi di sicurezza è limità i danni da qualsiasi pods compromessi? Qualchese serviziu hà permessi o accessu chì ùn anu micca bisognu?

Kubernetes furnisce una piattaforma incredibile chì vi permette di sfruttà e migliori pratiche per implementà migliaia di servizii in un cluster. Tuttavia, ogni applicazione hè diversa. A volte l'implementazione richiede un pocu più di travagliu.

Fortunatamente, Kubernetes furnisce a cunfigurazione necessaria per ottene tutti i scopi tecnichi. Utilizendu una cumminazione di richieste è limiti di risorse, sonde di Liveness è Readiness, init containers, pulitiche di rete è sintonizzazioni di u kernel persunalizati, pudete ottene un rendimentu altu cù a tolleranza di difetti è una scalabilità rapida.

Cosa altru à leghje:

  1. Best Practices è Best Practices per Running Containers and Kubernetes in Production Environments.
  2. 90+ Strumenti utili per Kubernetes: implementazione, gestione, monitoraghju, sicurezza è più.
  3. U nostru canale Intornu à Kubernetes in Telegram.

Source: www.habr.com

Add a comment