Postgres martedì n. 5: «PostgreSQL e Kubernetes. CI/CD. Automazione dei test»

Postgres martedì n. 5: «PostgreSQL e Kubernetes. CI/CD. Automazione dei test»

Alla fine dello scorso anno si è svolta una nuova diretta della comunità russa di PostgreSQL #RuPostgres, durante la quale il suo cofondatore Nikolai Samokhvalov ha parlato con il CTO di "Flanta" Dmitry Stolyarov riguardo a questo DBMS nel contesto di Kubernetes.

Pubblicamo la trascrizione della parte principale di questa discussione, e su YouTube-канале сообщества è disponibile la registrazione video completa:

Riproduci video

Database e Kubernetes

НС: Oggi non parleremo di VACUUM e CHECKPOINT. Vogliamo discutere di Kubernetes. So che hai già molti anni di esperienza. Ho visto i tuoi video e alcuni li ho anche rivisti a pezzi... Andiamo subito al sodo: perché utilizzare Postgres o MySQL in K8s?

ДС: Non c'è una risposta definitiva a questa domanda e non può esserci. Ma in generale, si tratta di semplicità e convenienza… potenziali. A tutti piace il managed service.

НС: Per averlo come RDS, solo che da soli?

ДС: Sì: per averlo come RDS, ma ovunque.

НС: "Ovunque" — è un'osservazione interessante. Nelle grandi aziende tutto è situato in posti diversi. E perché, allora, se si tratta di una grande azienda, non adottare una soluzione pronta? Ad esempio, Nutanix ha le proprie soluzioni, altre aziende (VMware…) hanno il loro "RDS, solo da noi".

ДС: Ma stiamo parlando di una specifica implementazione che funzionerà solo in determinate condizioni. Se parliamo di Kubernetes, esiste una grande varietà di infrastrutture (che possono trovarsi in K8s). Fondamentalmente è uno standard per l'API al cloud…

НС: Inoltre, è gratuito!

ДС: Non è così importante. La gratuità è rilevante per un segmento di mercato piuttosto ridotto. Ciò che conta è un'altra cosa… Probabilmente ti ricordi della mia presentazione "Database e Kubernetes»?

НС: Sì.

ДС: Ho capito che è stato accolto in modo molto ambiguo. Alcune persone hanno pensato che stessi dicendo: «Ragazzi, andiamo a mettere tutti i database in Kubernetes!», mentre altri hanno deciso che si trattava di biciclette terribili. Ma quello che volevo dire era ben altro: «Guardate cosa sta succedendo, quali sono i problemi e come possiamo affrontarli. È il momento di portare i database in Kubernetes? In produzione? Beh, solo se vi piace... fare certe cose. Ma per lo sviluppo — posso dire che lo consiglio. Per lo sviluppo è molto importante la dinamicità nella creazione/rimozione degli ambienti.»

НС: Con sviluppo intendi tutti gli ambienti che non sono in produzione? Staging, QA…

ДС: Se parliamo di perf-stand, allora probabilmente no, perché lì i requisiti sono specifici. Se parliamo di casi particolari dove in staging è necessaria un'ampia DB, allora anche probabilmente no… Se è un ambiente statico, a lungo termine, quale vantaggio ci sarebbe nell'avere il database in K8s?

НС: Nessuno. Ma dove vediamo ambienti statici? L'ambiente statico diventa obsoleto già il giorno dopo.

ДС: Lo staging può essere statico. Abbiamo clienti…

НС: Sì, anch'io ho. È un grosso problema, se hai un database di 10 TB e lo staging è di 200 GB…

ДС: Ho un caso davvero interessante! In staging c'è un database di produzione, dove vengono apportate modifiche. E c'è un pulsante: «rilascialo in produzione». Queste modifiche — le differenze — vengono aggiunte (sembra, semplicemente sincronizzandosi tramite API) in produzione. È un caso molto esotico.

НС: Ho visto startup nella Silicon Valley che sono ancora su RDS o addirittura su Heroku — storie di 2-3 anni fa — e scaricano il dump sul proprio laptop. Perché il database al momento è solo di 80 GB, e sul laptop c'è spazio. Poi comprano dischi per ciascuno, così da avere 3 database e sviluppare cose diverse. A volte succede anche questo. Ho anche notato che non hanno paura di copiare da produzione a staging — dipende molto dall'azienda. Ma ho visto anche persone molto spaventate e che spesso non hanno tempo e mani. Ma prima di passare a questo tema, vorrei sentire di Kubernetes. Ho capito bene che in produzione non ce l'ha nessuno al momento?

