O scurtă prezentare a declarațiilor PostgreSQL pentru Kubernetes, opțiunile și experiența noastră

O scurtă prezentare a declarațiilor PostgreSQL pentru Kubernetes, opțiunile și experiența noastră

Din ce în ce mai mult se primesc astfel de solicitări de la clienți: „Vrem ca Amazon RDS, dar mai ieftin”; „Ne dorim ca RDS, dar peste tot, în orice infrastructură.” Pentru a implementa o astfel de soluție gestionată pe Kubernetes, ne-am uitat la starea actuală a celor mai populari operatori pentru PostgreSQL (Stolon, operatori de la Crunchy Data și Zalando) și am făcut alegerea noastră.

Acest articol este experiența noastră atât din punct de vedere teoretic (o trecere în revistă a soluțiilor), cât și din punct de vedere practic (ce s-a ales și ce a rezultat). Dar mai întâi, să definim care sunt cerințele generale pentru un potențial înlocuitor pentru RDS...

Ce este RDS

Când oamenii vorbesc despre RDS, din experiența noastră, se referă la un serviciu DBMS gestionat care:

  1. ușor de configurat;
  2. are capacitatea de a lucra cu instantanee și de a se recupera după ele (de preferință cu suport pentru PITR);
  3. vă permite să creați topologii master-slave;
  4. are o listă bogată de extensii;
  5. asigură auditul și gestionarea utilizatorilor/accesului.

În general, abordările pentru implementarea sarcinii pot fi foarte diferite, dar calea cu Ansibleul condiționat nu este aproape de noi. (Colegii de la 2GIS au ajuns la o concluzie similară ca urmare a încercarea lui creați un „Instrument de implementare rapidă a clusterului de failover bazat pe Postgres”.)

Operatorii sunt abordarea general acceptată pentru rezolvarea unor astfel de probleme în ecosistemul Kubernetes. Mai detaliat despre ele în legătură cu bazele de date care rulează în Kubernetes, a spus deja directorul tehnic al Flant: distolÎn unul dintre rapoartele sale.

NB: Pentru a crea rapid operatori simpli, vă recomandăm să acordați atenție utilitarului nostru Open Source operator-shell. Folosind-o, puteți face acest lucru fără cunoștințe despre Go, dar în moduri mai familiare pentru administratorii de sistem: în Bash, Python etc.

Există mai mulți operatori K8s populari pentru PostgreSQL:

  • Stolon;
  • Crunchy Data Operator PostgreSQL;
  • Operator Zalando Postgres.

Să le privim mai îndeaproape.

Selectarea operatorului

Pe lângă caracteristicile importante deja menționate mai sus, noi, în calitate de ingineri de infrastructură din Kubernetes, ne așteptam și la următoarele de la operatori:

  • implementați din Git și cu Resurse personalizate;
  • suport anti-afinitate pod;
  • instalarea afinității nodului sau a selectorului de noduri;
  • stabilirea toleranțelor;
  • disponibilitatea opțiunilor de reglare;
  • tehnologii de înțeles și chiar comenzi.

Fără a intra în detalii cu privire la fiecare dintre puncte (întreaba în comentarii dacă mai ai întrebări despre ele după ce ai citit întregul articol), voi observa în general că acești parametri sunt necesari pentru o descriere mai subtilă a specializării nodurilor cluster în pentru a le comanda pentru aplicații specifice. Astfel putem obține echilibrul optim între performanță și cost.

Acum - către operatorii PostgreSQL înșiși.

1. Stolon

Stolon de la firma italiană Sorint.lab în raportul deja menționat a fost considerat ca un fel de standard printre operatorii pentru SGBD. Acesta este un proiect destul de vechi: prima sa lansare publică a avut loc în noiembrie 2015 (!), iar depozitul GitHub se mândrește cu aproape 3000 de stele și peste 40 de colaboratori.

Într-adevăr, Stolon este un exemplu excelent de arhitectură atentă:

O scurtă prezentare a declarațiilor PostgreSQL pentru Kubernetes, opțiunile și experiența noastră
Dispozitivul acestui operator poate fi găsit în detaliu în raport sau documentatia proiectului. În general, este suficient să spunem că poate face tot ce este descris: failover, proxy pentru accesul client transparent, backup-uri... Mai mult, proxy-urile oferă acces printr-un serviciu endpoint - spre deosebire de celelalte două soluții discutate mai jos (au două servicii de accesare). baza).

