Postgres-marți nr. 5: „PostgreSQL și Kubernetes. CI/CD. Automatizarea testării”

Postgres-marți nr. 5: „PostgreSQL și Kubernetes. CI/CD. Automatizarea testării”

La sfârșitul anului trecut a avut loc un alt live stream al comunității rusești PostgreSQL #RuPostgres, în cadrul căruia co-fondatorul său, Nikolai Samohvalov, a discutat cu directorul tehnic al 'Flanta', Dmitry Stolyarov, despre această SGBD în contextul Kubernetes.

Publicăm transcrierea părții principale a acestei discuții, iar pe canalul de YouTube al comunității a fost publicat înregistrarea video completă:

Redați video

Baze de date și Kubernetes

NS: Astăzi nu vom vorbi despre VACUUM și CHECKPOINT-uri. Vrem să discutăm despre Kubernetes. Știu că ai deja mulți ani de experiență. Am văzut videoclipurile tale și chiar am revăzut unele. Hai să începem direct: de ce avem nevoie de Postgres sau MySQL în K8s?

DS: Nu există un răspuns definitiv la această întrebare și nu poate exista. Dar, în general, este vorba despre simplitate și confort… potențiale. Toată lumea vrea servicii gestionate.

NS: Ca RDS, dar la tine acasă?

DS: Da: ca RDS, dar oriunde.

NS: 'Oriunde' — acesta este un comentariu bun. În companiile mari, totul este situat în locuri diferite. De ce, atunci, dacă este o companie mare, să nu alegem o soluție gata făcută? De exemplu, Nutanix are propriile sale dezvoltări, iar alte companii (VMware…) — același 'RDS, dar la tine acasă'.

DS: Dar vorbim despre o implementare specifică, care va funcționa doar în anumite condiții. Dacă discutăm despre Kubernetes, aici există o varietate imensă de infrastructură (care poate fi în K8s). Practic, acesta este standardul pentru API-uri către cloud...

NS: Și este gratuit!

DS: Nu este atât de important. Gratuitatea este importantă pentru un segment nu foarte mare al pieței. Ceea ce contează cu adevărat… Probabil că îți amintești prezentarea 'Baze de date și Kubernetes»?

NS: Da.

DS: Am realizat că a fost percepută foarte ambiguu. O parte dintre oameni au crezut că spun: 'Băieți, haideți să mutăm toate Bazele de Date în Kubernetes!', iar alții au decis că sunt niște bicicleta rău intenționate. Dar eu voiam de fapt să spun altceva: 'Uitați ce se întâmplă, ce probleme sunt și cum pot fi rezolvate. Să ducem bazele de date în Kubernetes? Producție? Numai dacă îți place să… te ocupi de anumite lucruri. Dar pentru dev… pot spune că recomand. Pentru dev este foarte importantă dinamica în crearea/ștergerea mediilor'.

NS: Prin dev te referi la toate mediile care nu sunt prod? Staging, QA…

DS: Dacă vorbim despre standuri perf, atunci probabil că nu, pentru că cerințele sunt specifice. Dacă vorbim despre cazuri speciale în care pe staging este necesară o bază de date foarte mare, atunci de asemenea, probabil că nu… Dacă este un mediu static, de lungă durată, care este beneficiul ca baza să fie plasată în K8s?

NS: Niciunul. Dar unde vedem medii statice? Mediile statice sunt deja depășite de mâine.

DS: Staging-ul poate fi static. Avem clienți…

NS: Da, am și eu. E o mare problemă dacă ai o bază de 10 TB, iar staging-ul — 200 GB…

DS: Am un caz foarte interesant! Pe staging se află baza de producție, în care se fac modificări. Și există un buton: „deploy în producție”. Aceste modificări — delta — sunt integrate (se pare că simplu prin API se sincronizează) în producție. Este o variantă foarte exotică.

NS: Am văzut startup-uri în Valea Siliciului care sunt în RDS sau chiar în Heroku încă — acestea sunt povești de acum 2-3 ani, — și ele descarcă un dump pe laptopul lor. Deoarece baza este doar de 80 GB, iar pe laptop mai există loc. Apoi cumpără discuri pentru fiecare, pentru a avea câte 3 baze, pentru a desfășura dezvoltări diferite. Așa se întâmplă și asta. De asemenea, am văzut că nu le este frică să copieze producția în staging — foarte mult depinde de companie. Dar am văzut și că le este foarte frică, și că adesea lipsește timpul și oamenii. Dar înainte să trecem la acest subiect, vreau să aud despre Kubernetes. Am înțeles corect că în producție nu are nimeni încă?

