Una breu visió general de les declaracions de PostgreSQL per a Kubernetes, les nostres opcions i experiència

Una breu visió general de les declaracions de PostgreSQL per a Kubernetes, les nostres opcions i experiència

Cada cop més, els clients reben les següents peticions: “El volem com Amazon RDS, però més barat”; "El volem com RDS, però a tot arreu, en qualsevol infraestructura". Per implementar aquesta solució gestionada a Kubernetes, vam analitzar l'estat actual dels operadors més populars per a PostgreSQL (Stolon, operadors de Crunchy Data i Zalando) i vam triar.

Aquest article és l'experiència que hem adquirit tant des del punt de vista teòric (revisió de solucions) com des del vessant pràctic (què s'ha escollit i què en va sortir). Però primer, determinem quins són els requisits generals per a un possible substitut de RDS...

Què és RDS

Quan la gent parla de RDS, segons la nostra experiència, es refereix a un servei de SGBD gestionat que:

  1. fàcil de configurar;
  2. té la capacitat de treballar amb instantànies i recuperar-se d'elles (preferiblement amb suport PITR);
  3. permet crear topologies mestre-esclau;
  4. té una rica llista d'extensions;
  5. proporciona auditoria i gestió d'usuaris/accés.

En termes generals, els enfocaments per implementar la tasca en qüestió poden ser molt diferents, però el camí amb Ansible condicional no està a prop nostre. (Com a resultat, els companys de 2GIS van arribar a una conclusió similar el seu intent crear "una eina per desplegar ràpidament un clúster de failover basat en Postgres").

Els operadors són un enfocament comú per resoldre problemes similars a l'ecosistema Kubernetes. El director tècnic de "Flanta" ja n'ha parlat amb més detall en relació a les bases de dades llançades dins de Kubernetes. distola un dels seus informes.

NB: Per crear ràpidament operadors senzills, us recomanem parar atenció a la nostra utilitat de codi obert operador de shell. Utilitzant-lo, podeu fer-ho sense coneixements de Go, però de maneres més familiars per als administradors del sistema: en Bash, Python, etc.

Hi ha diversos operadors K8s populars per a PostgreSQL:

  • Estoló;
  • Crunchy Data Operador PostgreSQL;
  • Operador Zalando Postgres.

Mirem-los més de prop.

Selecció de l'operador

A més de les característiques importants ja esmentades anteriorment, nosaltres, com a enginyers d'operacions d'infraestructura de Kubernetes, també esperàvem el següent dels operadors:

  • desplegament des de Git i amb Recursos personalitzats;
  • suport anti-afinitat de pod;
  • instal·lar l'afinitat de nodes o el selector de nodes;
  • instal·lació de toleràncies;
  • disponibilitat de capacitats de sintonització;
  • tecnologies comprensibles i fins i tot ordres.

Sense entrar en detalls sobre cadascun dels punts (pregunteu als comentaris si encara teniu preguntes sobre ells després de llegir l'article sencer), notaré en general que aquests paràmetres són necessaris per descriure amb més precisió l'especialització dels nodes del clúster per tal de ordenar-los per a aplicacions específiques. D'aquesta manera podem aconseguir l'equilibri òptim en termes de rendiment i cost.

Ara passem als mateixos operadors PostgreSQL.

1. Estoló

Estolon de l'empresa italiana Sorint.lab in informe ja esmentat va ser considerat com una mena d'estàndard entre els operadors per a DBMS. Aquest és un projecte força antic: el seu primer llançament públic va tenir lloc el novembre de 2015 (!), i el dipòsit de GitHub compta amb gairebé 3000 estrelles i més de 40 col·laboradors.

De fet, Stolon és un excel·lent exemple d'arquitectura reflexiva:

Una breu visió general de les declaracions de PostgreSQL per a Kubernetes, les nostres opcions i experiència
El dispositiu d'aquest operador es pot trobar amb detall a l'informe o documentació del projecte. En general, n'hi ha prou amb dir que pot fer tot el que es descriu: failover, servidors intermediaris per a l'accés transparent del client, còpies de seguretat... A més, els servidors intermediaris proporcionen accés a través d'un servei de punt final, a diferència de les altres dues solucions que es comenten a continuació (cadascun tenen dos serveis per base d'accés).

Tanmateix, Stolon no hi ha recursos personalitzats, és per això que no es pot desplegar de manera que sigui fàcil i ràpid, "com els pastissos calents", crear instàncies de DBMS a Kubernetes. La gestió es realitza a través de la utilitat stolonctl, el desplegament es fa mitjançant el gràfic Helm i els personalitzats es defineixen i s'especifiquen a ConfigMap.