ДС: Abbiamo piccoli database in produzione. Parliamo di volumi nell'ordine di decine di gigabyte e servizi non critici, per i quali era troppo imbarazzante creare repliche (e non c'era bisogno). E a condizione che ci sia un buon storage per Kubernetes. Questo database funzionava su una macchina virtuale — in modo conveniente su VMware, sopra un SAN. L'abbiamo messo in PV e ora possiamo spostarlo da macchina a macchina.

НС: I database di quella dimensione, fino a 100 GB, su dischi buoni e con una buona rete possono essere distribuiti in pochi minuti, giusto? La velocità di 1 Gb al secondo non è più un'eccezione.

ДС: Sì, per operazioni lineari non è un problema.

НС: Ok, riguardo a produzione dobbiamo solo pensarci. E se consideriamo Kubernetes per ambienti non-prod — come procedere? Vedo che in Zalando fanno un operatore, in Crunchy stanno sviluppando, ci sono altre opzioni. E c'è OnGres — è il nostro buon amico Alvaro dalla Spagna: non fanno solo operatore, ma un intero distributore (StackGres), dove oltre a Postgres abbiamo deciso di includere anche il backup, il proxy Envoy…

ДС: A cosa serve Envoy? Per bilanciare proprio il traffico di PostgreSQL?

НС: Sì. Cioè, lo vedono in questo modo: se prendi una distribuzione Linux e il kernel, il PostgreSQL normale è il kernel, mentre loro vogliono creare una distribuzione che sia amichevole per il cloud e possa girare in Kubernetes. Collegano i componenti (backup e simili) e li ottimizzano affinché funzionino bene.

ДС: Ottimo! Fondamentalmente, è un software per creare il proprio PostgreSQL gestito.

НС: Le distribuzioni Linux hanno sempre problemi: come fare i driver per supportare tutto l'hardware. La loro idea è che lavoreranno in Kubernetes. So che con l'operatore di Zalando abbiamo recentemente visto un legame con AWS, e questo non è molto positivo. Non dovrebbe esserci un legame con un'infrastruttura specifica - qual è il senso allora?

ДС: Non so in quale situazione specifica Zalando si sia legato, ma al momento in Kubernetes lo storage è realizzato in modo tale che non è possibile fare un backup del disco in modo generico. Recentemente, nello standard - nell'ultima versione - specifiche CSI è stata aggiunta la possibilità di snapshot, ma dove è stata implementata? Onestamente, è ancora tutto così grezzo… Proviamo CSI su AWS, GCE, Azure, vSphere, ma iniziamo a usare e si vede che non è ancora pronto.

НС: Ecco perché a volte ci si deve legare all'infrastruttura. Penso che sia ancora una fase iniziale - problemi di crescita. Domanda: cosa consiglieresti ai principianti che vogliono provare PgSQL in K8s? Quale operatore, forse?

ДС: Il problema è che per noi PostgreSQL è solo il 3%. Abbiamo un lungo elenco di software diverso in Kubernetes, non voglio nemmeno elencarli tutti. Ad esempio, Elasticsearch. Gli operatori sono tanti: alcuni si sviluppano attivamente, altri no. Abbiamo stilato una serie di requisiti che deve avere un operatore per essere preso sul serio. In un operatore specificamente per Kubernetes - non in 'un operatore per fare qualcosa nell'ecosistema di Amazon' ... In effetti, usiamo abbastanza massicciamente (= quasi da tutti i clienti) un unico operatore - per Redis (pubblicheremo presto anche un articolo su di esso).

НС: E per MySQL non c'è nulla? So che Percona... dato che ora si occupano sia di MySQL, sia di MongoDB, sia di Postgres, dovrebbero realizzare qualcosa di universale: per tutti i database, per tutti i provider di cloud.

ДС: Non abbiamo avuto il tempo di guardare gli operatori per MySQL. Per noi non è attualmente una priorità. MySQL funziona bene in standalone. Perché usare un operatore, se puoi semplicemente avviare il database... Puoi avviare un contenitore Docker con Postgres, oppure farlo in modo semplice.

