27. mai DevOpsConf 2019 peamiseks saalis, mis toimub festivali raames , sektsioonis âJĂ€tkuv tarnimineâ kĂ”las ettekand âwerf â meie tööriist CI/CD jaoks Kubernetesesâ. Selles rÀÀgitakse nendest probleemidest ja vĂ€ljakutsetest, millega igaĂŒhel on silmitsi seista Kubernetesesse juurutamisel, samuti nĂŒanssidest, mis ei pruugi kohe silma torkata. Tutvustades vĂ”imalikke lahendusteid, nĂ€itame, kuidas see on rakendatud avatud lĂ€htekoodiga tööriistis .
Alates meie ettekandest on meie utiliit (varem tuntud kui dapp) ĂŒletanud ajaloolise piiri 1000 tĂ€hte GitHubis â loodame, et kasvav kasutajaskond teeb elu lihtsamaks paljudele DevOps-inseneridele.

Nii et tutvustame (~47 minutit, palju informatiivsem kui artikkel) ja selle peamisi kokkuvÔtteid tekstivormis. Alustame!
Koodi tarnimine Kubernetesesse
Ettekanne rÀÀgib enam mitte werf'ist, vaid CI/CD-st Kuberneteses, eeldades, et meie tarkvara on pakitud Docker-konteinernitesse (sellest rÀÀkisin ma ), ja K8s kasutatakse selle kĂ€itamiseks tootmises (sellest â ).
Kuidas nÀeb vÀlja tarnimine Kubernetesesse?
- On olemas Git-repositsioon koos koodiga ja juhistega selle kogumiseks. Rakendus kogutakse Docker-pildiks ja avaldatakse Docker Registry'sse.
- Samas repositooriumis on juhised ka selle kohta, kuidas rakendust juurutada ja kÀivitada. Juhtimise etapis saadetakse need juhised Kubernetes'esse, mis toob vajaliku pildi registrist ja kÀivitab selle.
- Lisaks on tavaliselt olemas testid. MÔningaid neist saab kÀivitada pildi avaldamise ajal. Samuti saab (sama juhiste abil) juurutada rakenduse koopia (erinevas K8s-nimruumis vÔi eraldi klastris) ja kÀivitada seal testid.
- LĂ”puks on vajalik CI-sĂŒsteem, mis saab sĂŒndmusi Git'ist (vĂ”i nupuvajutustest) ja kutsub vĂ€lja kĂ”ik mÀÀratud etapid: build, publish, deploy, test.