D'una banda, resulta que l'operador no és realment un operador (al cap i a la fi, no utilitza CRD). Però, d'altra banda, és un sistema flexible que permet configurar els recursos en K8s com cregui.

En resum, per a nosaltres personalment no ens va semblar òptim crear un gràfic separat per a cada base de dades. Per tant, vam començar a buscar alternatives.

2. Crunchy Data Operador PostgreSQL

Operador de Crunchy Data, una jove startup nord-americana, semblava una alternativa lògica. La seva història pública comença amb el primer llançament el març de 2017, des d'aleshores el dipòsit de GitHub ha rebut una mica menys de 1300 estrelles i més de 50 col·laboradors. La darrera versió del setembre es va provar per funcionar amb Kubernetes 1.15-1.18, OpenShift 3.11+ i 4.4+, GKE i VMware Enterprise PKS 1.3+.

L'arquitectura de Crunchy Data PostgreSQL Operator també compleix els requisits establerts:

Una breu visió general de les declaracions de PostgreSQL per a Kubernetes, les nostres opcions i experiència

La gestió es fa a través de la utilitat pgo, però, al seu torn genera recursos personalitzats per a Kubernetes. Per tant, l'operador ens va agradar com a usuaris potencials:

  • hi ha control via CRD;
  • gestió còmoda d'usuaris (també mitjançant CRD);
  • integració amb altres components Crunchy Data Container Suite — una col·lecció especialitzada d'imatges de contenidors per a PostgreSQL i utilitats per treballar-hi (incloent-hi pgBackRest, pgAudit, extensions de contrib, etc.).

Tanmateix, els intents de començar a utilitzar l'operador de Crunchy Data van revelar diversos problemes:

  • No hi havia possibilitat de toleracions: només es proporciona nodeSelector.
  • Els pods creats formaven part de Deployment, malgrat que vam desplegar una aplicació amb estat. A diferència dels StatefulSets, els desplegaments no poden crear discs.

L'últim inconvenient porta a moments divertits: a l'entorn de prova hem aconseguit executar 3 rèpliques amb un disc emmagatzematge local, fent que l'operador informi que 3 rèpliques estaven funcionant (encara que no ho fessin).

Una altra característica d'aquest operador és la seva integració ja feta amb diversos sistemes auxiliars. Per exemple, és fàcil instal·lar pgAdmin i pgBounce, i en documentació Es consideren Grafana i Prometeu preconfigurats. Recentment versió 4.5.0-beta1 La millora de la integració amb el projecte s'anota per separat pgMonitor, gràcies a la qual l'operador ofereix una visualització clara de les mètriques de PgSQL des de la caixa.

Tanmateix, l'estranya elecció dels recursos generats per Kubernetes ens va portar a la necessitat de trobar una solució diferent.

3. Operador Zalando Postgres

Coneixem els productes Zalando des de fa molt de temps: tenim experiència utilitzant Zalenium i, per descomptat, ho vam provar Patroni és la seva popular solució HA per a PostgreSQL. Sobre l'enfocament de l'empresa per crear Operador Postgres un dels seus autors, Alexey Klyukin, va dir a l'aire Postgres-dimarts #5, i ens va agradar.

Aquesta és la solució més jove que es parla a l'article: el primer llançament va tenir lloc l'agost de 2018. No obstant això, tot i el petit nombre de llançaments formals, el projecte ha recorregut un llarg camí, superant ja en popularitat la solució de Crunchy Data amb més de 1300 estrelles a GitHub i el nombre màxim de col·laboradors (70+).

"Sota el capó" aquest operador utilitza solucions provades en el temps:

  • Patroni i Spilo Per conduir,
  • WAL-E - per a còpies de seguretat,
  • PgBouncer - com a piscina de connexió.

Així és com es presenta l'arquitectura de l'operador de Zalando:

Una breu visió general de les declaracions de PostgreSQL per a Kubernetes, les nostres opcions i experiència

L'operador es gestiona completament mitjançant Recursos personalitzats, crea automàticament un StatefulSet a partir de contenidors, que després es pot personalitzar afegint diversos sidecars al pod. Tot això és un avantatge important en comparació amb l'operador de Crunchy Data.

Com que hem escollit la solució de Zalando entre les 3 opcions considerades, a continuació es presentarà una descripció més de les seves capacitats, immediatament juntament amb la pràctica d'aplicació.

Practica amb Postgres Operator de Zalando

El desplegament de l'operador és molt senzill: només cal que baixeu la versió actual de GitHub i apliqueu els fitxers YAML del directori es manifesta. Alternativament, també podeu utilitzar operadorhub.