Cu toate acestea, Stolon fără resurse personalizate, motiv pentru care nu poate fi implementat în așa fel încât să fie ușor și rapid – „like hot cakes” – să creezi instanțe DBMS în Kubernetes. Gestionarea se realizează prin intermediul utilității stolonctl, implementare - prin Helm-chart și cele personalizate sunt definite în ConfigMap.

Pe de o parte, se dovedește că operatorul nu este cu adevărat un operator (pentru că nu folosește CRD). Dar, pe de altă parte, este un sistem flexibil care vă permite să configurați resursele în K8-uri așa cum doriți.

În concluzie, pentru noi personal, nu părea a fi cea mai bună modalitate de a începe o diagramă separată pentru fiecare bază de date. Așa că am început să căutăm alternative.

2. Crunchy Data Operator PostgreSQL

Operator de la Crunchy Data, un tânăr startup american, arăta ca o alternativă logică. Istoria sa publică începe cu prima lansare în martie 2017, de atunci depozitul GitHub a primit puțin sub 1300 de stele și peste 50 de colaboratori. Cea mai recentă versiune din septembrie a fost testată pentru a funcționa cu Kubernetes 1.15-1.18, OpenShift 3.11+ și 4.4+, GKE și VMware Enterprise PKS 1.3+.

Arhitectura Crunchy Data PostgreSQL Operator îndeplinește, de asemenea, cerințele menționate:

O scurtă prezentare a declarațiilor PostgreSQL pentru Kubernetes, opțiunile și experiența noastră

Managementul se face prin utilitate pgo, cu toate acestea, generează, la rândul său, resurse personalizate pentru Kubernetes. Prin urmare, operatorul ne-a încântat ca potențiali utilizatori:

  • există control prin CRD;
  • management comod al utilizatorilor (tot prin CRD);
  • integrarea cu alte componente Crunchy Data Container Suite - o colecție specializată de imagini container pentru PostgreSQL și utilități pentru lucrul cu acesta (inclusiv pgBackRest, pgAudit, extensii de la contrib etc.).

Cu toate acestea, încercările de a începe să utilizați operatorul de la Crunchy Data au scos la iveală mai multe probleme:

  • Nu a existat nicio posibilitate de toleranțe - este furnizat doar nodeSelector.
  • Pod-urile create au făcut parte din implementare, în ciuda faptului că implementam o aplicație cu stare. Spre deosebire de StatefulSets, implementările nu pot crea discuri.

Ultimul defect duce la momente amuzante: în mediul de testare, am reușit să rulăm 3 replici cu un singur disc depozitare locală, în urma căruia operatorul a raportat că funcționează 3 replici (deși nu a fost cazul).

O altă caracteristică a acestui operator este integrarea sa gata făcută cu diverse sisteme auxiliare. De exemplu, este ușor să instalați pgAdmin și pgBounce și în documentație sunt considerate Grafana și Prometeu preconfigurate. Într-un recent lansarea 4.5.0-beta1 s-a remarcat separat o integrare îmbunătățită cu proiectul pgMonitor, datorită căruia operatorul oferă o vizualizare vizuală a parametrilor PgSQL din cutie.

Cu toate acestea, alegerea ciudată a resurselor generate de Kubernetes ne-a determinat să găsim o soluție diferită.

3. Operator Zalando Postgres

Produsele Zalando ne sunt cunoscute de multă vreme: avem experiență în utilizarea Zalenium și, bineînțeles, am încercat Patroni este soluția lor populară HA pentru PostgreSQL. Despre abordarea companiei de a crea Operator Postgres a spus unul dintre autorii săi - Alexei Klyukin - în aer Postgres-Marți #5si noua ne-a placut.

Aceasta este cea mai tânără soluție discutată în articol: prima lansare a avut loc în august 2018. Cu toate acestea, în ciuda numărului mic de lansări formale, proiectul a parcurs un drum lung, depășind deja popularitatea soluției de la Crunchy Data cu peste 1300 de stele pe GitHub și numărul maxim de colaboratori (70+).