НС: C'era anche questa domanda. Completamente senza operatore?

ДС: Sì, al 100% abbiamo PostgreSQL avviato senza operatore. Finora è così. Utilizziamo attivamente l'operatore per Prometheus, per Redis. Abbiamo piani per trovare un operatore per Elasticsearch - è quello che 'brucia' di più, perché vogliamo installarlo nel 100% dei casi in Kubernetes. Così come vogliamo arrivare a installare MongoDB sempre in Kubernetes. Ci sono certe esigenze che si presentano - c'è la sensazione che in questi casi si possa fare qualcosa. Ma per Postgres non abbiamo nemmeno guardato. Certo, sappiamo della esistenza di varie opzioni, ma in effetti abbiamo standalone.

Database per test in Kubernetes

НС: Passiamo al tema del testing. Come gestire le modifiche nel database - dal punto di vista della prospettiva DevOps. Ci sono microservizi, molti database, in continuazione ci sono cambiamenti. Come garantire un CI/CD normale, affinché dal punto di vista del DB tutto sia a posto. Qual è il tuo approccio?

ДС: Non può esserci una risposta unica. Ci sono diversi parametri. Il primo è la dimensione del database che desideriamo distribuire. Hai già accennato che le aziende trattano in modo diverso il fatto di avere una copia del database di produzione su dev e stage.

НС: E in ottica GDPR, penso che stiano diventando sempre più cauti... Posso dire che in Europa hanno già iniziato a multare.

ДС: Ma spesso si può scrivere un software che faccia un dump dalla produzione e lo obfuscazione. Si ottengono dati di produzione (snapshot, dump, copia binaria ...), ma sono anonimizzati. Altrimenti può trattarsi di script di generazione: possono essere fixture o semplicemente uno script che genera un grande database. Il problema è: quanto tempo ci vuole per creare l'immagine di base? E quanto tempo ci vuole per distribuirla nell'ambiente giusto?

Siamo arrivati a uno schema: se il cliente ha un set di dati di fixture (versione minima del database), allora di default li usiamo. Se parliamo di ambienti di revisione, quando abbiamo creato un branch, abbiamo distribuito un'istanza dell'app - lì distribuiamo un piccolo database. Ma è andata bene anche una variante, quando si preleva un dump dalla produzione una volta al giorno (di notte) e si costruisce un contenitore Docker con PostgreSQL e MySQL basato su questi dati caricati. Se da quest'immagine è necessario distribuire il database 50 volte, si fa abbastanza facilmente e rapidamente.

НС: Copiando semplicemente?

ДС: I dati sono memorizzati direttamente nell'immagine Docker. Cioè, abbiamo un'immagine pronta, magari di 100 GB. Grazie ai layer in Docker, possiamo distribuire rapidamente questa immagine il numero di volte necessario. È un metodo semplice, ma funziona piuttosto bene.

НС: Quindi, mentre stai testando, cambia proprio all'interno di Docker, giusto? Copy-on-write all'interno di Docker — buttiamo via e ricominciamo, tutto bene. Fantastico! E lo state già utilizzando intensamente?

ДС: Da un po'.

НС: Ci occupiamo di cose molto simili. Solo che non utilizziamo il copy-on-write di Docker, ma un altro metodo.

ДС: Non è generico. Quello di Docker funziona ovunque.

НС: Teoricamente, sì. Ma abbiamo anche dei moduli; si possono creare diversi moduli e lavorare con vari sistemi di file. Qui c'è un punto. Noi guardiamo tutto questo da una prospettiva diversa rispetto a Postgres. Ora ho visto dalla prospettiva di Docker e ho notato che tutto funziona. Ma se il database è enorme, ad esempio, 1 TB, allora tutto diventa lungo: sia le operazioni notturne, sia il mettere tutto in Docker... E se si devono mettere 5 TB in Docker... O va tutto bene?

ДС: Qual è la differenza: lo state facendo tramite dump e restore?

НС: Non è affatto necessario. I modi per generare questa immagine possono essere diversi.

ДС: Per alcuni clienti abbiamo fatto in modo che, invece di generare regolarmente l'immagine di base, la mantenessimo sempre aggiornata. È sostanzialmente una replica, ma i dati non vengono ottenuti direttamente dal master, bensì tramite un archivio. Un archivio binario, dove i WAL vengono aggiornati ogni giorno, e lì vengono anche eseguiti i backup... Questi WAL poi arrivano — con un piccolo ritardo (solo 1-2 secondi) — all'immagine di base. Da essa cloniamo in qualsiasi modo — attualmente usiamo ZFS come default.

НС: Ma con ZFS sei limitato a un nodo.

ДС: Ma con ZFS sei limitato a un solo nodo.

НС: Sì. Ma ZFS ha anche un magico send: con cui puoi inviare uno snapshot e persino (questo non l'ho ancora testato molto bene, ma...) puoi inviare la delta tra due PGDATA. Infatti, abbiamo anche un altro strumento che non abbiamo considerato molto per tali compiti. In PostgreSQL c'è pg_rewind, che funziona come un rsync 'intelligente', saltando molte cose che non è necessario controllare, perché non sono certamente cambiate. Possiamo fare una sincronizzazione rapida tra due server e ripristinare allo stesso modo.

Quindi stiamo cercando di creare, da questa prospettiva più DBA, uno strumento che permetta di fare la stessa cosa di cui parlavi: abbiamo un database, ma vogliamo testare qualcosa 50 volte, quasi contemporaneamente.

ДС: 50 volte significa che ti serve ordinare 50 istanze Spot.

НС: No, facciamo tutto su una macchina.

ДС: Ma come distribuite 50 volte, se questo è un database, diciamo, terabyte? Probabilmente avrà bisogno in modo condizionale di 256 GB di RAM?

НС: Sì, a volte serve molta memoria — è normale. Ma un esempio dalla vita reale. Su una macchina di produzione ci sono 96 core e 600 GB. In questo caso, per il database vengono utilizzati 32 core (anche 16 core a volte) e 100-120 GB di memoria.

ДС: E lì ci stanno 50 copie?

НС: Ma la copia è una, poi funziona copy-on-write (ZFS)... Ti spiego meglio.

Ad esempio, abbiamo un database da 10 TB. Abbiamo creato un disco per esso, e ZFS ha anche ridotto la sua dimensione di circa il 30-40%. Poiché non facciamo test di carico, non ci importa del tempo di risposta esatto: può essere fino a 2 volte più lento — va bene.

Diamo la possibilità a programmatori, QA, DBA, ecc. di eseguire test con 1-2 thread. Ad esempio, possono avviare una migrazione. Non richiede subito 10 core — le servono 1 backend di Postgres, 1 core. La migrazione si avvierà — può darsi, autovacuum si avvierà un'altra, a quel punto si utilizza il secondo core. Abbiamo riservato 16-32 core, quindi 10 persone possono lavorare contemporaneamente, non ci sono problemi.

Poiché fisicamente PGDATA è uguale, risulta che stiamo ingannando Postgres in realtà. La questione è: si avviano, ad esempio, 10 Postgres contemporaneamente. Qual è il problema di solito? Si impostano shared_buffers, diciamo, al 25%. Di conseguenza, sono 200 GB. Non puoi avviarne più di tre, perché la memoria finisce.

: Ma a un certo punto abbiamo capito che non è necessario: impostiamo shared_buffers a 2 GB. PostgreSQL ha effective_cache_size, e in realtà solo questo influisce su i piani. Lo impostiamo a 0,5 TB. E neanche importa che in realtà non ci siano: costruisce piani come se ci fossero.

: Quindi, quando testiamo una migrazione, possiamo raccogliere tutti i piani — vedremo come accadrà in produzione. I secondi saranno diversi (più lenti), ma i dati che leggiamo realmente e i piani stessi (quali JOIN e così via) risultano esattamente come in produzione. E parallelamente possiamo avviare un gran numero di tali controlli su una sola macchina.

ДС: Non pensi che ci siano diversi problemi qui? Il primo è che questa soluzione funziona solo con PostgreSQL. Questo approccio è molto specifico, non è generico. Il secondo è che Kubernetes (e tutto ciò che ora si sta spostando verso le tecnologie cloud) presuppone molti nodi, e questi nodi sono effimeri. E nel tuo caso si tratta di un nodo stateful, persistente. Queste cose mi creano delle contraddizioni.

НС: Primo — concordo, è una questione puramente legata a Postgres. Penso che se abbiamo un qualche tipo di IO diretto e un buffer pool quasi per tutta la memoria, tale approccio non sarà adatto — i piani saranno diversi. Ma per ora stiamo solo lavorando con Postgres e non pensiamo ad altri.

Parlando di Kubernetes. Tu stesso racconti ovunque che il nostro database è persistente. Se l'istanza cade, l'importante è mantenere il disco. Anche la nostra piattaforma è in Kubernetes, e il componente con Postgres è separato (anche se un giorno sarà integrato). Quindi funziona così: l'istanza è caduta, ma abbiamo mantenuto il suo PV e lo abbiamo semplicemente collegato a un'altra (nuova) istanza, come se non fosse successo nulla.

ДС: Dal mio punto di vista, stiamo creando pod in Kubernetes. K8s è elastico: i nodi si ordinano automaticamente secondo necessità. Il compito è semplicemente creare un pod e specificare che ha bisogno di X risorse, poi K8s si occupa del resto. Ma il supporto per lo storage in Kubernetes è ancora instabile: in 1.16, nel 1.17 questo rilascio è uscito settimane fa) queste funzionalità stanno solo diventando beta.

Passeranno sei mesi o un anno — diventerà più o meno stabile, o almeno sarà dichiarato tale. Allora la possibilità di snapshots e resize risolverà completamente il tuo problema. Perché hai un database. Sì, potrebbe non essere molto veloce, ma la velocità dipende da ciò che c'è 'sotto il cofano', perché alcune implementazioni possono gestire il copying e il copy-on-write a livello del sottosistema di storage.

НС: Qui bisogna anche aspettare che tutti i motori (Amazon, Google…) inizino a supportare questa versione — ci vuole anche un po' di tempo.

ДС: Per ora non li usiamo. Utilizziamo il nostro.

Sviluppo locale per Kubernetes

НС: Hai mai incontrato questa richiesta, quando è necessario alzare tutti i pod su una singola macchina e fare un piccolo test? Per ottenere rapidamente una prova di concetto e vedere che l'applicazione funziona in Kubernetes, senza dover dedicare molte macchine a questo. Esiste Minikube, giusto?

ДС: Mi sembra che questo caso — l'implementazione su un singolo nodo — riguardi esclusivamente lo sviluppo locale. O qualche manifestazione di tale pattern. Esiste Minikube, esiste k3s, KIND. Stiamo procedendo verso l'uso di Kubernetes in Docker. Abbiamo appena iniziato a lavorarci per test.

НС: In passato pensavo fosse un tentativo di racchiudere tutti i pod in un'unica immagine Docker. Ma si è rivelato essere qualcosa di completamente diverso. Ci sono comunque contenitori separati, pod separati — solo in Docker.

ДС: Sì. E hanno fatto una simulazione piuttosto divertente, ma il concetto è che… Abbiamo uno strumento per il deployment — werf. Vogliamo implementare una modalità — ipoteticamente werf up: 'Sollevami un Kubernetes locale'. E poi lanciare un ipotetico werf follow. Così il programmatore può modificare in IDE, mentre nel sistema è in esecuzione un processo che rileva le modifiche e ricompila le immagini, ridistribuendole nel K8s locale. Questo è il tentativo di risolvere il problema dello sviluppo locale.

Snapshots e clonazione di DB nelle realtà K8s

НС: Se torniamo al copy-on-write. Ho notato che anche i cloud offrono snapshots. Funzionano in modi diversi. Ad esempio, in GCP: hai un'istanza multi-terabyte sulla costa orientale degli Stati Uniti. Crei periodicamente snapshots. Sollevi una copia del disco da uno snapshot sulla costa occidentale — dopo pochi minuti è già tutto pronto, funziona molto velocemente, solo che il cache deve essere riempito in memoria. Ma questi cloni (snapshots) servono per 'provisionare' un nuovo volume. È fantastico quando devi creare molte istanze.

Ma per i test, mi sembra che gli snapshots, di cui parli in Docker o di cui parlo io in ZFS, btrfs e persino LVM... — permettano proprio di non creare nuovi dati reali su una singola macchina. Nel cloud dovresti anche pagare per essi ogni volta e aspettare non secondi, ma minuti (o nel caso di lazy loading, forse anche ore).

Invece, puoi ottenere questi dati in un paio di secondi, eseguire il test e scartarlo. Questi snapshots risolvono problemi diversi. Nel primo caso — per scalare e ottenere nuove repliche, nel secondo — per i test.

ДС: Non sono d'accordo. Fare una clonazione normale dei volumi è un compito del cloud. Non ho guardato la loro implementazione, ma so come lo facciamo noi su hardware. Abbiamo Ceph, in cui a qualsiasi volume fisico (RBD) puoi dire clone e ricevere in decine di millisecondi un secondo volume con le stesse caratteristiche, IOPSe così via. Bisogna capire che all'interno c'è un astuto copy-on-write. Perché il cloud non dovrebbe farlo allo stesso modo? Sono sicuro che in un modo o nell'altro stanno cercando di realizzarlo.

НС: Ma ci vorranno comunque secondi, decine di secondi, per avviare l'istanza, portare Docker e così via.

ДС: Perché è necessario avviare un'intera istanza? Abbiamo un'istanza con 32 core, una con 16... e ci stanno dentro solo alcune — ad esempio, quattro. Quando ordiniamo un quinto, verrà avviata l'istanza, e poi verrà eliminata.

НС: Sì, interessante, in Kubernetes la situazione è diversa. Abbiamo un DB non in K8s, e un'istanza. Ma per clonare un database multiterrabyte ci vogliono non più di due secondi.

ДС: Questo è fantastico. Ma il mio messaggio iniziale è che non si tratta di una soluzione generica. Sì, è ottima, ma è adatta solo a Postgres e solo su un nodo.

НС: Non è adatta solo per Postgres: i piani, come ho descritto, funzioneranno così solo per esso. Ma se non ci preoccupiamo dei piani, e abbiamo solo bisogno di dati per test funzionali, allora va bene per qualsiasi DBMS.

ДС: Molti anni fa abbiamo fatto qualcosa di simile con snapshot LVM. È un classico. Questo approccio è stato utilizzato molto attivamente. Solo che i nodi stateful sono un problema. Perché non vanno mai dimenticati, bisogna sempre tenerne conto...

НС: Non vedi qui qualche opportunità per un ibrido? Diciamo, uno stateful — è un pod, funziona per più persone (molti tester). Abbiamo un solo volume, ma grazie al filesystem i clone sono locali. Se il pod si guasta, il disco rimane — il pod si riavvia, legge le informazioni su tutti i clone, ripristina tutto e dice: «Ecco i vostri clone su queste porte, lavorateci sopra».

ДС: Tecnicamente questo significa che all'interno di Kubernetes è un pod, dentro il quale eseguiamo molti Postgres.

НС: Sì. Ha un limite: diciamo, non più di 10 persone possono lavorare contemporaneamente. Se servono 20 — avviamo un secondo pod simile. È completamente possibile clonarlo, ottenendo un secondo volume completo, su cui ci saranno gli stessi 10 «fine» clone. Non vedi questa possibilità?

ДС: Bisogna aggiungere qui la questione della sicurezza. Questa organizzazione implica che questo pod abbia privilegi elevati (capabilities), perché può eseguire operazioni non standard sul filesystem... Ma ripeto: credo che a medio termine Kubernetes sistemerà lo storage, e nei cloud sistemeranno la questione dei volumi — tutto funzionerà semplicemente. Ci sarà ridimensionamento, clonazione... C'è un volume — diciamo: «Crea un nuovo basato su quello», — e dopo un secondo e mezzo otteniamo ciò che ci serve.

НС: Non credo che ci vogliano un secondo e mezzo per diversi terabyte. Su Ceph lo fai da solo, ma stai parlando di cloud. Vai nel cloud, su EC2 fai un clone di un volume EBS di diversi terabyte e guarda quale sarà la performance. Non ci vorrà qualche secondo. Sono molto curioso di vedere quando arriveranno a quei livelli. Capisco cosa vuoi dire, ma mi permetto di non essere d'accordo.

ДС: Ok, ma ho detto che a medio termine, non a breve termine. Nei prossimi anni.

Riguardo all'operatore per PostgreSQL di Zalando

A metà di questo incontro si è unito anche Alexey Klyukin, ex sviluppatore di Zalando, che ha raccontato la storia dell'operatore PostgreSQL:

È fantastico che questo tema sia stato toccato: sia Postgres che Kubernetes. Quando abbiamo iniziato a svilupparlo in Zalando nel 2017, era un argomento che tutti volevano affrontare, ma nessuno lo faceva. Tutti già usavano Kubernetes, ma quando si chiedeva come gestire i database, anche persone come Kelsey Hightower, predicando K8s, dicevano circa quanto segue:

«Andate verso i servizi gestiti e usateli, non avviate DB in Kubernetes. Altrimenti il vostro K8s deciderà, ad esempio, di eseguire un aggiornamento, spegnerà tutti i nodi, e i vostri dati voleranno lontano lontano».

Abbiamo deciso di realizzare un operatore che, contro questo consiglio, avvierà DB Postgres in Kubernetes. E avevamo una buona ragione — Patroni. Questo è il failover automatico per PostgreSQL, fatto correttamente, cioè utilizzando etcd, consul o ZooKeeper come repository di informazioni sul cluster. Una repository che fornirà a tutti, che chiedono, ad esempio, chi è il leader attuale, le stesse informazioni — nonostante sia tutto decentralizzato — per evitare il brain split. Inoltre, abbiamo avuto immagine Docker per esso.

In realtà, la necessità di un auto failover è emersa dopo la migrazione da un data center hardware interno al cloud. Il cloud si basava su una propria soluzione PaaS (Platform-as-a-Service). Era Open Source, ma per implementarlo era necessaria una grande impegno. Si chiamava STUPS.

Inizialmente non c'era alcun Kubernetes. Cioè, quando si implementava la propria soluzione, K8s era già presente, ma così grezzo che non era adatto per la produzione. Questo era, a quanto ricordo, nel 2015 o 2016. Entro il 2017, Kubernetes era diventato più o meno maturo — c'era la necessità di migrazione verso di esso.

E avevamo già un contenitore Docker. C'era una PaaS che utilizzava Docker. Perché non provare K8s? Perché non scrivere il proprio operatore? Murat Kabilov, che è venuto da noi da Avito, ha iniziato questo come un progetto personale — "giocare" — e il progetto ha decollato.

Ma in realtà volevo parlare di AWS. Perché lì c'era storicamente del codice legato ad AWS…

Quando avviate qualcosa in Kubernetes, bisogna capire che K8s è un lavoro in corso. Si sviluppa costantemente, migliora e a volte si rompe. È necessario seguire attentamente tutte le modifiche in Kubernetes e essere pronti a tuffarsi nel suo funzionamento nei dettagli — forse più di quanto vorreste. Questo è vero per qualsiasi piattaforma su cui eseguirete i vostri DB…

Quindi, quando abbiamo creato l'operatore, avevamo Postgres che funzionava con un volume esterno (in questo caso EBS, dato che lavoravamo in AWS). Il database cresceva e a un certo punto è stato necessario effettuare un resize: ad esempio, la dimensione iniziale dell'EBS era 100 TB, il database ha raggiunto tale dimensione e ora vogliamo fare l'EBS a 200 TB. Come? Diciamo che si potrebbe fare un dump/restore su una nuova istanza, ma questo è lungo e comporta dei tempi di inattività.

Perciò volevamo un resize che aumentasse la partizione dell'EBS e poi dicesse al file system di utilizzare il nuovo spazio. E lo abbiamo fatto, ma all'epoca Kubernetes non aveva alcuna API per l'operazione di resize. Poiché lavoravamo su AWS, abbiamo scritto codice per la sua API.

Nessuno impedisce di fare lo stesso per altre piattaforme. Nell'operatore non c'è vincolo che possa essere eseguito solo su AWS, non funziona su tutto il resto. In generale, è un progetto Open Source: se qualcuno vuole accelerare l'adozione di una nuova API, è il benvenuto. Ci sono GitHub, pull request — il team di Zalando cerca di rispondere abbastanza rapidamente e promuovere l'operatore. Per quanto ne so, il progetto ha partecipato a Google Summer of Code e ad altre iniziative simili. Zalando sta lavorando molto attivamente su di esso.

P.S. Bonus!

Se siete interessati all'argomento PostgreSQL e Kubernetes, vorremmo anche farvi notare che la scorsa settimana c'è stato il prossimo Postgres Tuesday, dove Nikolai ha parlato con Alexander Kukushkin di Zalando. Il video è disponibile qui.

P.P.S.

Leggete anche nel nostro blog:

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS 🔥 Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS | ProHoster