Després de la instal·lació, hauríeu de preocupar-vos per la configuració emmagatzematge per a registres i còpies de seguretat. Això es fa mitjançant ConfigMap postgres-operator a l'espai de noms on heu instal·lat l'operador. Un cop configurats els dipòsits, podeu implementar el vostre primer clúster PostgreSQL.

Per exemple, el nostre desplegament estàndard té aquest aspecte:

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

Aquest manifest desplega un grup de 3 instàncies amb un sidecar al formulari postgres_exporter, de la qual prenem les mètriques de l'aplicació. Com podeu veure, tot és molt senzill i, si voleu, podeu crear un nombre literalment il·limitat de clústers.

Val la pena parar atenció panell d'administració web - postgres-operator-ui. Ve amb l'operador i us permet crear i eliminar clústers, així com treballar amb còpies de seguretat fetes per l'operador.

Una breu visió general de les declaracions de PostgreSQL per a Kubernetes, les nostres opcions i experiència
Llista de clústers PostgreSQL

Una breu visió general de les declaracions de PostgreSQL per a Kubernetes, les nostres opcions i experiència
Gestió de còpies de seguretat

Una altra característica interessant és el suport API d'equips. Aquest mecanisme es crea automàticament rols a PostgreSQL, basat en la llista de noms d'usuari resultant. Aleshores, l'API us permet retornar una llista d'usuaris per als quals es creen rols automàticament.

Problemes i solucions

Tanmateix, l'ús de l'operador aviat va revelar diverses deficiències importants:

  1. manca de suport de nodeSelector;
  2. impossibilitat de desactivar les còpies de seguretat;
  3. quan s'utilitza la funció de creació de bases de dades, els privilegis per defecte no apareixen;
  4. De vegades falta la documentació o està obsoleta.

Afortunadament, molts d'ells es poden resoldre. Comencem pel final: problemes amb documentació.