„Sub capota” acestui operator, se folosesc soluții testate în timp:

  • Patroni şi Spilo Pentru condus,
  • WAL-E - pentru copii de rezervă,
  • PgBouncer - ca un pool de conexiuni.

Iată cum este prezentată arhitectura operatorului de la Zalando:

O scurtă prezentare a declarațiilor PostgreSQL pentru Kubernetes, opțiunile și experiența noastră

Operatorul este gestionat în totalitate prin Resurse personalizate, creează automat un StatefulSet din containere, care poate fi apoi personalizat prin adăugarea diferitelor sidecar-uri la pod. Toate acestea reprezintă un plus semnificativ în comparație cu operatorul de la Crunchy Data.

Întrucât am ales soluția de la Zalando dintre cele 3 opțiuni luate în considerare, o descriere suplimentară a capabilităților acesteia va fi prezentată mai jos, imediat împreună cu practica de aplicare.

Practicați cu Postgres Operator de la Zalando

Implementarea operatorului este foarte simplă: trebuie doar să descărcați cea mai recentă versiune de pe GitHub și să aplicați fișiere YAML din director manifestă. Alternativ, puteți utiliza și operatorhub.

După instalare, ar trebui să aveți grijă de setări stocare pentru jurnale și copii de rezervă. Se face prin ConfigMap postgres-operator în spațiul de nume în care ați setat operatorul. Cu depozitele configurate, puteți implementa primul dvs. cluster PostgreSQL.

De exemplu, implementarea noastră standard arată astfel:

apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
 name: staging-db
spec:
 numberOfInstances: 3
 patroni:
   synchronous_mode: true
 postgresql:
   version: "12"
 resources:
   limits:
     cpu: 100m
     memory: 1Gi
   requests:
     cpu: 100m
     memory: 1Gi
 sidecars:
 - env:
   - name: DATA_SOURCE_URI
     value: 127.0.0.1:5432
   - name: DATA_SOURCE_PASS
     valueFrom:
       secretKeyRef:
         key: password
         name: postgres.staging-db.credentials
   - name: DATA_SOURCE_USER
     value: postgres
   image: wrouesnel/postgres_exporter
   name: prometheus-exporter
   resources:
     limits:
       cpu: 500m
       memory: 100Mi
     requests:
       cpu: 100m
       memory: 100Mi
 teamId: staging
 volume:
   size: 2Gi

Acest manifest implementează un grup de 3 instanțe cu un sidecar al formularului postgres_exporter, din care colectăm valorile aplicației. După cum puteți vedea, totul este foarte simplu și, dacă doriți, puteți face un număr literalmente nelimitat de clustere.

Merită să acordați atenție panou web pentru administrare - postgres-operator-ui. Vine împreună cu operatorul și vă permite să creați și să ștergeți clustere, precum și să lucrați cu copiile de rezervă pe care le face operatorul.

O scurtă prezentare a declarațiilor PostgreSQL pentru Kubernetes, opțiunile și experiența noastră
Lista clusterelor PostgreSQL

O scurtă prezentare a declarațiilor PostgreSQL pentru Kubernetes, opțiunile și experiența noastră
Managementul backupului

O altă caracteristică interesantă este suportul API-ul Teams. Acest mecanism creează automat roluri în PostgreSQL, pe baza listei de nume de utilizator rezultată. După aceea, API-ul vă permite să returnați o listă de utilizatori pentru care sunt create automat roluri.

Probleme și soluții

Cu toate acestea, utilizarea operatorului a dezvăluit curând câteva dezavantaje semnificative:

  1. lipsa suportului nodeSelector;
  2. incapacitatea de a dezactiva backup-urile;
  3. când se utilizează funcția de creare a bazelor, privilegiile implicite nu apar;
  4. periodic nu există documentație suficientă sau este depășită.

Din fericire, multe dintre ele pot fi rezolvate. Să începem de la sfârșit - probleme cu documentație.

Cel mai probabil, veți întâlni faptul că nu este întotdeauna clar cum să înregistrați o copie de rezervă și cum să conectați o găleată de rezervă la interfața de utilizare a operatorului. Documentația vorbește despre asta în treacăt, dar descrierea reală este în PR:

  1. trebuie să faci un secret;
  2. transmite-l operatorului ca parametru pod_environment_secret_name în CRD cu setările operatorului sau în ConfigMap (în funcție de modul în care alegeți să instalați operatorul).

