Produkcijsko pripravljene slike za k8s

Ta zgodba govori o tem, kako uporabljamo kontejnerje v produkcijskem okolju, zlasti pod Kubernetesom. Članek je posvečen zbiranju metrik in logov iz kontejnerjev ter gradnji slik.

Produkcijsko pripravljene slike za k8s

Mi smo iz fintech podjetja Exness, ki razvija storitve za spletno trgovanje in fintech produkte za B2B in B2C. V našem R&D imamo več različnih ekip, v razvojnem oddelku pa imamo več kot 100 zaposlenih.

Predstavljamo ekipo, ki je odgovorna za platformo za zbiranje in izvajanje kode naših razvijalcev. Konkretno skrbimo za zbiranje, shranjevanje in zagotavljanje metrik, logov in dogodkov iz aplikacij. Trenutno upravljamo s približno tremi tisoč Docker kontejnerji v produkcijskem okolju, podpiramo naše big data skladišče s kapaciteto 50 Tb in zagotavljamo arhitekturne rešitve, ki temeljijo na naši infrastrukturi: Kubernetes, Rancher in različni javni cloud ponudniki. 

Naša motivacija

Kaj gori? Nihče ne more odgovoriti. Kje je žarišče? Težko je razumeti. Kdaj je zagorelo? To lahko ugotovimo, vendar ne takoj. 

Produkcijsko pripravljene slike za k8s

Zakaj so nekateri kontejnerji obstali, drugi pa padli? Kateri kontejner je za to kriv? Zunaj so kontejnerji enaki, znotraj pa ima vsak svoj Neo.

Produkcijsko pripravljene slike za k8s

Naši razvijalci so dobro usposobljeni. Ustvarjajo dobre storitve, ki podjetju prinašajo dobiček. A včasih pride do napak, ko se kontejnerji z aplikacijami neusklajeno obnašajo. En kontejner porabi preveč CPU, drugi omrežja, tretji vhodno-izhodnih operacij, četrti pa sploh ni jasno, kaj dela s soketi. Vse to pada in ladja se potaplja. 

Agenti

Da bi razumeli, kaj se dogaja znotraj, smo se odločili, da agenti delujejo neposredno v kontejnerjih.

Produkcijsko pripravljene slike za k8s

Ti agenti so zadržni programi, ki ohranjajo kontejnerje v takem stanju, da se med seboj ne uničijo. Agenti so standardizirani, kar omogoča standardiziran pristop k vzdrževanju kontejnerjev. 

V našem primeru morajo agenti zagotavljati loge v standardnem formatu, označene in s throttle-ingom. Prav tako morajo zagotavljati standardizirane metrike, ki so razširljive z vidika poslovnih aplikacij.

Pod agenti se prav tako razumejo orodja za operativno in vzdrževalno delo, ki znajo delovati v različnih sistemih orkestracije in podpirajo različne slike (Debian, Alpine, Centos itd.).

Nazad, agenti moraju podržavati jednostavan CI/CD, uključujući Docker datoteke. Inače, brod će se raspasti jer će se kontejneri isporučivati po 'krivim' prugama.

Proces izrade i struktura ciljnog image-a

Da bi sve bilo standardizirano i upravljivo, potrebno je pridržavati se nekog standardnog procesa izrade. Zato smo odlučili da izradimo kontejnere kao kontejnere — takva je ovde rekurzija.

Produkcijsko pripravljene slike za k8s

Ovdje su kontejneri prikazani kao neprekidne konture. Također, odlučili smo da stavimo distribucije u njih, da život ne bi izgledao kao malina. O tome zašto je to učinjeno, pričat ćemo u nastavku.
 
Kao rezultat, dobili smo alat za izradu — kontejner određene verzije koji se oslanja na određene verzije distribucija i određene verzije skripti.

Kako ga primenjujemo? Imamo Docker Hub u kojem se nalazi kontejner. Mirroriramo ga unutar našeg sistema kako bismo se oslobodili vanjskih zavisnosti. Dobio se kontejner žute boje. Kreiramo šablon kako bismo instalirali u kontejner sve potrebne distribucije i skripte. Nakon toga, izrađujemo image spreman za upotrebu: programeri stavljaju svoj kod i neke svoje posebne zavisnosti. 

