Bost huts egin dira Kubernetesen lehen aplikazioa zabaltzean

Bost huts egin dira Kubernetesen lehen aplikazioa zabaltzeanAris-Dreamer-ek huts egin du

Jende askok uste du nahikoa dela aplikazioa Kubernetesera migratzea (helm erabiliz edo eskuz) eta pozik egongo dira. Baina ez da hain erraza.

Team Mail.ru Cloud Solutions Julian Gindi DevOps ingeniariaren artikulu bat itzuli zuen. Migrazio-prozesuan bere konpainiak aurkitu dituen hutsuneak partekatzen ditu, rake bera zapal ez dezazun.

Lehen urratsa: Pod eskaerak eta mugak konfiguratzea

Has gaitezen gure lekak abiaraziko diren ingurune garbi bat konfiguratzen. Kubernetes-ek lan bikaina egiten du pod-ak programatzen eta hutsegite-baldintzak kudeatzen. Baina konturatu zen programatzaileak batzuetan ezin duela pod bat jarri behar bezala funtzionatzeko zenbat baliabide behar dituen kalkulatzea zaila bada. Hor sortzen dira baliabide eta mugen eskaerak. Eztabaida handia dago eskaerak eta mugak ezartzeko planteamendu onenari buruz. Batzuetan benetan zientzia baino artea dela sentitzen da. Hona hemen gure planteamendua.

Pod eskaerak - Hau da programatzaileak erabiltzen duen balio nagusia poda modu egokian kokatzeko.

Of Kubernetesen dokumentazioa: iragazketa-urratsak poda programatu daitekeen nodoen multzoa zehazten du. Adibidez, PodFitsResources iragazkiak nodo batek pod baten baliabide eskaera zehatzak asetzeko nahikoa baliabide dituen egiaztatzen du.

Aplikazio-eskaerak erabiltzen ditugu zenbat baliabide kalkulatzeko erabili ahal izateko Izan ere Aplikazioak behar bezala funtzionatzeko behar du. Horrela, programatzaileak nodoak modu errealistan kokatu ditzake. Hasieran eskaerak marjina batekin ezarri nahi genituen, pod bakoitzak baliabide kopuru aski handia zuela ziurtatzeko, baina programazio-denborak nabarmen handitzen zirela eta zenbait pod sekula ez zirela guztiz programatuta, haientzako baliabide-eskaerarik jaso ez balitz bezala.

Kasu honetan, programatzaileak sarritan lekak kanporatzen zituen eta ezin izango zituen birprogramatu kontrol-hegazkinak ez baitzuen ideiarik zenbat baliabide beharko lituzkeen aplikazioak, programazio-algoritmoaren funtsezko osagaia.

Pod mugak - hau lekaren muga argiagoa da. Klusterrak edukiontziari esleituko dizkion baliabide kopuru maximoa adierazten du.

Berriz ere, batetik dokumentazio ofiziala: Edukiontzi batek 4 GiB memoria-muga ezarrita badu, kubelet-ek (eta edukiontziaren exekuzio-denborak) betearaziko dute. Exekuzio-denborak ez du onartzen edukiontziari zehaztutako baliabide-muga baino gehiago erabiltzea. Adibidez, edukiontzi bateko prozesu bat baimendutako memoria kopurua baino gehiago erabiltzen saiatzen denean, sistemaren nukleoak prozesua amaitzen du "memoria gabe" (OOM) errore batekin.

Edukiontzi batek beti erabil ditzake baliabideen eskaeran zehaztutakoa baino baliabide gehiago, baina ezin du inoiz mugan zehaztutakoa baino gehiago erabili. Balio hori zaila da behar bezala ezartzea, baina oso garrantzitsua da.

Egokiena, pod baten baliabide-eskakizunak prozesu baten bizitza-zikloan zehar aldatzea nahi dugu, sistemako beste prozesuekin oztopatu gabe; hori da mugak ezartzea.