DS: Avem baze mici în producție. Vorbim despre volume de zeci de gigabyte și servicii necritice, pentru care era lene să facem replici (și nici nu a fost o necesitate). Și cu condiția că sub Kubernetes există un stocaj normal. Această bază a funcționat pe o mașină virtuală — adică în VMware, deasupra unui sistem de stocare. Am plasat-o în PV și acum o putem muta de pe mașină pe mașină.

NS: Baze de această dimensiune, de până la 100 GB, pe discuri bune și cu o rețea bună pot fi desfășurate în câteva minute, corect? Viteza de 1 GB pe secundă — asta nu mai este o excentricitate.

DS: Da, pentru o operație lineară nu este o problemă.

NS: Ok, despre producție ar trebui să ne gândim doar. Și dacă luăm în considerare Kubernetes pentru medii non-prod — cum procedăm? Văd că în Zalando fac un operator, în Crunchy se dezvoltă, există și alte variante. Și există OnGres — acesta este prietenul nostru bun Alvaro din Spania: ei fac de fapt nu doar operator, ci un întreg distribuibil (StackGres), în care, pe lângă Postgres în sine, au decis să includă și backup-ul, proxy-ul Envoy...

DS: Envoy pentru ce? Încărcarea traficului Postgres?

NS: Da. Asta înseamnă că ei văd astfel: dacă luăm un sistem de operare Linux și nucleul, PostgreSQL obișnuit este nucleul, iar ei vor să creeze un sistem de operare care să fie prietenos cu norul și să funcționeze în Kubernetes. Asamblează componente (backup-uri etc.) și le reglează pentru a funcționa bine.

DS: Foarte bine! Practic, acest software este pentru a crea un Postgres gestionat.

NS: Distribuțiile Linux au tot timpul probleme: cum să creeze driver-e pentru a suporta tot hardware-ul. Iar ei au ideea că vor funcționa în Kubernetes. Știu că la operatorul Zalando am văzut recent o legătură cu AWS și asta nu este deloc bine. Nu ar trebui să existe o legătură cu o infrastructură specifică — care ar fi atunci sensul?

DS: Nu știu în ce situație s-a legat Zalando, dar în Kubernetes acum, stocarea este făcută astfel încât nu poți face backup de disc într-un mod generic. Recent, în standardul — în ultima versiune specificației CSI — au făcut posibilitatea instantaneelor, dar unde este implementată? Sincer, totul este atât de incipient… Încercăm CSI peste AWS, GCE, Azure, vSphere, dar când începi să folosești, devine evident că nu este pregătit.

NS: De aceea trebuie uneori să ne legăm de infrastructură. Cred că suntem încă în faza incipientă — probleme de creștere. Întrebare: ce ai sfătui pe cei începători care vor să încerce PgSQL în K8s? Ce operator, poate?

DS: Problema este că Postgres pentru noi înseamnă 3%. Mai avem o listă foarte mare de software diferit în Kubernetes, nu voi enumera tot. De exemplu, Elasticsearch. Sunt o mulțime de operatori: unii se dezvoltă activ, alții — nu. Am stabilit cerințe pentru noi ce ar trebui să aibă un operator, pentru a fi luați în serios. Un operator în special pentru Kubernetes — nu în „operatorul pentru a face ceva în condițiile Amazon”... De fapt, folosim destul de mult (= aproape toți clienții) un singur operator — pentru Redis (vom publica în curând un articol și despre acesta).

NS: Dar pentru MySQL nu există? Știu că Percona… deoarece acum se ocupă atât de MySQL, cât și de MongoDB și Postgres, ar trebui să creeze un sistem universal: pentru toate bazele de date, pentru toți furnizorii de cloud.

DS: Nu am avut timp să ne uităm la operatorii pentru MySQL. Pentru noi, acest lucru nu este un focus principal acum. MySQL funcționează bine în mod standalone. De ce un operator, dacă poți pur și simplu să lansezi DB… Poți lansa un container Docker cu Postgres, sau poți să-l lansezi simplu.

