Una breve panoramica delle istruzioni PostgreSQL per Kubernetes, le nostre scelte e la nostra esperienza

Una breve panoramica delle istruzioni PostgreSQL per Kubernetes, le nostre scelte e la nostra esperienza

Sempre più spesso, tali richieste vengono ricevute dai clienti: "Lo vogliamo come Amazon RDS, ma più economico"; "Lo vogliamo come RDS, ma ovunque, in qualsiasi infrastruttura". Per implementare una tale soluzione gestita su Kubernetes, abbiamo esaminato lo stato attuale degli operatori più popolari per PostgreSQL (Stolon, operatori di Crunchy Data e Zalando) e fatto la nostra scelta.

Questo articolo è la nostra esperienza sia da un punto di vista teorico (una rassegna di soluzioni) sia da un punto di vista pratico (cosa è stato scelto e cosa ne è derivato). Ma prima definiamo quali sono i requisiti generali per un potenziale sostituto di RDS ...

Cos'è l'RDS

Quando si parla di RDS, nella nostra esperienza, si intende un servizio DBMS gestito che:

  1. facile da configurare;
  2. ha la capacità di lavorare con le istantanee e ripristinarle (preferibilmente con il supporto per PITR);
  3. permette di creare topologie master-slave;
  4. ha un ricco elenco di estensioni;
  5. fornisce il controllo e la gestione degli utenti/accessi.

In generale, gli approcci all'implementazione dell'attività possono essere molto diversi, ma il percorso con Ansible condizionale non è vicino a noi. (I colleghi di 2GIS sono giunti a una conclusione simile come risultato di suo tentativo creare uno "Strumento di distribuzione rapida del cluster di failover basato su Postgres".)

Sono gli operatori l'approccio generalmente accettato per risolvere tali problemi nell'ecosistema Kubernetes. Più in dettaglio su di loro in relazione ai database in esecuzione all'interno di Kubernetes, ha già detto il direttore tecnico di Flant, distillareIn uno dei suoi rapporti.

NB: Per creare rapidamente operatori semplici, ti consigliamo di prestare attenzione alla nostra utility Open Source operatore di shell. Usandolo, puoi farlo senza conoscere Go, ma in modi più familiari per gli amministratori di sistema: in Bash, Python, ecc.

Esistono diversi operatori K8 popolari per PostgreSQL:

  • Stolone;
  • Crunchy Data Operatore PostgreSQL;
  • Operatore Zalando Postgres.

Diamo un'occhiata a loro più da vicino.

selezione operatore

Oltre alle importanti funzionalità già menzionate sopra, noi, in qualità di ingegneri dell'infrastruttura in Kubernetes, ci aspettavamo anche quanto segue dagli operatori:

  • distribuire da Git e con Risorse personalizzate;
  • supporto anti-affinità pod;
  • installazione dell'affinità del nodo o del selettore del nodo;
  • impostazione delle tolleranze;
  • disponibilità di opzioni di ottimizzazione;
  • tecnologie comprensibili e persino comandi.