Šta je dobro u ovom pristupu? 

  • Prvo, potpuna verzijska kontrola alata za izradu – kontejner izrade, verzije skripti i distribucija. 
  • Drugo, postigli smo standardizaciju: na isti način kreiramo šablone, međufazne i operativne image-e. 
  • Treće, kontejneri nam obezbjeđuju prenosivost. Danas koristimo Gitlab, a sutra ćemo preći na TeamCity ili Jenkins i isto tako ćemo moći pokretati naše kontejnere. 
  • Četvrto, minimizacija zavisnosti. Nismo slučajno stavili distribucije u kontejner, jer to omogućava da ih ne preuzimamo svaki put iz interneta. 
  • Peto, povećana brzina izrade – dostupnost lokalnih kopija image-a omogućava da ne trošimo vreme na preuzimanje, jer postoji lokalni image. 

Drugim rečima, postigli smo kontrolisani i fleksibilni proces izrade. Koristimo iste alate za izradu bilo kojih kontejnera sa potpunim verzioniranjem. 

Kako funkcioniše naš postupak izrade

Produkcijsko pripravljene slike za k8s

Zagon se začne z eno ukazno vrstico, postopek se izvede v sliki (označena z rdečo). Razvijalec ima Docker datoteko (označena z rumeno), ki jo upodobimo in zamenjamo spremenljivke z vrednostmi. Hkrati dodajamo headerje in footerje - to so naši agenti. 

Header dodaja distribucije iz ustreznih slik. Footer pa ustvari naše storitve, nastavi zagon obremenitve, beleženja in drugih agentov, spremeni entrypoint itd. 

Produkcijsko pripravljene slike za k8s

Dugo smo razmišljali, ali nam potrebujemo nadzornika. Na koncu smo se odločili, da ga potrebujemo. Izbrali smo S6. Nadzornik omogoča upravljanje kontejnerja: omogoča povezovanje v primeru padca glavnega procesa in zagotavlja ročno upravljanje kontejnerja brez njegove rekonstrukcije. Dnevniki in metrike so procesi, ki se izvajajo znotraj kontejnerja. Tudi njih je treba nekako nadzorovati, kar počnemo s pomočjo nadzornika. Nazadnje, S6 prevzame izvajanje upravljanja, obdelave signalov in drugih nalog.

Ker uporabljamo različne sisteme orkestracije, mora po sestavi in zagonu kontejner razumeti, v katerem okolju se nahaja, in delovati ustrezno. Na primer:
To nam omogoča, da zberemo eno sliko in jo zaženemo v različnih sistemih orkestracije, pri čemer se bo zagnala ob upoštevanju specifičnosti tega sistema orkestracije.

 Produkcijsko pripravljene slike za k8s

Za isti kontejner dobimo različna drevesa procesov v Dockerju in Kubernetesu:

Produkcijsko pripravljene slike za k8s

Obremenitev se izvaja pod nadzornikom S6. Opozorite na collector in events - to so naši agenti, odgovorni za dnevnike in metrike. V Kubernetesu jih ni, v Dockerju pa so. Zakaj? 

Če pogledamo specifikacijo 'poda' (tukaj in naprej - Kubernetes pod), bomo opazili, da kontejner events deluje v podu, kjer je ločen kontejner collector, ki izvaja funkcijo zbiranja metrik in dnevnikov. Izkoristimo lahko možnosti Kubernetes: zagon kontejnerjev v enem podu, v enotnem procesnem in/ali omrežnem prostoru. V bistvu vgrajujemo svoje agente in izvajamo nekatere funkcije. In če se ta isti kontejner zažene v Dockerju, bo prejel vse iste možnosti, to je lahko dostavil dnevnike in metrike, saj bodo agenti zagnani znotraj. 

Metrike in dnevniki

Dostava metrik in dnevnikov je zapletena naloga. Z njeno rešitvijo je povezano več vidikov.
Infrastruktura se gradi za izvršavanje korisnog opterećenja, a ne za masovno dostavljanje logova. Drugim rečima, ovaj proces treba da se izvršava uz minimalne zahteve za resurse kontejnera. Težimo da pomognemo našim programerima: „Uzmi Docker Hub kontejner, pokreni ga, i možemo dostaviti logove.“ 