NS: A fost, de asemenea, o întrebare despre asta. Chiar fără operator?

DS: Da, în 100% din cazuri avem PostgreSQL lansat fără operator. Așa stau lucrurile deocamdată. Folosim activ operatorul pentru Prometheus, pentru Redis. Avem în plan să găsim un operator pentru Elasticsearch - acesta ne

este cel mai urgent

NS: Hai să trecem la subiectul testării. Cum să implementăm modificările în bază - din perspectiva DevOps. Există microservicii, multe baze, tot timpul se schimbă câte ceva. Cum asigurăm un CI/CD normal, astfel încât din perspectiva SGBD-ului totul să fie în regulă. Care este abordarea ta?

DS: Nu poate exista un singur răspuns. Există mai mulți parametri. Primul - este dimensiunea bazei pe care dorim să o implementăm. Ai menționat tu însuți că în companii se abordează diferit ideea ca copia bazei prod să fie pe dev și stage.

NS: Și în condițiile GDPR, cred că sunt din ce în ce mai atenți... Pot spune că în Europa au început deja să impună amenzi.

DS: Dar adesea poți scrie software care face un dump din producție și îl obfuschează. Obții date prod (snapshot, dump, copie binară...), dar acestea sunt anonimizate. În locul acestora pot exista și scripturi de generare: pot fi fixture sau pur și simplu un script care generează o bază mare. Problema este: cât timp durează să creezi imaginea de bază? Și cât timp durează să o desfășori în mediu necesar?

Am ajuns la schema: dacă clientul are un set de date fixture (versiunea minimă a bazei), atunci folosim acestea implicit. Dacă este vorba despre medii de review, când am creat o ramură, ne-a fost desfășurat un exemplarul aplicației - aici desfășurăm o bază mică. o variantă, când facem un dump de producție o dată pe zi (noaptea) și construim pe baza acestuia un container Docker cu PostgreSQL și MySQL cu aceste date încărcate. Dacă din această imagine trebuie să desfășurăm baza de date de 50 de ori, se face destul de simplu și rapid.

NS: Printr-o simplă copiere?

DS: Datele sunt stocate direct în imaginea Docker. Adică avem o imagine gata, să presupunem de 100 GB. Datorită straturilor din Docker, putem desfășura rapid această imagine de atâtea ori cât avem nevoie. Metoda este simplă, dar funcționează destul de bine.

NS: Ulterior, atunci când testezi, se schimbă direct în interiorul Docker-ului, da? Copy-on-write în interiorul Docker-ului — eliminăm și reluăm, totul este bine. Grozav! Și deja folosiți asta pe scară largă?

DS: De mult.

NS: Ne ocupăm de lucruri foarte asemănătoare. Numai că noi nu folosim copy-on-write din Docker, ci altceva.

DS: Nu este generic. Dar cel din Docker funcționează pe scară largă.

NS: În teorie, da. Dar avem și module, putem face diverse module și lucra cu diferite sisteme de fișiere. Aici este un aspect. Privim diferit din perspectiva Postgres-ului la tot acest proces. Acum am văzut din perspectiva Docker-ului și am observat că la voi totul funcționează. Dar dacă baza de date este uriașă, să zicem de 1 TB, atunci totul devine lent: și operațiile nocturne, și încărcarea în Docker… Dar dacă trebuie să încarcăm 5 TB în Docker… Sau totul este în regulă?

DS: Ce diferență face: sunt doar bloburi, pur și simplu biți și octeți.

NS: Diferența este aceasta: faceți asta prin dump și restore?

DS: Deloc obligatoriu. Metodele de generare a acestei imagini pot fi diferite.

NS: Pentru unii clienți am realizat că, în loc să generăm regulat o imagine de bază, o menținem constant actualizată. Practic, este o replică, dar datele nu le primim direct de la master, ci prin arhivă. O arhivă binară, în care WAL-urile sunt adăugate zilnic, și care, de asemenea, conține backup-uri... Aceste WAL-uri ajung apoi — cu o întârziere mică (literal 1-2 secunde) — la imaginea de bază. De pe aceasta clonăm prin orice metodă — acum, implicit, avem ZFS.

DS: Dar cu ZFS ești restricționat la un singur nod.