El més probable és que us trobeu amb el fet que no sempre està clar com registrar una còpia de seguretat i com connectar el cub de còpia de seguretat a la interfície d'usuari de l'operador. La documentació parla d'això de passada, però la descripció real hi és PR:

  1. necessitat de fer un secret;
  2. passar-ho a l'operador com a paràmetre pod_environment_secret_name al CRD amb la configuració de l'operador o a ConfigMap (segons com decidiu instal·lar l'operador).

Tanmateix, com es veu, això és impossible actualment. Per això hem recollit la vostra versió de l'operador amb alguns desenvolupaments addicionals de tercers. Per obtenir més informació al respecte, vegeu a continuació.

Si passeu els paràmetres de còpia de seguretat a l'operador, és a dir, - wal_s3_bucket i les claus d'accés a AWS S3, i després farà una còpia de seguretat de tot: no només bases en la producció, sinó també la posada en escena. Això no ens va bé.

A la descripció dels paràmetres de Spilo, que és l'embolcall bàsic de Docker per a PgSQL quan s'utilitza l'operador, va resultar: podeu passar un paràmetre WAL_S3_BUCKET buit, desactivant així les còpies de seguretat. A més, amb gran alegria, vaig trobar llest PR, que de seguida vam acceptar a la nostra bifurcació. Ara només cal afegir enableWALArchiving: false a un recurs de clúster PostgreSQL.

Sí, hi va haver l'oportunitat de fer-ho de manera diferent fent funcionar 2 operadors: un per a la posada en escena (sense còpies de seguretat) i el segon per a la producció. Però ens hem pogut conformar amb un.

D'acord, vam aprendre a transferir l'accés a les bases de dades per a S3 i les còpies de seguretat van començar a emmagatzemar-se. Com fer que les pàgines de còpia de seguretat funcionin a la interfície d'usuari de l'operador?

Una breu visió general de les declaracions de PostgreSQL per a Kubernetes, les nostres opcions i experiència

Haureu d'afegir 3 variables a la interfície d'usuari de l'operador:

  • SPILO_S3_BACKUP_BUCKET
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

Després d'això, estarà disponible la gestió de còpies de seguretat, la qual cosa en el nostre cas simplificarà el treball amb la posada en escena, permetent-nos lliurar-hi slices de producció sense scripts addicionals.

Un altre avantatge va ser el treball amb l'API Teams i àmplies oportunitats per crear bases de dades i rols mitjançant eines d'operador. Tanmateix, el creat els rols no tenien drets per defecte. En conseqüència, un usuari amb drets de lectura no podria llegir taules noves.

Per què això? Malgrat que al codi hi el necessari GRANT, no sempre s'utilitzen. Hi ha 2 mètodes: syncPreparedDatabases и syncDatabases. En syncPreparedDatabases - malgrat que a l'apartat preparedDatabases hi hi ha una condició defaultRoles и defaultUsers per crear rols, no s'apliquen els drets per defecte. Estem en procés de preparar un pedaç perquè aquests drets s'apliquin automàticament.

I l'últim punt de les millores que són rellevants per a nosaltres: pegat, que afegeix Node Affinity al StatefulSet creat. Els nostres clients sovint prefereixen reduir costos utilitzant instàncies puntuals, i és evident que no val la pena allotjar serveis de bases de dades. Aquest problema es podria resoldre mitjançant toleràncies, però la presència de Node Affinity dóna més confiança.

Què va passar?

A partir dels resultats de la resolució dels problemes anteriors, vam introduir Postgres Operator de Zalando el teu repositori, on es recull amb pegats tan útils. I per a més comoditat, també hem recollit Imatge de Docker.

Llista de PR acceptats a la bifurcació:

Serà genial si la comunitat admet aquests PR perquè puguen amunt amb la següent versió de l'operador (1.6).

Bonificació! Cas d'èxit de la migració de producció

Si utilitzeu Patroni, la producció en directe es pot migrar a l'operador amb un temps d'inactivitat mínim.

Spilo us permet crear clústers en espera mitjançant l'emmagatzematge S3 amb Wal-E, quan el registre binari de PgSQL s'emmagatzema primer a S3 i després la rèplica el bombeja. Però què fer si ho tens no utilitzat per Wal-E a la infraestructura antiga? La solució a aquest problema ja està es va suggerir al hub.

La replicació lògica de PostgreSQL arriba al rescat. Tanmateix, no entrarem en detalls sobre com crear publicacions i subscripcions, perquè... el nostre pla va ser un fiasco.

El cas és que la base de dades tenia diverses taules carregades amb milions de files, que, a més, s'omplien i s'eliminaven constantment. Subscripció senzilla с copy_data, quan la nova rèplica copia tot el contingut del mestre, simplement no pot mantenir-se al dia amb el mestre. La còpia de contingut va funcionar durant una setmana, però mai no es va posar al dia amb el mestre. Al final, em va ajudar a resoldre el problema article companys d'Avito: podeu transferir dades utilitzant pg_dump. Descriuré la nostra versió (lleugerament modificada) d'aquest algorisme.

La idea és que podeu fer una subscripció desactivada lligada a una ranura de rèplica específica i, a continuació, corregir el número de transacció. Hi havia rèpliques disponibles per al treball de producció. Això és important perquè la rèplica ajudarà a crear un abocament coherent i seguirà rebent canvis del mestre.

Les ordres posteriors que descriguin el procés de migració utilitzaran les anotacions d'amfitrió següents:

  1. mestre — servidor font;
  2. rèplica 1 — rèplica en streaming a la producció antiga;
  3. rèplica 2 - nova rèplica lògica.

Pla de migració

1. Creeu una subscripció al mestre per a totes les taules de l'esquema public base dbname:

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

2. Creeu una ranura de rèplica al mestre:

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

3. Atureu la rèplica a la rèplica antiga:

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

4. Obteniu el número de transacció del mestre:

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

5. Traieu l'abocador de la rèplica antiga. Ho farem en diversos fils, que ajudaran a accelerar el procés:

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

6. Carregueu l'abocament al nou servidor:

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

7. Després de descarregar l'abocament, podeu iniciar la rèplica a la rèplica de transmissió:

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

7. Creem una subscripció en una nova rèplica lògica:

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. Anem oid subscripcions:

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

9. Diguem que es va rebre oid=1000. Apliquem el número de transacció a la subscripció:

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

10. Comencem la replicació:

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

11. Comproveu l'estat de la subscripció, la rèplica hauria de funcionar:

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. Després d'iniciar la rèplica i sincronitzar les bases de dades, podeu canviar.

13. Després d'inhabilitar la rèplica, heu de corregir les seqüències. Això està ben descrit a l'article a wiki.postgresql.org.

Gràcies a aquest pla, el canvi es va dur a terme amb retards mínims.

Conclusió

Els operadors de Kubernetes us permeten simplificar diverses accions reduint-les a la creació de recursos K8s. Tanmateix, després d'haver aconseguit una automatització notable amb la seva ajuda, val la pena recordar que també pot aportar una sèrie de matisos inesperats, així que trieu els vostres operadors amb prudència.

Després d'haver considerat els tres operadors Kubernetes més populars per a PostgreSQL, vam triar el projecte de Zalando. I vam haver de superar certes dificultats amb ell, però el resultat va ser realment agradable, així que tenim previst ampliar aquesta experiència a altres instal·lacions de PgSQL. Si teniu experiència utilitzant solucions similars, estarem encantats de veure els detalls als comentaris!

PS

Llegeix també al nostre blog:

Font: www.habr.com

Afegeix comentari