Cu toate acestea, după cum s-a dovedit, în acest moment acest lucru nu este posibil. De aceea am adunat versiunea dvs. de operator cu unele dezvoltări suplimentare de la terți. Mai multe despre asta - vezi mai jos.

Dacă transmiteți parametri operatorului pentru backup, și anume - wal_s3_bucket și cheile de acces în AWS S3, apoi acesta va face backup la tot: nu numai baze în producție, ci și punere în scenă. Nu ne convenea.

În descrierea parametrilor către Spilo, care este învelișul Docker de bază pentru PgSQL atunci când utilizați operatorul, s-a dovedit că puteți transmite un parametru WAL_S3_BUCKET gol, dezactivând astfel backup-urile. Mai mult, spre mare bucurie, am găsit gata PR, pe care l-am acceptat imediat în furca noastră. Acum este destul de ușor de adăugat enableWALArchiving: false la o resursă de cluster PostgreSQL.

Da, s-a putut face altfel rulând 2 operatori: unul pentru staging (fără backup) și al doilea pentru producție. Dar ne-am descurcat cu unul.

Ok, am învățat cum să transferăm accesul pentru S3 la bazele de date și backup-urile au început să intre în stocare. Cum se face ca paginile de rezervă să funcționeze în interfața operatorului?

O scurtă prezentare a declarațiilor PostgreSQL pentru Kubernetes, opțiunile și experiența noastră

În interfața de utilizare a operatorului, va trebui să adăugați 3 variabile:

  • SPILO_S3_BACKUP_BUCKET
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

După aceea, gestionarea backupului va deveni disponibilă, ceea ce în cazul nostru va simplifica munca cu punerea în scenă, permițându-vă să livrați felii din producție acolo fără scripturi suplimentare.

Ca un alt plus, lucrul cu API-ul Teams și s-au apelat largi oportunități pentru crearea de baze de date și roluri folosind instrumentele operatorului. Cu toate acestea, în curs de dezvoltare rolurile nu aveau permisiuni implicit. În consecință, un utilizator cu drepturi de citire nu a putut citi tabele noi.

De ce este asta? Chiar dacă în cod există necesar GRANTnu se aplică întotdeauna. Există 2 metode: syncPreparedDatabases и syncDatabases. În syncPreparedDatabases - în ciuda faptului că în secţiune preparedDatabases există exista o conditie defaultRoles и defaultUsers pentru a crea roluri, drepturile implicite nu sunt aplicate. Suntem în proces de pregătire a unui patch, astfel încât aceste drepturi să fie aplicate automat.

Și ultimul moment în îmbunătățirile care sunt relevante pentru noi - plastureA care adaugă o afinitate de nod la StatefulSet generat. Clienții noștri preferă adesea să reducă costurile utilizând instanțe spot, care în mod clar nu merită găzduirea serviciilor de baze de date. Această problemă ar putea fi rezolvată prin toleranțe, dar prezența Node Affinity oferă mai multă încredere.

Ce sa întâmplat?

Ca urmare a rezolvării problemelor de mai sus, am introdus operatorul Postgres de la Zalando în depozitul dvsunde merge cu patch-uri atât de utile. Și pentru mai multă comoditate, am colectat și noi Imagine Docker.

Lista PR-urilor acceptate în fork:

Va fi grozav dacă comunitatea sprijină aceste PR, astfel încât să ajungă în amonte cu următoarea versiune a operatorului (1.6).

Primă! Povestea de succes a migrației producției

Dacă utilizați Patroni, producția live poate fi migrată către operator cu timp de nefuncționare minim.

Spilo vă permite să creați clustere de așteptare prin stocarea S3 cu wal-ecând jurnalul binar PgSQL este mai întâi stocat în S3 și apoi pompat de replică. Dar dacă ai nu folosit de Wal-E în infrastructura veche? Soluția la această problemă este deja s-a sugerat pe hub.

Replicarea logică PostgreSQL vine în ajutor. Cu toate acestea, nu vom intra în detalii despre cum să creăm publicații și abonamente, pentru că... planul nostru a eșuat.