Drugi aspekt - ograničenje obima logova. Kada se u više kontejnera pojavi situacija sa povećanjem obima logova (aplikacija u petlji ispisuje stack-trace), opterećenje na CPU-u, komunikacionim kanalima i sistemu za obradu logova raste, što utiče na rad hosta u celini i na druge kontejnere na hostu, što ponekad dovodi do „pada“ hosta. 

Treći aspekt - potrebno je podržati što više metoda za prikupljanje metrika od samog starta. Od čitanja datoteka i provere Prometheus-endpoint-a do korišćenja specifičnih aplikativnih protokola.

I poslednji aspekt - potrebno je minimizovati potrošnju resursa.

Odabrali smo open-source rešenje na Go-u pod nazivom Telegraf. To je univerzalni konektor koji podržava više od 140 vrsta ulaznih kanala (input plugins) i 30 vrsta izlaznih (output plugins). Doprinosili smo mu, a sada ćemo objasniti kako ga koristi naš tim na primeru Kubernetes-a. 

Produkcijsko pripravljene slike za k8s

Recimo, programer raspoređuje opterećenje, i Kubernetes prima zahtev za kreiranje poda. U tom trenutku za svaki pod automatski se kreira kontejner pod nazivom Collector (koristimo mutation webhook). Collector je naš agent. Na početku, ovaj kontejner se podešava za rad sa Prometheus-om i sistemom za prikupljanje logova.

  • Za to koristi anotacije poda, a u zavisnosti od njenog sadržaja, kreira, recimo, krajnju tačku end-point Prometheus; 
  • Na osnovu specifikacije poda i specifičnih podešavanja kontejnera odlučuje kako će se logovi dostavljati.

Logove prikupljamo putem Docker API-ja: programerima je dovoljno da ih postave u stdout ili stderr, a zatim će se Collector pobrinuti za njih. Logovi se prikupljaju u delovima s određenim kašnjenjem, kako bi se sprečila moguća preopterećenja hosta. 

Metričke podatke prikupljamo po instancama radnog opterećenja (procesima) u kontejnerima. Sve se označava tagovima: namespace, pod i tako dalje, a zatim se konvertuje u Prometheus format – i postaje dostupno za prikupljanje (osim logova). Takođe, logove, metrike i događaje šaljemo u Kafka i dalje:

  • Logovi su dostupni u Graylog-u (za vizuelnu analizu);
  • Dnevi, metrike in dogodki se pošljejo v Clickhouse za dolgoročno shranjevanje.

Tako kot vse deluje v AWS, pri čemer Graylog z Kafka nadomestimo s Cloudwatch. Tja pošiljamo dneve in vse postane zelo priročno: takoj je jasno, kateremu klastru in kontejnerju pripadajo. Enako velja za Google Stackdriver. Naša shema deluje tako on-premise z Kafka kot v oblakih. 

Če nimamo Kubernetes s podi, je shema nekoliko bolj zapletena, vendar deluje po istih načelih.

Produkcijsko pripravljene slike za k8s

Znotraj kontejnerja se izvajajo isti procesi, ki jih orkestriramo s pomočjo S6. Vsi ti isti procesi so zagnani znotraj enega kontejnerja.

Na koncu

Ustvarili smo celovito rešitev za gradnjo in zagon slik v proizvodnji, z možnostmi zbiranja in dostave dnevnikov in metrik:

  • Razvili smo standardiziran pristop k gradnji slik, na njegovi osnovi pa smo razvili CI predloge;
  • Agenti za zbiranje podatkov so naše razširitve Telegraf. Dobro smo jih testirali v proizvodnji;
  • Uporabljamo mutation webhook za vključevanje kontejnerjev z agenti v podih; 
  • Integrirali smo se v ekosistem Kubernetes/Rancher;
  • Lahko izvajamo enake kontejnerje v različnih sistemih orkestracije in dobimo pričakovane rezultate;
  • Ustvarili smo popolnoma dinamično konfiguracijo za upravljanje kontejnerjev. 

Sodisar: Ilja Prudnikov

Izvor: habr.com

Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki 🔥 Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki | ProHoster