NS: Da. Dar ZFS are și o magie send: cu care poți trimite un snapshot și chiar (asta nu am testat foarte mult, dar...) poți trimite delta între două PGDATA. De fapt, avem și un alt instrument pe care nu l-am considerat foarte mult pentru astfel de sarcini. În PostgreSQL există pg_rewind, care funcționează ca un rsync „inteligent”, omite multe lucruri care nu trebuie verificate, pentru că acolo clar nu s-au făcut modificări. Putem realiza o sincronizare rapidă între două servere și putem reveni la starea anterioară în același mod.

Așadar, încercăm să creăm din această perspectivă mai orientată spre DBA un instrument care să permită realizarea aceleași activități despre care ai vorbit: avem o bază de date, dar dorim să testăm ceva de 50 de ori, aproape simultan.

DS: 50 de ori înseamnă că trebuie să comandați 50 de instanțe Spot.

NS: Nu, facem totul pe o singură mașină.

DS: Dar cum veți desfășura de 50 de ori, dacă această singură bază, să zicem, are 1 terabyte? Cel mai probabil, are nevoie de, să zicem, 256 GB RAM?

NS: Da, uneori ai nevoie de multă memorie — este normal. Dar un exemplu din viață. Pe mașina de producție sunt 96 de nuclee și 600 GB. În același timp, pentru baza de date se folosesc 32 de nuclee (chiar și 16 nuclee uneori) și o memorie de 100-120 GB.

DS: Și acolo încap 50 de copii?

NS: Dar copia este una, apoi funcționează copy-on-write (ZFS)... Îți voi explica mai în detaliu.

De exemplu, avem o bază de 10 TB. Am creat un disc pentru ea, ZFS i-a comprimare dimensiunea cu aproximativ 30-40%. Deoarece nu facem testare de încărcare, nu ne interesează timpul de răspuns exact: poate să fie de 2 ori mai lent — este în regulă.

Oferim programatorilor, QA, DBA etc. posibilitatea de a efectua teste în 1-2 fire. De exemplu, pot lansa o migrație. Nu necesită imediat 10 nuclee — are nevoie de 1 backend Postgres, 1 nucleu. Migrarea se va lansa — poate, autovacuum se va lansa încă, atunci se va activa al doilea nucleu. Avem alocate 16-32 nuclee, așa că 10 persoane pot lucra simultan, nu sunt probleme.

Deoarece fizic PGDATA este identică, se întâmplă că înșelăm realmente Postgres. Trucul este acesta: pornesc, de exemplu, 10 Postgres-uri simultan. Care este problema, de obicei? Se setează shared_buffers, de exemplu, la 25%. Aproape că aceasta înseamnă 200 GB. Nu poți lansa mai mult de trei astfel de instanțe, pentru că rămâi fără memorie.

Dar într-un anumit moment am realizat că acest lucru nu este necesar: setăm shared_buffers la 2 GB. PostgreSQL are effective_cache_size, și în realitate doar acesta influențează planurile. Acest lucru îl setăm la 0,5 TB. Și nu contează că de fapt nu există: el construiește planuri ca și cum ar exista.

Prin urmare, atunci când testăm o migrare, putem aduna toate planurile - vom vedea cum se va desfășura în producție. Secundele vor fi diferite (mai lente), dar datele pe care le citim efectiv și planurile în sine (ce JOIN-uri sunt etc.) sunt exact la fel ca în producție. Și în paralel, putem rula multe astfel de verificări pe o singură mașină.

DS: Nu crezi că există câteva probleme aici? Prima - este o soluție care funcționează doar pe PostgreSQL. Această abordare este foarte specifică, nu este generică. A doua - Kubernetes (și tot ce înseamnă acum tehnologiile cloud) presupune multe noduri, iar aceste noduri sunt efemere. În cazul tău, este un nod stateful, persistent. Aceste lucruri îmi provoacă contradicții.

NS: În primul rând - sunt de acord, aceasta este o poveste pur Postgres. Cred că, dacă avem un fel de direct IO și un pool de buffer aproape pentru toată memoria, această abordare nu va funcționa - planurile vor fi diferite. Dar pentru moment lucrăm doar cu Postgres și nu ne gândim la altele.