Cert este că baza de date avea mai multe tabele încărcate cu milioane de rânduri, care, în plus, au fost în mod constant completate și șterse. Abonament simplu с copy_data, când noua replică copiază tot conținutul din master, pur și simplu nu a putut ține pasul cu masterul. Copierea conținutului a funcționat timp de o săptămână, dar nu a ajuns niciodată din urmă cu maestrul. Până la urmă, a ajutat la rezolvarea problemei articol colegii de la Avito: puteți transfera date folosind pg_dump. Voi descrie versiunea noastră (puțin modificată) a acestui algoritm.

Ideea este că puteți face un abonament dezactivat legat de un anumit slot de replicare și apoi puteți fixa numărul tranzacției. Au existat replici pentru lucrări de producție. Acest lucru este important deoarece replica va ajuta la crearea unui dump consistent și va continua să primească modificări de la master.

Comenzile ulterioare care descriu procesul de migrare vor folosi următoarea notație pentru gazde:

  1. maestru — server sursă;
  2. replica1 - replica streaming pe vechea productie;
  3. replica2 - noua replica logica.

Plan de migrare

1. Creați un abonament la toate tabelele din schema din expert public baza dbname:

psql -h master -d dbname -c "CREATE PUBLICATION dbname FOR ALL TABLES;"

2. Creați un slot de replicare pe master:

psql -h master -c "select pg_create_logical_replication_slot('repl', 'pgoutput');"

3. Opriți replicarea pe replica veche:

psql -h replica1 -c "select pg_wal_replay_pause();"

4. Obțineți numărul tranzacției de la master:

psql -h master -c "select replay_lsn from pg_stat_replication where client_addr = 'replica1';"

5. Dump din vechea replică. Vom face acest lucru în mai multe fire, ceea ce va ajuta la accelerarea procesului:

pg_dump -h replica1 --no-publications --no-subscriptions -O -C -F d -j 8 -f dump/ dbname

6. Încărcați dump-ul pe noul server:

pg_restore -h replica2 -F d -j 8 -d dbname dump/

7. După descărcarea dump-ului, puteți începe replicarea pe replica de streaming:

psql -h replica1 -c "select pg_wal_replay_resume();"

7. Creați un abonament pe o nouă replică logică:

psql -h replica2 -c "create subscription oldprod connection 'host=replica1 port=5432 user=postgres password=secret dbname=dbname' publication dbname with (enabled = false, create_slot = false, copy_data = false, slot_name='repl');"

8. Ia oid abonamente:

psql -h replica2 -d dbname -c "select oid, * from pg_subscription;"

9. Să zicem că a fost primit oid=1000. Să aplicăm numărul tranzacției la abonament:

psql -h replica2 -d dbname -c "select pg_replication_origin_advance('pg_1000', 'AA/AAAAAAAA');"

10. Să începem replicarea:

psql -h replica2 -d dbname -c "alter subscription oldprod enable;"

11. Verificați starea abonamentului, replicarea ar trebui să funcționeze:

psql -h replica2 -d dbname -c "select * from pg_replication_origin_status;"
psql -h master -d dbname -c "select slot_name, restart_lsn, confirmed_flush_lsn from pg_replication_slots;"

12. După ce replicarea este pornită și bazele de date sunt sincronizate, puteți comuta.

13. După dezactivarea replicării, trebuie să remediați secvențele. Acest lucru este bine descris în articolul de pe wiki.postgresql.org.

Datorită acestui plan, trecerea a trecut cu întârzieri minime.

Concluzie

Operatorii Kubernetes vă permit să simplificați diverse acțiuni, reducându-le la crearea de resurse K8s. Cu toate acestea, după ce a realizat o automatizare remarcabilă cu ajutorul lor, merită să ne amintim că poate aduce și o serie de nuanțe neașteptate, așa că alegeți-vă operatorii cu înțelepciune.

După ce am analizat cei mai populari trei operatori Kubernetes pentru PostgreSQL, am ales proiectul de la Zalando. Și a trebuit să depășim unele dificultăți cu el, dar rezultatul a fost cu adevărat plăcut, așa că intenționăm să extindem această experiență la alte instalări ale PgSQL. Dacă aveți experiență în utilizarea unor soluții similare, vom fi bucuroși să vedem detaliile în comentarii!

PS

Citește și pe blogul nostru:

Sursa: www.habr.com

Adauga un comentariu