Siin on mÔned olulised mÀrkused:
- Kuna meil on muutumatu infrastruktuur (immutable infrastructure), peab rakenduse pilt, mida kasutatakse kĂ”igis etappides (staging, production jne), olema ĂŒhesugune.. Ăksikasjalikumalt sellest ja koos nĂ€idistega rÀÀkisin ma .
- Kuna me jĂ€rgime lĂ€henemist infrastruktuur kui kood (IaC), peab rakenduse kood, selle kogumise ja kĂ€ivitamise juhised olema just ĂŒhes repositooriumis.. Rohkem teavet selle kohta â vt .
- Tootmise ahel (tootmine) nĂ€eme tavaliselt nii: rakendus on kokku pandud, testitud ja vĂ€lja lastud (vabastamise etapp) ja kĂ”ik â tarnimine toimus. Kuid tegelikult saab kasutaja seda, mida te vĂ€lja lasite, ei just siis, kui te selle tootmisprotsessi tarnisite ja kui ta pÀÀses sellele juurde ja see tootmisprotsess töötas. SeetĂ”ttu arvan, et tootmise ahel lĂ”peb ainult tööetapis (töö), ja tĂ€psemalt, isegi hetkel, kui kood eemaldati tootmisest (asendades selle uuega).
Naaseme ĂŒlaltoodud Kubernetesâe tarnimise skeemi juurde: seda ei ole vĂ€lja mĂ”elnud ainult meie, vaid ka sisuliselt igaĂŒks, kes selle probleemiga tegeleb. Tegelikult nimetatakse seda mustrit nĂŒĂŒd GitOps (rohkem terminist ja ideedest, mis selle taga seisavad, saab lugeda )). Vaatame skeemi etappe.
Kogumise etapp
Tundub, et 2019. aastal vĂ”ib rÀÀkida Docker-piltide kogumisest, kui kĂ”ik oskavad kirjutada Dockerfileâe ja kĂ€ivitada docker build?.. ĐĐŸŃ ĐœŃĐ°ĐœŃŃ, ĐœĐ° ĐșĐŸŃĐŸŃŃĐ” Ń
ĐŸŃĐ”Đ»ĐŸŃŃ Đ±Ń ĐŸĐ±ŃаŃĐžŃŃ ĐČĐœĐžĐŒĐ°ĐœĐžĐ”:
- Pildi suurus on oluline, seega kasutage , et jÀtta pildile alles ainult tÔeliselt vajalik rakenduse tööks.
- Kihte tuleb minimeerida, ĂŒhendades
RUN-kÀsku loogiliselt. - Kuid see toob kaasa probleeme silumiseks, kuna ehituse kokkuvarisemisel tuleb leida see Ôige kÀsk jÀrjekorrast, mis probleemi pÔhjustas.
- Kogumise kiirus on oluline, kuna soovime kiiresti muudatusi ellu viia ja nende tulemusi jÀlgida. NÀiteks ei taha ma iga rakenduse kogumise korral keeltes esinevaid sÔltuvusi uuesti koguda.
- Sageli vajatakse ĂŒhest Git-repositooriumist palju pilte, mida saab lahendada Dockerfileâide komplekti (vĂ”i nimetatud etappidega ĂŒhes failis) ja Bash-skripti abil nende jĂ€rjestikuseks kogumiseks.
See oli vaid jÀÀmÀe tipp, millega kÔik silmitsi seisavad. Kuid on ka teisi probleeme, sealhulgas:
- Sageli on meil ehitusetapis vaja midagi mountida (nt. apt kÀskluse tulemuse vahemÀlu salvestamiseks vÀlisesse kataloogi).
- Soovime Ansible ebaefektiivse shell'i asemel.
- Soovime kogu ilma Dockerita (miks peaks olema tÀiendav virtuaalmasin, kuhu tuleb see kÔik seadistada, kui meil on juba Kubernetes'i klaster, kus konteinerit jooksutada?).
- Paralleelne koostamine, mida vĂ”ib tĂ”lgendada erinevalt: erinevad kĂ€sud Dockerfileâis (kui kasutatakse multi-stage), mitu commit'i ĂŒhes repozitoriumis, mitu Dockerfile'i.
- Jaotatud ehitamine: soovime ehitada midagi podâides, mis on âefemiirilisedâ, kuna neil kaob vahemĂ€lu, seega â see tuleb kuskil eraldi salvestada.
- LĂ”puks, oma soovide tippu nimetasin automaagiks: oleks ideaalne siseneda repozitoriumi, sisestada mĂ”ni kĂ€sk ja saada valmis pilt, koostatud arusaamisega, kuidas ja mida Ă”igesti teha. Kuigi ma isiklikult ei ole kindel, et kĂ”ik nĂŒansid on vĂ”imalik ette nĂ€ha.
Ja siin on projektid:
- â ehitaja Docker Inc.âilt (juba integreeritud uusimatesse Docker'i versioonidesse), mis pĂŒĂŒab lahendada kĂ”iki neid probleeme;
- â Google'i ehitaja, mis vĂ”imaldab ehitamist ilma Dockerita;
- â CNCF katse teha automaagia ja eriti huvitav lahendus rebase'iga kihtide jaoks;
- ja veel hunnik muid utiliite, nagu , âŠ
⊠ja vaadake, kui palju neil on tĂ€hti GitHub'is. See tĂ€hendab, et ĂŒhelt poolt docker build on midagi olemas ja see vĂ”ib midagi teha, kuid tegelikult kĂŒsimus ei ole lĂ”puni lahendatud â selle tĂ”estuseks on alternatiivsete kogujate paralleelne areng, millest igaĂŒhel on oma osa probleemide lahendamisel.
Kogumine werfis
Nii jĂ”udsime (varem nagu dapp) â Open Source tööriist, mille on vĂ€lja töötanud ettevĂ”te âFlantâ, millega oleme tegelenud juba aastaid. KĂ”ik algas viis aastat tagasi Bash-skriptidega, mis optimeerisid Dockerfileâide kogumist, ja viimased kolm aastat on toimunud tĂ€ieĂ”iguslik arendus ĂŒhe projekti raames oma Git-repositooriumiga. (esialgu Rubyâs, seejĂ€rel Goâs, ja samal ajal ka ĂŒmber nimetatud). Millised kogumise kĂŒsimused on werfis lahendatud?

Sinisega rĂ”hutatud probleemid on juba lahendatud, paralleelne kogumine on teostatud ĂŒhe hosti raames, ning kollaselt esile tĂ”stetud kĂŒsimusi plaanime lĂ”pule viia suve lĂ”puks.
Avaldamise staadium registryâs (publish)
Oleme kogunud docker push⊠â mis vĂ”ib olla keerulist pildi ĂŒleslaadimises registryâs? Ja siis tekib kĂŒsimus: âMillise sildi peaks pildile panema?â See tekib sellest, et meil on Gitflow (vĂ”i mĂ”ni muu Git strateegia) ja Kubernetes, ning tööstus pĂŒĂŒdleb selle poole, et Kuberneteses toimuv jĂ€rgiks seda, mis toimub Gitâis. LĂ”ppude lĂ”puks on Git meie ainus tĂ”eallikas.
Mis selles nii keerulist on? Kordineeritavuse tagamine: alates Git'i commit'ist, mis on oma olemuselt muutumatu (muutumatu), kuni Docker'i pildini, mis peab jÀÀma samaks.
Meile on samuti oluline tuvastada pÀritolu, sest me tahame mÔista, millisest commit'ist on loodud rakendus, mis töötab Kuberneteses (siis saame teha diff'e ja sarnaseid asju).
Siltimistaktikad
Esimene â see on lihtne git tag. Meil on registry pildiga, mis on sildistatud kui 1.0. Kuberneteses on etapp ja tootmine, kuhu see pilt on vĂ€lja tĂ”mmatud. Git'is teeme commit'e ja mingil hetkel mÀÀrame sildi 2.0. Kogume selle vastavalt repole ja paigutame registry'sse sildiga 2.0. Rakendame etapis ja, kui kĂ”ik lĂ€heb hĂ€sti, siis tootmisse.

Selle lÀhenemisviisi probleem on see, et me mÀÀrasime esmalt sildi, ja alles siis testisime ja rakendasime. Miks? Esiteks on see lihtsalt ebaoluline: me vÀljastame versiooni tarkvarast, mida pole isegi kontrollitud (me ei saa teisiti, kuna kontrollimiseks on vajalik silt paigaldada). Teiseks, see tee ei sobi Gitflow'ga.
Teine variant â git commit + tag. Master harul on silt 1.0; tema jaoks registry's â pilt, mis on juurutatud tootmisesse. Lisaks on Kubernetes-klastris preview ja staging kontuurid. JĂ€tkame Gitflow'd: arenduspeamises (develop) loome uusi funktsioone, mille tulemuseks on kohalik commit, mille identifikaator on #c1. Me kogume selle kokku ja avaldame registry'sse, kasutades seda identifikaatorit (#c1). Sellega sama identifikaatoriga viime lĂ€bi preview'e. Sarnasel viisil tegutseme commitidega #c2 ja #c3.
Kui oleme aru saanud, et funktsioon on piisav, hakkame kÔike stabiliseerima. Git'is loome haru release_1.1 (baasil #c3 kohast develop). Selle versiooni kogumine ei ole vajalik, kuna see on tehtud eelneval etapil. SeetÔttu saame lihtsalt selle staging'isse viia. Parandame vead #c4 ja viime sarnasel viisil staging'isse. Samal ajal kÀib arendus develop, kuhu vaheldumisi tuuakse muudatusi release_1.1. Mingil hetkel saame kokku pandud ja staging'isse viidud commit', millega oleme rahul (#c25).
Siis teeme merge (fast-forwardiga) versiooni haru (release_1.1) masterisse. Paneme selle commit'i kĂŒlge uue versiooni sildi (1.1). Kuid see pilt on juba kogutud registry's, seega, et mitte uuesti seda koguda, lisame lihtsalt teise sildi olemasolevale pildile (nĂŒĂŒd on tal registry's sildid #c25 ja 1.1). PĂ€rast seda lĂ€hetame selle tootmisse.
On puudus, et staging'is on laetud ĂŒks pilt (#c25), kuid tootmises on nagu teine (1.1), kuid me teame, et âfĂŒĂŒsiliseltâ on see sama pilt registrist.

Tegelikkuses on puuduseks see, et merge commitâde tugi puudub, peame tegema fast-forward.
Saame minna edasi ja teha triki⊠Vaatame lihtsa Dockerfileâi nĂ€idet:
FROM ruby:2.3 as assets
RUN mkdir -p /app
WORKDIR /app
COPY . ./
RUN gem install bundler && bundle install
RUN bundle exec rake assets:precompile
CMD bundle exec puma -C config/puma.rb
FROM nginx:alpine
COPY --from=assets /app/public /usr/share/nginx/www/publicLoome sellest faili sellise printsiibi alusel, et vÔtame:
- SHA256 kasutatavate piltide identifikaatoritest (
ruby:2.3janginx:alpine), mis on nende sisu kontrollsummad; - kÔik kÀsud (
RUN,CMDjne); - SHA256 failidest, mis on lisatud.
⊠ja vÔtame uuesti kontrollsummana (SHA256) sellise faili. See allkiri kÔigest, mis mÀÀrab Docker-pildi sisu.

Naaseme skeemi juurde ja kasutame selliste allkirjade asemel commitâe,st. mĂ€rgistame pildid allkirjadega.

NĂŒĂŒd, kui nĂ€iteks on tarvis âmergeâida muudatused vĂ€ljaandest masterisse, saame teha tĂ”elise merge commit'i: sellel on erinev identifikaator, kuid sama allkiri. Sama identifikaatoriga viime vĂ€lja ka pildi tootmisse.
Puuduseks on see, et nĂŒĂŒd ei ole vĂ”imalik mÀÀrata, mis commit on tootmisse viidud â kontrollsummad toimivad ainult ĂŒhes suunas. See probleem lahendatakse tĂ€iendava metadata kihiga â rÀÀgin sellest lĂ€hemalt hiljem.
MĂ€rgistamine werf'is
werf'is oleme lĂ€inud veelgi kaugemale ning valmistume nendele, kes ei hoia oma cache'i ĂŒhel masinal, jaotatud ehitamiseks... Nii et meil on kahe tĂŒĂŒpi Docker'i pildid, mida nimetame etapi ja pilt.
Git'i hoidlas werf on sÀilitatud spetsiifilised juhised ehitamiseks, mis kirjeldavad erinevaid ehitusetappe (beforeInstall, install, beforeSetup, setup). Esimene stage- pildistame kogume signatuuriga, mis on mÀÀratletud kui esimeste sammude kontrollsummana. SeejÀrel lisame lÀhtekoodi, uue stage-pildi jaoks arvutame ka selle kontrollsummat⊠Need toimingud korratakse kÔigi etappide jaoks, mille tulemuseks on set stage-pilte. Siis loome lÔpliku image-pildi, mis sisaldab ka tema pÀritolu metaandmeid. Ja just seda pilti me mÀrgistame erinevate viisidega (detailid hiljem).

Oletame, et pÀrast seda ilmub uus commit, kus on muudetud ainult rakenduse koodi. Mida juhtub? Koodi muudatuste jaoks luuakse patch, valmistatakse ette uus stage-pilt. Selle signatuur mÀÀratakse kui vana stage-pildi ja uue patƥi kontrollsumma. Sellest pildist kujundatakse uus lÔplik image-pilt. Sarnane kÀitumine toimub ka teistel etappidel.
Seega, stage-pildid on cache, mida saab hoida hajutatult, ning neist loodud image-pildid laaditakse Docker Registry'sse.

Registry puhastamine
Jutt on siiski pigem nende Docker'i siltide eemaldamisest, mis on jÀÀnud rippuma pĂ€rast eemaldatud silte â see on Docker Registry standardne funktsioon. TĂ”eliselt rÀÀgime olukorrast, kus koguneb palju Docker'i silte ja me mĂ”istame, et osa neist pole enam vajalik, kuid nad vĂ”tavad ruumi (ja/vĂ”i maksame selle eest).
Millised on puhastamise strateegiad?
- VÔib lihtsalt mitte midagi teha puhastada. MÔnikord on tÔesti lihtsam veidi maksta liigse ruumi eest, kui proovida lahti harutada tohutut silti. Kuid see toimib ainult teatud hetkeni.
- TĂ€ielik lĂ€htestamine. Kui kustutada kĂ”ik pildid ja koostada ainult ajakohased CI-sĂŒsteemis, vĂ”ib tekkida probleem. Kui tootmises konteiner kĂ€ivitub, laaditakse sellele uus pilt â selline, mida pole keegi testinud. See hĂ€vitab immutable infrastructure idee.
- Sinine-roheline. Kui ĂŒks registri hakkab ĂŒle voolama â laadige pildid teise. Sama probleem, mis eelmisel meetodil: millal on vĂ”imalik puhastada see registreerimine, mis hakkas ĂŒle voolama?
- Aja jÀrgi. Kustutada kÔik pildid, mis on vanemad kui 1 kuu? Kuid kindlasti on teenus, mis ei ole kuus uuendatud...
- KÀsitsi mÀÀratle, mida vÔib juba eemaldada.
TĂ”eliselt toimivaid variante on kaks: mitte puhastada vĂ”i kasutada blue-green kombinatsiooni koos kĂ€sitsi puhastamisega. Viimases juhul tĂ€hendab see jĂ€rgmist: kui saad aru, et on aeg registrit puhastada, lood uue ja lisad kĂ”ik uued pildid sellesse, nĂ€iteks kuu aja jooksul. Ja kuu pĂ€rast vaatad, millised pod'id Kuberneteses kasutavad endiselt vana registrit ning kannad need ka uude registrisse ĂŒle.
Kuhu me jĂ”udsime werf? ĐŃ ŃĐŸĐ±ĐžŃĐ°Đ”ĐŒ:
- Git head: kĂ”ik sildid, kĂ”ik harud â eeldades, et kĂ”ik, mis on Git'is sildistatud, on vajalik ka piltides (ja kui ei, siis tuleb need Git'is eemaldada);
- kÔik pod'id, mis on praegu Kuberneteses vÀlja toimetatud;
- vanad ReplicaSet'id (need, mis on hiljuti vÀlja toimetatud), samuti plaanime skaneerida Helm'i vÀljalasked ja vÀlja valida viimased pildid seal.
⊠ja teeme sellest komplektist whitelist'i â nimekiri piltidest, mida me ei eemalda. KĂ”ik muu puhastame, pĂ€rast mida otsime ĂŒles orvud staatilised pildid ja eemaldame need ka.
Deploy-etapp
UsaldusvÀÀrne deklaratiivsuse tase
Esimene asi, millele tahaks tĂ€helepanu pöörata deploos, on uue ressursik ĐșĐŸĐœŃОгŃŃаatia vĂ€ljaandmine, mis on deklareeritud. Originaalne YAML-dokument Kubernetes-ressursside kirjeldamisega erineb alati oluliselt (tulemusest), mis tegelikult klastris töötab. Sest Kubernetes lisab konfiguratsioonile:
- tuvastajad;
- teenuste teavet;
- mitmeid vaikeseade vÀÀrtusi;
- osa praeguse oleku kohta;
- muudatused, mis on tehtud admission webhooki töö kÀigus;
- eraldi juhtide (ja planeerija) töö tulemuse.
SeetĂ”ttu, kui ilmub uus ressursi konfiguratsioon (uus), ei saa me lihtsalt vĂ”tta ja kirjutada selle ĂŒle praegust, "elavat" konfiguratsiooni (live). Selleks peame me vĂ”rreldama uus eelmise rakendatud konfiguratsiooniga (last-applied) ja rakendama live saadud patĆĄi.
Seda lÀhenemist nimetatakse 2-way merge. Seda kasutatakse nÀiteks Helm'is.
On ka 3-way merge, mis erineb selle poolest, et:
- vÔrreldes last-applied ja uus, vaatame, mis on eemaldatud;
- vÔrreldes uus ja live, vaatame, mis on lisatud vÔi muudetud;
- kumulatiivse patĆĄi rakendame live.
Deployime ĂŒle 1000 rakenduse Helmiga, nii et tegelikult elame 2-way merge'i kaudu. Kuid sellel on mitmeid probleeme, mille oleme lahendanud oma patchâidega, et aidata Helm'il normaalselt töötada.
TÔeline vÀljalaske staatus
PĂ€rast seda, kui meie CI-sĂŒsteem on jĂ€rjekordse sĂŒndmuse tĂ”ttu genereerinud uue konfiguratsiooni Kubernetes'e jaoks, edastab see selle rakendamiseks (rakenda) klastrisse â kasutades Helm'i vĂ”i kubectl apply. SeejĂ€rel toimub juba kirjeldatud N-way merge, milles Kubernetes API kiidab heaks CI-sĂŒsteemi, ning see omakorda oma kasutaja.

Kuid probleem on suur: nimelt edukas rakendamine ei tĂ€henda eduka vĂ€ljalaskmist.Kui Kubernetes mĂ”istab, milliseid muudatusi tuleb rakendada, siis rakendab selle â me ei tea veel, milline on lĂ”pptulemus. NĂ€iteks frontendis vĂ”ib uuendus ja pod'ide taaskĂ€ivitamine Ă”nnestuda, samas kui backendis see ei Ă”nnestu ning saame rakenduse erinevad versioonid.
Ăige tegemiseks on selles skeemis tarvis lisasilda â spetsiaalset jĂ€lgijat, mis saaks Kubernetes API-lt teavet staatuse kohta ja edastada selle edasiseks analĂŒĂŒsimiseks tegeliku seisundi osas. Oleme loonud Open Source'i teegi Go-s â (vt selle teadaanne ), â mis lahendab selle probleemi ja on integreeritud werf-i.
Selle jĂ€lgija kĂ€itumist werf-i tasandil configureerimine toimub annotatsioonide abil, mis paigutatakse Deployment'itele vĂ”i StatefulSets'ile. Peamine annotatsioon on fail-mode â mĂ”istab jĂ€rgmisi vÀÀrtusi:
-
IgnoreAndContinueDeployProcessâ ignoreerime selle komponendi vĂ€ljalaskmisel esinevaid probleeme ja jĂ€tkame juurutamist; -
FailWholeDeployProcessImmediatelyâ selle komponendi viga peatab juurutamisprotsessi; -
HopeUntilEndOfDeployProcessâ loodame, et see komponent töötab juurutamise lĂ”puks.
NÀiteks selline kombinatsioon ressurssidest ja annotatsiooni vÀÀrtustest fail-mode:

Kui juurutame esmakordselt, vĂ”ib andmebaas (MongoDB) olla veel valmis â Deployment'id kukuvad. Kuid vĂ”ime oodata aega, kuni see kĂ€ivitub, ja juurutamine möödub siiski.
Werfil on veel kaks annotatsiooni kubedogi jaoks:
-
failures-allowed-per-replicaâ lubatud kukkumiste arv iga replikatsiooni kohta; -
show-logs-untilâ reguleerib hetke, kuni werf nĂ€itab (stdout-is) logisid kĂ”igilt juurutatavatelt pod'idelt. Vaikimisi on seePodIsReady(et ignoreerida teateid, mis meile tĂ”enĂ€oliselt ei ole vajalikud, kui pod'ile hakkab liiklus tulema), kuid lubatud on ka vÀÀrtusedControllerIsReadyjaEndOfDeploy.
Mida veel soovime juurutamiselt?
Lisaks juba kirjeldatud kahele punktile soovime:
- nĂ€ha logisid â ning ainult vajalikke, mitte kĂ”iki jĂ€rjestikku;
- jĂ€lgida edusamme, kuna kui töö âvaikseltâ seiskub minutiteks, on oluline mĂ”ista, mis seal toimub;
- omada automaatset tagasipöördumist juhtumiteks, kui midagi lÀheb valesti (seetÔttu on kriitiliselt oluline teada tÔelist staatust). KÀivitamine peab olema atomaarne: kas see toimub lÔpuni vÔi kÔik naaseb eelnevasse olekusse.
KokkuvÔte
Meie ettevĂ”ttele on nende kĂ”igi aspektide teostamiseks tarnimise eri etappides (build, publish, deploy) piisav CI-sĂŒsteem ja tööriist .
KokkuvÔtteks:

TÀnu werfile oleme suutnud hÀsti edasi liikuda paljusid DevOps-inseneride probleeme lahendada ja oleme rÔÔmsad, kui laiem kogukond vÀhemalt proovib seda tööriista. Hea tulemuse saavutamine koos on lihtsam.
Video ja slaidid
Video ettekandest (~47 minutit):

Ettekande esitlus:
P.S.
Teised ettekanded Kubernetesest meie blogis:
- «» (Dmitri Stoljarov; 27. aprill 2019 «Stachkis»);
- «» (Andrei Polovov; 8. aprill 2019 Saint HighLoad++);
- «» (Dmitri Stolyarov; 8. november 2018 HighLoad++);
- «» (Dmitri Stolyarov; 28. mai 2018 RootConf'is);
- «» (Dmitri Stolyarov; 7. november 2017 HighLoad++);
- «» (Dmitri Stolyarov; 6. juuni 2017 RootConf'il).
Allikas: habr.com