Despre Kubernetes. Tu însuți povestești peste tot că baza noastră este persistentă. Dacă instanța cade, important este să salvăm discul. Așadar, întreaga noastră platformă este în Kubernetes, iar componenta cu Postgres este separată (deși și aceasta va fi acolo într-o zi). Deci, așa stau lucrurile: instanța a căzut, dar am salvat PV-ul ei și l-am conectat pur și simplu la o altă (nouă) instanță, de parcă nimic nu s-ar fi întâmplat.

DS: Din punctul meu de vedere, creăm pod-uri în Kubernetes. K8s este elastic: nodurile sunt solicitate pe măsură ce este nevoie. Sarcina este pur și simplu să creăm un pod și să spunem că are nevoie de X resurse, iar apoi K8s se ocupă singur. Dar suportul pentru stocare în Kubernetes este încă instabil: în 1.16, pe 1.17 (această versiune a fost lansată săptămâni în urmă) aceste caracteristici devin doar o versiune beta.

După jumătate de an - un an, va deveni mai stabil, sau cel puțin va fi declarat astfel. Atunci posibilitatea de snapshot-uri și redimensionare îți rezolvă complet problema. Pentru că ai o bază. Da, poate să nu fie foarte rapidă, dar viteza depinde de ceea ce este 'sub capotă', deoarece unele implementări pot face copiere și copy-on-write la nivelul subsistemului de disc.

NS: Aici mai trebuie să se întâmple ca toate motoarele (Amazon, Google...) să înceapă să suporte această versiune - și asta durează și ea un timp.

DS: Până acum nu le folosim. Folosim al nostru.

Dezvoltare locală pe Kubernetes

NS: Te-ai confruntat vreodată cu o astfel de nevoie, când trebuie să ridici toate pod-urile pe aceeași mașină și să faci un mic test. Ca să obții rapid un proof of concept, să vezi că aplicația funcționează în Kubernetes, fără a aloca o grămadă de mașini pentru asta. Există Minikube, nu-i așa?

DS: Mi se pare că acest caz — desfășurarea pe un singur nod — este exclusiv despre dezvoltarea locală. Sau despre anumite manifestări ale acestui tipar. Există Minikube, există k3s, teste e2e actualizate.. Mergem spre utilizarea Kubernetes în Docker. Acum am început să lucrăm cu el pentru teste.

NS: Credeam mai devreme că este o încercare de a înfășura toate pod-urile într-o singură imagine Docker. Dar s-a dovedit că este complet altceva. Tot acolo sunt containere separate, pod-uri separate — doar că în Docker.

DS: Da. Și acolo s-a realizat o imitație destul de amuzantă, dar sensul este acesta… Avem un utilitar pentru desfășurare — werf. Vrem să facem un mod — permițându-i werf up: „Ridică-mi un Kubernetes local”. Și apoi să pornim un proces werf follow. Atunci dezvoltatorul va putea edita în IDE, iar în sistem se va rula un proces care va detecta modificările și va reconstrui imaginile, redeployându-le în K8s local. Astfel vrem să încercăm să rezolvăm problema dezvoltării locale.

Snapshots și clonarea Bazei de Date în realitățile K8s

NS: Dacă ne întoarcem la copy-on-write. Am observat că și în облаках există snapshots. Funcționează diferit. De exemplu, în GCP: ai un instantaneu de mai mulți terabiți pe coasta de est a SUA. Faci periodic snapshots. Ridici o copie a discului din snapshot pe coasta de vest — în câteva minute este gata, funcționează foarte rapid, doar că trebuie să umpli cache-ul în memorie. Dar aceste clone (snapshots) sunt pentru a „provisiona” un nou volum. Este grozav când trebuie să creezi multe instantanee.

Dar pentru teste, mi se pare că snapshots, de care vorbești în Docker sau de care vorbesc eu în ZFS, btrfs și chiar LVM… — permit să nu creezi cu adevărat date noi pe aceeași mașină. În cloud, vei plăti pentru ele de fiecare dată și nu vei mai aștepta secunde, ci minute (iar în cazul lazy load-ului, posibil, ore).

În locul acesta, poți obține aceste date în una-două secunde, să rulezi testul și să le arunci. Aceste snapshots rezolvă diferite sarcini. În primul caz — pentru a scala și a obține replici noi, iar în al doilea — pentru teste.