Senza entrare nei dettagli su ciascuno dei punti (chiedi nei commenti se hai ancora domande su di essi dopo aver letto l'intero articolo), noterò in generale che questi parametri sono necessari per una descrizione più sottile della specializzazione dei nodi del cluster in per ordinarli per applicazioni specifiche. In questo modo possiamo raggiungere l'equilibrio ottimale tra prestazioni e costi.

Ora - agli stessi operatori PostgreSQL.

1. Stolone

Stolone dalla società italiana Sorint.lab in relazione già citata era considerato una sorta di standard tra gli operatori per il DBMS. Questo è un progetto piuttosto vecchio: la sua prima uscita pubblica è avvenuta nel novembre 2015 (!), e il repository GitHub vanta quasi 3000 stelle e più di 40 collaboratori.

In effetti, Stolon è un ottimo esempio di architettura ponderata:

Una breve panoramica delle istruzioni PostgreSQL per Kubernetes, le nostre scelte e la nostra esperienza
Il dispositivo di questo operatore può essere trovato in dettaglio nel rapporto o documentazione del progetto. In generale, basti dire che può fare tutto quanto descritto: failover, proxy per l'accesso client trasparente, backup... Inoltre, i proxy forniscono l'accesso attraverso un servizio endpoint - a differenza delle altre due soluzioni discusse di seguito (hanno due servizi per l'accesso base).

Tuttavia, Stolone nessuna risorsa personalizzata, motivo per cui non può essere distribuito in modo tale che sia facile e veloce - "come le torte calde" - creare istanze DBMS in Kubernetes. La gestione viene effettuata tramite l'utilità stolonctl, distribuzione - tramite il grafico Helm e quelli personalizzati sono definiti in ConfigMap.

Da un lato, risulta che l'operatore non è realmente un operatore (perché non utilizza CRD). Ma d'altra parte, è un sistema flessibile che ti consente di configurare le risorse in K8 nel modo desiderato.

Riassumendo, per noi personalmente, non sembrava essere il modo migliore per iniziare un grafico separato per ogni database. Così abbiamo iniziato a cercare alternative.

2. Crunchy Data Operatore PostgreSQL

Operatore di Crunchy Data, una giovane startup americana, sembrava un'alternativa logica. La sua storia pubblica inizia con il primo rilascio nel marzo 2017, da allora il repository GitHub ha ricevuto poco meno di 1300 stelle e oltre 50 contributori. L'ultima versione di settembre è stata testata per funzionare con Kubernetes 1.15-1.18, OpenShift 3.11+ e 4.4+, GKE e VMware Enterprise PKS 1.3+.

L'architettura Crunchy Data PostgreSQL Operator soddisfa anche i requisiti dichiarati:

Una breve panoramica delle istruzioni PostgreSQL per Kubernetes, le nostre scelte e la nostra esperienza

La gestione avviene tramite l'utility pgo, tuttavia, a sua volta genera risorse personalizzate per Kubernetes. Pertanto, l'operatore ci ha soddisfatto come potenziali utenti:

  • c'è il controllo tramite CRD;
  • comoda gestione degli utenti (anche tramite CRD);
  • integrazione con altri componenti Suite contenitore dati croccante - una raccolta specializzata di immagini contenitore per PostgreSQL e utilità per lavorare con esso (inclusi pgBackRest, pgAudit, estensioni da contrib, ecc.).

Tuttavia, i tentativi di iniziare a utilizzare l'operatore da Crunchy Data hanno rivelato diversi problemi:

  • Non c'era possibilità di tolleranze: viene fornito solo nodeSelector.
  • I pod creati facevano parte della distribuzione, nonostante stessimo distribuendo un'applicazione con stato. A differenza degli StatefulSet, i deployment non possono creare dischi.

L'ultimo difetto porta a momenti divertenti: nell'ambiente di test, siamo riusciti a eseguire 3 repliche con un disco memoria locale, a seguito della quale l'operatore ha segnalato che 3 repliche funzionavano (anche se non era così).

Un'altra caratteristica di questo operatore è la sua integrazione già pronta con vari sistemi ausiliari. Ad esempio, è facile installare pgAdmin e pgBounce e in documentazione sono considerati Grafana e Prometheus preconfigurati. In un recente versione 4.5.0-beta1 notato separatamente una migliore integrazione con il progetto pgMonitor, grazie al quale l'operatore offre una visualizzazione visiva delle metriche PgSQL fuori dagli schemi.

Tuttavia, la strana scelta delle risorse generate da Kubernetes ci ha portato a trovare una soluzione diversa.

3. Operatore Zalando Postgres

I prodotti Zalando ci sono noti da molto tempo: abbiamo esperienza nell'uso di Zalenium e, ovviamente, abbiamo provato patrono è la loro popolare soluzione HA per PostgreSQL. Informazioni sull'approccio dell'azienda alla creazione Operatore Postgres ha detto uno dei suoi autori - Alexei Klyukin - in onda Postgres-Martedì #5e ci è piaciuto.

Questa è la soluzione più giovane discussa nell'articolo: il primo rilascio è avvenuto ad agosto 2018. Tuttavia, nonostante il numero limitato di rilasci formali, il progetto ha fatto molta strada, superando già la popolarità della soluzione di Crunchy Data con oltre 1300 stelle su GitHub e il numero massimo di contributori (70+).

"Sotto il cofano" di questo operatore vengono utilizzate soluzioni collaudate nel tempo:

Ecco come viene presentata l'architettura dell'operatore di Zalando:

Una breve panoramica delle istruzioni PostgreSQL per Kubernetes, le nostre scelte e la nostra esperienza

L'operatore è completamente gestito tramite Custom Resources, crea automaticamente uno StatefulSet dai container, che possono poi essere personalizzati aggiungendo vari sidecar al pod. Tutto questo è un vantaggio significativo rispetto all'operatore di Crunchy Data.

Poiché abbiamo scelto la soluzione di Zalando tra le 3 opzioni considerate, di seguito verrà presentata un'ulteriore descrizione delle sue capacità, insieme alla pratica di applicazione.

Esercitati con Postgres Operator di Zalando

La distribuzione dell'operatore è molto semplice: basta scaricare l'ultima versione da GitHub e applicare i file YAML dalla directory manifesta. In alternativa, puoi anche usare hub operatore.

Dopo l'installazione, dovresti occuparti delle impostazioni storage per log e backup. È fatto tramite ConfigMap postgres-operator nello spazio dei nomi in cui si imposta l'operatore. Con i repository configurati, puoi distribuire il tuo primo cluster PostgreSQL.

Ad esempio, la nostra distribuzione standard è simile a questa:

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

Questo manifest distribuisce un cluster di 3 istanze con un sidecar del modulo postgres_exporter, da cui raccogliamo le metriche dell'applicazione. Come puoi vedere, tutto è molto semplice e, se lo desideri, puoi creare un numero letteralmente illimitato di cluster.

Vale la pena prestare attenzione pannello web per l'amministrazione - postgres-operatore-ui. Viene fornito con l'operatore e consente di creare ed eliminare cluster, nonché di lavorare con i backup eseguiti dall'operatore.

Una breve panoramica delle istruzioni PostgreSQL per Kubernetes, le nostre scelte e la nostra esperienza
Elenco dei cluster PostgreSQL

Una breve panoramica delle istruzioni PostgreSQL per Kubernetes, le nostre scelte e la nostra esperienza
Gestione dei backup

Un'altra caratteristica interessante è il supporto API di squadre. Questo meccanismo crea automaticamente ruoli in PostgreSQL, in base all'elenco risultante di nomi utente. Successivamente, l'API ti consente di restituire un elenco di utenti per i quali i ruoli vengono creati automaticamente.

Problemi e soluzioni

Tuttavia, l'uso dell'operatore ha presto rivelato diversi inconvenienti significativi:

  1. mancanza di supporto nodeSelector;
  2. impossibilità di disabilitare i backup;
  3. quando si utilizza la funzione di creazione delle basi, i privilegi predefiniti non vengono visualizzati;
  4. periodicamente la documentazione non è sufficiente o non è aggiornata.

Fortunatamente, molti di loro possono essere risolti. Cominciamo dalla fine: problemi con documentazione.

Molto probabilmente, ti imbatterai nel fatto che non è sempre chiaro come registrare un backup e come connettere un bucket di backup all'interfaccia utente dell'operatore. Questo è menzionato nella documentazione di passaggio, ma la vera descrizione è in PR:

  1. devi fare un segreto;
  2. passarlo all'operatore come parametro pod_environment_secret_name in CRD con le impostazioni dell'operatore o in ConfigMap (a seconda di come si sceglie di installare l'operatore).

Tuttavia, come si è scoperto, al momento questo non è possibile. Ecco perché abbiamo raccolto la tua versione dell'operatore con alcuni ulteriori sviluppi di terze parti. Maggiori informazioni su di esso - vedi sotto.

Se passi i parametri all'operatore per il backup, vale a dire - wal_s3_bucket e chiavi di accesso in AWS S3, quindi it eseguirà il backup di tutto: non solo basi in produzione, ma anche messa in scena. Non ci andava bene.

Nella descrizione dei parametri di Spilo, che è il wrapper Docker di base per PgSQL quando si utilizza l'operatore, è risultato che è possibile passare un parametro WAL_S3_BUCKET vuoto, disabilitando così i backup. Inoltre, con grande gioia, ho trovato PR pronto, che abbiamo subito accettato nel nostro fork. Ora è abbastanza facile da aggiungere enableWALArchiving: false a una risorsa cluster PostgreSQL.

Sì, era possibile farlo diversamente eseguendo 2 operatori: uno per lo staging (senza backup) e il secondo per la produzione. Ma siamo riusciti a cavarcela con uno.

Ok, abbiamo imparato come trasferire l'accesso per S3 ai database e i backup hanno iniziato a entrare nello storage. Come far funzionare le pagine di backup nell'interfaccia utente dell'operatore?

Una breve panoramica delle istruzioni PostgreSQL per Kubernetes, le nostre scelte e la nostra esperienza

Nell'interfaccia utente dell'operatore, dovrai aggiungere 3 variabili:

  • SPILO_S3_BACKUP_BUCKET
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

Dopodiché, sarà disponibile la gestione del backup, che nel nostro caso semplificherà il lavoro con lo staging, consentendo di consegnare lì sezioni dalla produzione senza script aggiuntivi.

Come altro vantaggio, sono state chiamate il lavoro con l'API Teams e ampie opportunità per la creazione di database e ruoli utilizzando gli strumenti dell'operatore. Tuttavia, emergente i ruoli non avevano diritti per impostazione predefinita. Di conseguenza, un utente con diritti di lettura non può leggere nuove tabelle.

Perché? Anche se nel codice c'è necessario GRANTnon sempre vengono applicati. Ci sono 2 metodi: syncPreparedDatabases и syncDatabases. In syncPreparedDatabases - nonostante il fatto che nella sezione preparedDatabases c'è c'è una condizione defaultRoles и defaultUsers per creare ruoli, i diritti predefiniti non vengono applicati. Stiamo preparando una patch in modo che questi diritti vengano applicati automaticamente.

E l'ultimo momento nei miglioramenti che sono rilevanti per noi - toppaA che aggiunge un'affinità di nodo allo StatefulSet generato. I nostri clienti spesso preferiscono tagliare i costi utilizzando istanze spot, che chiaramente non valgono l'hosting di servizi di database. Questo problema potrebbe essere risolto attraverso tolleranze, ma la presenza di Node Affinity dà più sicurezza.

Cosa è successo?

Come risultato della risoluzione dei problemi di cui sopra, abbiamo eseguito il fork dell'operatore Postgres da Zalando in il tuo depositodove sta andando con patch così utili. E per maggiore comodità, abbiamo anche raccolto Immagine Docker.

Elenco dei PR accettati nel fork:

Sarebbe fantastico se la comunità supportasse questi PR in modo che arrivino a monte con la prossima versione dell'operatore (1.6).

Bonus! Storia di successo della migrazione di produzione

Se utilizzi Patroni, la produzione live può essere migrata all'operatore con tempi di inattività minimi.

Spilo ti consente di creare cluster in standby tramite lo storage S3 con wal-equando il log binario PgSQL viene archiviato per la prima volta in S3 e quindi espulso dalla replica. Ma cosa succede se hai no utilizzato da Wal-E nelle vecchie infrastrutture? La soluzione a questo problema è già è stato suggerito sul mozzo.

La replica logica di PostgreSQL viene in soccorso. Tuttavia, non entreremo nei dettagli su come creare pubblicazioni e abbonamenti, perché ... il nostro piano è fallito.

Il fatto è che il database aveva diverse tabelle caricate con milioni di righe, che peraltro venivano costantemente rifornite ed eliminate. Abbonamento semplice с copy_data, quando la nuova replica copia tutto il contenuto dal master, semplicemente non riusciva a tenere il passo con il master. La copia dei contenuti ha funzionato per una settimana, ma non ha mai raggiunto il master. Alla fine, ha contribuito a risolvere il problema articolo colleghi di Avito: puoi trasferire i dati utilizzando pg_dump. Descriverò la nostra versione (leggermente modificata) di questo algoritmo.

L'idea è che puoi creare un abbonamento disabilitato legato a uno slot di replica specifico e quindi correggere il numero di transazione. C'erano repliche per il lavoro di produzione. Questo è importante perché la replica aiuterà a creare un dump coerente e continuerà a ricevere le modifiche dal master.

I comandi successivi che descrivono il processo di migrazione utilizzeranno la seguente notazione per gli host:

  1. Mastercard — server di origine;
  2. replica1 - replica in streaming sulla vecchia produzione;
  3. replica2 - una nuova replica logica.

Piano di migrazione

1. Creare una sottoscrizione a tutte le tabelle nello schema nella procedura guidata public base dbname:

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

2. Creare uno slot di replica sul master:

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

3. Arrestare la replica sulla vecchia replica:

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

4. Ottieni il numero di transazione dal master:

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

5. Eseguire il dump dalla vecchia replica. Lo faremo in diversi thread, che aiuteranno ad accelerare il processo:

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

6. Carica il dump sul nuovo server:

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

7. Dopo aver scaricato il dump, è possibile avviare la replica sulla replica di streaming:

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

7. Crea una sottoscrizione su una nuova replica logica:

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. Ottieni oid abbonamenti:

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

9. Diciamo che è stato ricevuto oid=1000. Applichiamo il numero di transazione all'abbonamento:

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

10. Iniziamo la replica:

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

11. Controlla lo stato dell'abbonamento, la replica dovrebbe funzionare:

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. Dopo l'avvio della replica e la sincronizzazione dei database, è possibile effettuare il passaggio.

13. Dopo aver disabilitato la replica, è necessario correggere le sequenze. È ben descritto nell'articolo su wiki.postgresql.org.

Grazie a questo piano, il passaggio è avvenuto con ritardi minimi.

conclusione

Gli operatori Kubernetes ti consentono di semplificare varie azioni riducendole alla creazione di risorse K8s. Tuttavia, avendo raggiunto una notevole automazione con il loro aiuto, vale la pena ricordare che può anche portare una serie di sfumature inaspettate, quindi scegli saggiamente i tuoi operatori.

Dopo aver esaminato i tre operatori Kubernetes più popolari per PostgreSQL, abbiamo scelto il progetto di Zalando. E abbiamo dovuto superare alcune difficoltà con esso, ma il risultato è stato davvero piacevole, quindi abbiamo in programma di estendere questa esperienza ad altre installazioni di PgSQL. Se hai esperienza nell'utilizzo di soluzioni simili, saremo lieti di vedere i dettagli nei commenti!

PS

Leggi anche sul nostro blog:

Fonte: habr.com

Aggiungi un commento