Zoritxarrez, ezin dut argibide zehatzik eman zer balio ezarri behar diren, baina guk geuk honako arau hauek betetzen ditugu:

  1. Karga probak egiteko tresna bat erabiliz, oinarrizko trafiko-maila simulatzen dugu eta pod baliabideen (memoria eta prozesadorea) erabilera kontrolatzen dugu.
  2. Pod eskaerak balio arbitrario baxuan ezartzen ditugu (baliabide-muga batekin eskaeren balioa baino 5 bider gutxi gorabehera) eta behatu. Eskaerak baxuegiak direnean, prozesua ezin da hasi, eta askotan Go exekutatzeko akats misteriotsuak eragiten ditu.

Kontuan izan baliabideen muga handiagoak zaildu egiten duela programazioa, podak baliabide nahikoa dituen xede-nodo bat behar duelako.

Imajinatu egoera bat non web zerbitzari arin bat duzun baliabide-muga oso altua duena, demagun 4 GB memoria. Prozesu honek horizontalki eskalatu beharko du ziurrenik, eta modulu berri bakoitza gutxienez 4 GB memoria erabilgarri duen nodo batean programatu beharko da. Halako nodorik ez badago, klusterrak nodo berri bat sartu beharko du pod hori prozesatzeko, eta horrek denbora pixka bat beharko du. Garrantzitsua da baliabideen eskaeren eta mugen arteko aldea ahalik eta txikiena izatea, eskalatze azkarra eta leuna bermatzeko.

Bigarren urratsa: Bizitasun eta Prestasun probak konfiguratzea

Kubernetes komunitatean maiz eztabaidatzen den beste gai sotil bat da. Garrantzitsua da Liveness eta Readiness probak ondo ulertzea, softwarea ondo exekutatzeko eta geldialdi-denbora minimizatzeko mekanismo bat eskaintzen baitute. Dena den, zure aplikazioari errendimendu larria eragin diezaiokete behar bezala konfiguratuta ez bada. Jarraian, bi laginak nolakoak diren laburbiltzen da.

Bizitasuna edukiontzia martxan dagoen ala ez erakusten du. Huts egiten badu, kubelet-ek edukiontzia hiltzen du eta berrabiarazi politika gaituta dago horretarako. Edukiontzia Liveness zunda batekin hornituta ez badago, egoera lehenetsia arrakastatsua izango da - hauxe dio Kubernetesen dokumentazioa.

Liveness zundek merkeak izan behar dute, hau da, ez lukete baliabide asko kontsumitu behar, maiz exekutatzen direlako eta Kubernetes-i aplikazioa martxan dagoela jakinarazi behar diotelako.

Aukera segundoro exekutatzeko ezartzen baduzu, segundoko eskaera bat gehituko da, beraz, kontutan izan trafiko hori kudeatzeko baliabide gehigarriak beharko direla.

Gure enpresan, Liveness probek aplikazio baten oinarrizko osagaiak egiaztatzen dituzte, nahiz eta datuak (adibidez, urruneko datu-base edo cache batekoak) guztiz eskuragarri ez izan.

Aplikazioak "osasuna" amaierako puntu batekin konfiguratu ditugu, 200 erantzun-kode bat besterik gabe itzultzen duena. Hau prozesua martxan dagoela eta eskaerak prozesatzeko gai dela adierazten du (baina oraindik ez da trafikoa).

proba jarrera edukiontzia eskaerak egiteko prest dagoen adierazten du. Prestakuntza-zundaketak huts egiten badu, amaierako kontrolatzaileak podaren IP helbidea kentzen du podari dagozkion zerbitzu guztien amaierako puntuetatik. Hau Kubernetes-en dokumentazioan ere adierazten da.

Presttasun probek baliabide gehiago kontsumitzen dituzte, aplikazioa eskaerak onartzeko prest dagoela adierazteko backendera bidali behar direlako.

Komunitatean eztabaida handia dago datu-basera zuzenean sartu ala ez. Gainbehera kontuan hartuta (egiaztapenak maiz egiten dira, baina egokitu daitezke), zenbait aplikaziotarako, trafikoa zerbitzatzeko presttasuna datu-basetik erregistroak itzultzen direla egiaztatu ondoren soilik zenbatzen dela erabaki dugu. Ongi diseinatutako prestasun-probek erabilgarritasun-maila handiagoak bermatu zituzten eta inplementazio garaian geldialdi-denbora ezabatu zuten.

Datu-baseari kontsulta egitea erabakitzen baduzu zure aplikazioa prest dagoen probatzeko, ziurtatu ahalik eta merkeena dela. Har dezagun eskaera hau:

SELECT small_item FROM table LIMIT 1

Hona hemen bi balio hauek Kubernetesen nola konfiguratzen ditugun adibide bat:

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

Konfigurazio-aukera gehigarri batzuk gehi ditzakezu:

  • initialDelaySeconds β€” zenbat segundo igaroko diren edukiontzia abian jarri eta laginak hasten diren artean.
  • periodSeconds β€” Lagin-lanen arteko itxaron-tartea.
  • timeoutSeconds β€” Unitatea larrialditzat hartzen den segundo kopurua. Denbora-muga arrunta.
  • failureThreshold β€” Berrabiarazi seinalea podra bidali aurretik probaren hutsegite kopurua.
  • successThreshold β€” poda prest egoerara joan aurretik arrakasta duten zunda kopurua (huts baten ondoren, poda abiarazten edo berreskuratzen denean).

Hirugarren urratsa: sare-politika lehenetsiak konfiguratzea podarentzat

Kubernetes-ek sareko topografia "laua" du; lehenespenez, pod guztiak zuzenean komunikatzen dira elkarren artean. Zenbait kasutan hori ez da desiragarria.

Segurtasun-arazo potentzial bat da erasotzaile batek aplikazio zaurgarri bakarra erabil dezakeela sareko pod guztietara trafikoa bidaltzeko. Segurtasun arlo askotan bezala, pribilegio txikienaren printzipioa aplikatzen da hemen. Egokiena, sare-politikek berariaz zehaztu beharko lukete poden arteko zein konexio onartzen diren eta zein ez.

Adibidez, behean izen-espazio jakin baterako sarrerako trafiko guztia ukatzen duen politika sinple bat dago:

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

Konfigurazio honen bistaratzea:

Bost huts egin dira Kubernetesen lehen aplikazioa zabaltzean
(https://miro.medium.com/max/875/1*-eiVw43azgzYzyN1th7cZg.gif)
Xehetasun gehiago Hemen.

Laugarren urratsa: portaera pertsonalizatua kakoak eta init edukiontziak erabiliz

Gure helburu nagusietako bat Kubernetes-i inplementazioak eskaintzea zen garatzaileentzako geldialdirik gabe. Hau zaila da, aplikazioak ixteko eta erabiltzen zituzten baliabideak askatzeko aukera asko daudelako.

Zailtasun bereziak sortu ziren nginx. Konturatu ginen pods hauek sekuentzialki zabaltzen zirenean, konexio aktiboak ondo amaitu aurretik kentzen zirela.

Lineako ikerketa ugari egin ondoren, Kubernetes-ek ez duela itxaron Nginx-en konexioak agortu arte poda amaitu aurretik. Geldialdiaren aurreko kako bat erabiliz, funtzionalitate hau inplementatu dugu eta geldialdi-denbora erabat kendu dugu:

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

Baina 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

Beste paradigma oso erabilgarria da init edukiontzien erabilera aplikazio zehatzen abiarazteari aurre egiteko. Hau bereziki erabilgarria da aplikazioa hasi aurretik exekutatu behar den datu-baseen migrazio prozesu bat baduzu. Prozesu honetarako baliabide-muga handiagoa ere zehaztu dezakezu aplikazio nagusirako muga hori ezarri gabe.

Ohiko beste eskema bat da sekretuak atzitzea modulu nagusiari kredentzial horiek ematen dizkion init edukiontzi batean, eta horrek aplikazio-modulu nagusitik bertatik sekretuetara baimenik gabeko sarbidea eragozten du.

Ohi bezala, aipa ezazu dokumentaziotik: Init edukiontziak segurtasunez exekutatzen ditu aplikazioaren edukiontziaren irudiaren segurtasuna murriztuko luketen kode pertsonalizatua edo utilitateak. Behar ez diren tresnak bereizita mantenduz, aplikazioaren edukiontziaren irudiaren eraso-azalera mugatzen duzu.

Bost urratsa: Kernel-a konfiguratzea

Azkenik, hitz egin dezagun teknika aurreratuago bati buruz.

Kubernetes oso plataforma malgua da, lan-kargak egoki ikusten duzun moduan exekutatzeko aukera ematen dizuna. Errendimendu handiko aplikazio ugari ditugu, baliabideak oso intentsiboak dituztenak. Karga-proba zabalak egin ondoren, Kubernetes-en ezarpen lehenetsiak indarrean zeudenean aplikazio bat espero zen trafiko-karga kudeatzeko borrokan ari zela ikusi genuen.

Hala ere, Kubernetes-ek nukleoaren parametroak pod zehatz baterako soilik aldatzen dituen edukiontzi pribilegiatua exekutatzeko aukera ematen du. Hona hemen irekitako konexioen gehienezko kopurua aldatzeko erabili duguna:

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

Teknika aurreratuagoa da, askotan beharrezkoa ez dena. Baina zure aplikazioa karga astunari aurre egiteko zailtasunak baditu, ezarpen horietako batzuk doitzen saiatu zaitezke. Prozesu honi buruzko xehetasun gehiago eta balio desberdinak ezartzen - beti bezala dokumentazio ofizialean.

Ondorioz

Kubernetes prest dagoen irtenbide bat dirudien arren, zure aplikazioak ondo funtzionatzen jarraitzeko eman behar dituzun urrats gako batzuk daude.

Zure Kubernetes-en migrazio osoan, garrantzitsua da "karga-probaren zikloa" jarraitzea: abiarazi aplikazioa, kargatu probatu, behatu metrikak eta eskalatzeko portaera, egokitu konfigurazioa datu horietan oinarrituta, eta, ondoren, berriro errepikatu zikloa.

Izan errealistak espero duzun trafikoari buruz eta saiatu haratago bultzatzen zein osagai apurtzen diren lehen ikusteko. Ikuspegi iteratibo honekin, zerrendatutako gomendio batzuk baino ez dira nahikoa arrakasta lortzeko. Edo pertsonalizazio sakonagoa eskatzen du.

Egin beti zure buruari galdera hauek:

  1. Zenbat baliabide kontsumitzen dituzte aplikazioek eta nola aldatuko da bolumen hori?
  2. Zeintzuk dira benetako eskakizunak? Zenbat trafiko kudeatuko du aplikazioak batez beste? Zer gertatzen da trafiko gailurra?
  3. Zenbat aldiz eskalatu beharko da zerbitzua horizontalki? Zenbateko azkar jarri behar dira sare berriak sarean trafikoa jasotzeko?
  4. Nola ixten dira ondo lekak? Beharrezkoa al da hori? Posible al da geldialdirik gabe inplementatzea?
  5. Nola murriztu ditzakezu segurtasun-arriskuak eta kaltetutako edozein ontzien kalteak mugatu? Zerbitzurik ba al dute behar ez duten baimenik edo sarbiderik?

Kubernetes-ek plataforma ikaragarri bat eskaintzen du, kluster batean milaka zerbitzu zabaltzeko praktika onak aprobetxatzeko. Hala ere, aplikazio bakoitza desberdina da. Batzuetan ezarpenak lan pixka bat gehiago eskatzen du.

Zorionez, Kubernetes-ek helburu tekniko guztiak lortzeko beharrezko konfigurazioa eskaintzen du. Baliabide-eskaerak eta mugak, Liveness eta Readiness zundak, hasierako edukiontziak, sare-politikak eta nukleoaren sintonizazio pertsonalizatuak konbinatuta, errendimendu handia lor dezakezu akatsen tolerantziarekin eta eskalagarritasun azkarrarekin batera.

Zer gehiago irakurri:

  1. Produkzio-inguruneetan edukiontziak eta Kubernetes exekutatzeko jardunbide egokiak eta jardunbide egokiak.
  2. Kubernetesentzako 90 tresna erabilgarriak: hedapena, kudeaketa, monitorizazioa, segurtasuna eta gehiago.
  3. Gure kanala Around Kubernetes Telegram-en.

Iturria: www.habr.com

Gehitu iruzkin berria