DS: Nu sunt de acord. A face o clonare corectă a volumelor este o sarcină pentru cloud. Nu am analizat implementarea lor, dar știu cum facem noi pe echipamente. Avem Ceph, prin el putem oricărei volume fizice (RBD) să spunem clone și să obținem în zeci de milisecunde a doua volum cu aceleași caracteristici, IOPSetc. Trebuie să înțelegem că în interior există un copy-on-write sofisticat. De ce cloud-ul nu ar face la fel? Sunt sigur că încearcă într-un fel sau altul să facă asta.

NS: Dar tot le vor lua secunde, zeci de secunde, pentru a ridica un instanț, a aduce Docker etc.

DS: De ce trebuie să ridicăm un întreg instanț? Avem un instanț cu 32 de nuclee, cu 16… și în el încap câteva – de exemplu, patru. Când cerem al cincilea, se va ridica deja un instanț, apoi va fi șters.

NS: Da, interesant, în Kubernetes se face altfel. La noi baza de date nu este în K8s, ci într-un singur instanț. În schimb, pentru clonarea unei baze de date de mai mulți terabiți nu durează mai mult de două secunde.

DS: Asta e grozav. Dar mesajul meu inițial este că aceasta nu este o soluție generică. Da, este grozav, dar se potrivește doar cu Postgres și numai pe un singur nod.

NS: Se potrivește nu doar pentru Postgres: acestea sunt planurile, așa cum am spus, vor funcționa doar în el. Dar dacă nu ne interesează planurile și avem pur și simplu nevoie de toate datele pentru testarea funcțională, atunci aceasta se potrivește pentru orice SGBD.

DS: Acum mulți ani am făcut ceva similar pe snapshots LVM. Este un clasic. Această abordare a fost folosită foarte activ. Doar că nodurile stateful sunt o durere. Pentru că trebuie să nu le lăsăm, întotdeauna să ne amintim de ele…

NS: Nu vezi aici o posibilitate de hibrid? Să zicem, stateful – este un pod oarecare, care lucrează cu câțiva oameni (multe testeri). Avem un volum, dar datorită sistemului de fișiere clonarile sunt locale. Dacă podul cade, discul rămâne – se va ridica podul, va citi informațiile despre toate clonele, le va readuce înapoi și va spune: „Iată clonele voastre pe aceste porturi, lucrați cu ele în continuare”.

DS: Tehnic, aceasta înseamnă că în cadrul Kubernetes este un singur pod, în care rulăm multe Postgres-uri.

NS: Da. Are o limită: să spunem, nu pot lucra simultan mai mult de 10 persoane. Dacă avem nevoie de 20 – vom lansa un al doilea astfel de pod. Este complet posibil să-l clonăm, obținând al doilea volum complet, pe care vor fi aceleași 10 clone „subțiri”. Nu vezi o astfel de posibilitate?

DS: Trebuie să adaug aici întrebări de securitate. Această organizație presupune că acest pod are privilegii ridicate (capabilități), deoarece poate efectua operațiuni neobișnuite asupra sistemului de fișiere... Dar repet: consider că, pe termen mediu, în Kubernetes se va rezolva problema stocării, iar în cloud se va rezolva întreaga istorie cu volumele — totul va „funcționa” simplu. Va exista redimensionare, clonare... Există un volum — spunem: „Creează unul nou pe baza celui existent”, — și în o secundă și jumătate primim ceea ce avem nevoie.

NS: Nu cred în o secundă și jumătate pentru multe terabytes. Pe Ceph faci totul tu, iar tu vorbești despre cloud. Du-te în cloud, pe EC2 fă un clonare a unui volum EBS de multe terabytes și vezi ce performanță va fi. Nu va dura câteva secunde. Mă interesează foarte mult când vor ajunge la acest indicator. Înțeleg despre ce vorbești, dar voi permite să nu fiu de acord.

DS: Ok, dar am spus că pe termen mediu, nu pe termen scurt. În câțiva ani.

Despre operatorul pentru PostgreSQL de la Zalando

La mijlocul acestei întâlniri, s-a alăturat și Alexey Klyukin, fost dezvoltator de la Zalando, care a povestit despre istoria operatorului PostgreSQL:

Este grozav că această temă a fost adusă în discuție: atât Postgres, cât și Kubernetes. Când am început să lucrăm la asta în Zalando în 2017, era un subiect la care toată lumea dorea să se implice, dar nimeni nu o făcea. Toată lumea deja avea Kubernetes, dar când întrebam cum să procedăm cu bazele de date, chiar și oameni precum Kelsey Hightower, care promovau K8s, spuneau cam următoarele:

„Mergeți la servicii gestionate și folosiți-le, nu rulați baze de date în Kubernetes. Altfel, Kubernetes-ul vostru va decide, de exemplu, să facă o actualizare, va închide toate nodurile și datele voastre vor zbura departe.”

Am decis să facem un operator care va rula, contrar acestui sfat, baze de date Postgres în Kubernetes. Și aveam un temei bun — Patroni. Acesta este failover automat pentru PostgreSQL, realizat corect, adică utilizând etcd, consul sau ZooKeeper ca depozit de informații despre cluster. Un astfel de depozit, care va oferi tuturor celor care întreabă, de exemplu, cine este acum liderul, aceeași informație — în ciuda faptului că totul este distribuit — pentru a nu exista split brain. În plus, aveam o imagine Docker pentru acesta.

De fapt, nevoia de auto failover a apărut după migrarea dintr-un centru de date intern în cloud. Cloudul a fost construit pe o soluție PaaS (Platform-as-a-Service) proprie. Este open source, dar pentru a-l implementa, a fost nevoie de mult efort. Se numea STUPS.

Inițial, nu exista niciun Kubernetes. Mai precis, când s-a dezvoltat soluția proprie, K8s exista deja, dar era atât de insuficient dezvoltat încât nu era potrivit pentru producție. Cred că era anul 2015 sau 2016. Până în 2017, Kubernetes a devenit oarecum matur — a apărut nevoia de migrare acolo.

Și deja aveam un container Docker. Aveam PaaS care utiliza Docker. De ce să nu încercăm K8s? De ce să nu scriem propriul operator? Murat Kabilov, care s-a alăturat nouă de la Avito, a început acest proiect din proprie inițiativă — „să ne jucăm” — și proiectul a avut succes.

Dar de fapt, voiam să vorbesc despre AWS. De ce acolo a existat istoric cod legat de AWS…

Când lansați ceva în Kubernetes, trebuie să înțelegeți că K8s este un work in progress. Evoluează constant, se îmbunătățește și, periodic, chiar se strică. Trebuie să fiți atenți la toate modificările din Kubernetes, să fiți pregătiți, în caz de nevoie, să vă împărtășiți experiențele și să înțelegeți în detaliu cum funcționează — poate mai mult decât v-ați dori. Asta este valabil, în principiu, pentru orice platformă pe care rulați bazele de date...

Așadar, când am realizat operatorul, aveam Postgres care lucra cu un volum extern (în acest caz — EBS, deoarece lucram în AWS). Baza de date a crescut, iar la un moment dat a fost necesar să facem resize: de exemplu, dimensiunea inițială EBS era de 100 TB, baza a crescut până la această dimensiune, acum vrem să facem EBS de 200 TB. Cum? Putem face un dump/restaurare pe un nou instanț, dar acest proces este lung și provoacă downtime.

De aceea, ne-am dorit un resize care să crească partiția EBS și apoi să instruiască sistemul de fișiere să utilizeze noul spațiu. Și am realizat acest lucru, dar în acel moment, Kubernetes nu avea niciun API pentru operația de resize. Deoarece lucram pe AWS, am scris cod pentru API-ul acestuia.

Nimic nu împiedică realizarea aceluiași lucru pentru alte platforme. În operator nu există o legătură care să permită rularea doar pe AWS, la fel ca pe celelalte, pe care nu va funcționa. În general, acesta este un proiect open source: dacă cineva dorește să accelereze apariția utilizării unui nou API — sunteți bineveniți. GitHub, pull request-urile — echipa Zalando se străduiește să răspundă rapid la acestea și să promoveze operatorul. Din câte știu, proiectul a participat la Google Summer of Code și la alte inițiative asemănătoare. Zalando lucrează foarte activ la el.

P.S. Bonus!

Dacă sunteți interesat de subiectul PostgreSQL și Kubernetes, vă aducem aminte că săptămâna trecută a avut loc următorul Postgres-marți, unde a discutat cu Nikolai Alexandr Kukushkin de la Zalando. Video-ul este disponibil aici.

P.P.S.

Citiți și în blogul nostru:

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster