2015-04-04 3 views
26

Sto ancora avvolgendo la mia mente su Kubernetes e su come dovrebbe funzionare. Attualmente sto cercando di capire come modellare qualcosa come un cluster PostgreSQL con replica streaming, ridimensionamento e failover/failback automatici (pgpool-II, repmgr, scegli il tuo veleno).Come modellare un cluster di failover PostgreSQL con Docker/Kubernetes?

Il mio problema principale con l'approccio è la duplice natura di un'istanza PostgreSQL, dal punto di vista della configurazione: è un master o uno standby freddo/caldo/hot. Se aumentassi il numero di repliche, mi aspetterei che venissero tutte in standbys, quindi immagino di creare un controller di replica postgresql-standby separatamente da un pod postgresql-master. Tuttavia, mi aspetto anche che uno di questi standbys diventi un master nel caso in cui il master attuale non sia attivo, quindi è un comune controller di replica postgresql dopo tutto.

L'unica idea che ho avuto finora è di mettere la configurazione della replica su un volume esterno e gestire lo stato e le modifiche di stato al di fuori dei contenitori.

(in caso di PostgreSQL configurazione sarebbe probabilmente già essere su un volume all'interno del suo data directory, che di per sé è ovviamente qualcosa che vorrei in un volume, ma non è questo il punto)

È che l'approccio corretto, o c'è un altro modo più pulito?

+0

Potrei aiutare a guardare Kelsey Hightower's [talk] (https://youtu.be/9W-ngbpBSMM) ... – errordeveloper

+5

@errordeveloper: divertente, come viene speso il 40% del tempo demo per far funzionare Kubernetes - - rappresenta anche la mia esperienza. Il file tl; dr del video è: PostgreSQL non è costruito per essere ridimensionato in orizzontale senza sforzo di riconfigurazione, quindi dovrebbe essere un pod e non un controller di replica. –

+1

Questo è vero, anche se può essere ottimizzato con immagini VM pre-cotta e poche altre scorciatoie. – errordeveloper

risposta

0

È possibile provare PostDock, con docker-compose o Kubernetes. Attualmente ho provato nel nostro progetto con finestra mobile-composizione, con lo schema come illustrato di seguito:

pgmaster (primary node1) --| 
|- pgslave1 (node2)  --| 
| |- pgslave2 (node3) --|----pgpool (master_slave_mode stream)----client 
|- pgslave3 (node4)  --| 
    |- pgslave4 (node5) --| 

Ho testato i seguenti scenari, e tutti funzionano molto bene:

  • replica: variazioni eseguito sul nodo primario (cioè master) verrà replicato su tutti i nodi di standby (cioè slave)
  • Failover: arresta il nodo primario e un nodo di standby (ad esempio, node4) assume automaticamente il ruolo principale.
  • Prevenzione di due nodi primari: resuscita il nodo primario precedente (nodo1), nodo4 continuerà come nodo primario, mentre nodo1 sarà in sincronizzazione ma come nodo di standby.

Per quanto riguarda l'applicazione client, queste modifiche sono tutte trasparenti. Il client punta semplicemente al nodo pgpool e continua a funzionare correttamente in tutti gli scenari sopra menzionati.

Nota: In caso di problemi durante l'avvio di PostDock, è possibile provare my forked version of PostDock.

pgpool-II con watchdog

Un problema con l'architettura sopra è che pgpool è l'unico punto di guasto. Così ho anche provato a abilitare Watchdog for pgpool-II con un IP virtuale delegato, in modo da evitare il singolo punto di errore.

master (primary node1) --\ 
|- slave1 (node2)  ---\ /pgpool1 (active) \ 
| |- slave2 (node3) ----|---|      |----client 
|- slave3 (node4)  ---/  \ pgpool2 (standby)/
    |- slave4 (node5) --/ 

Ho testato i seguenti scenari, e tutti funzionano molto bene:

  • scenario normale: entrambi pgpools start up, con l'IP virtuale applicata automaticamente ad uno di loro, nel mio caso, pgpool1
  • Failover: arresto pgpool1. L'IP virtuale verrà automaticamente applicato a pgpool2, che quindi diventa attivo.
  • Avvia pgpool non riuscito: avvia nuovamente pgpool1. L'IP virtuale verrà mantenuto con pgpool2 e pgpool1 funziona ora come standby.

Per quanto riguarda l'applicazione client, queste modifiche sono tutte trasparenti. Il client punta semplicemente sull'IP virtuale e continua a funzionare correttamente in tutti gli scenari sopra menzionati.

È possibile trovare questo progetto a my GitHub repository on the watchdog branch.