Nella prima parte di questo articolo abbiamo configurato Vagrant per eseguire due macchine virtuali Ubuntu 14.04 Trusty Tahr, rispettivamente denominate pg
e backup
. In questa seconda parte vedremo come utilizzare Puppet per impostare e configurare un server PostgreSQL su pg
ed esegui il backup tramite Barman dal backup
casella.
Pupazzo:configurazione
Dopo aver definito le macchine come nell'articolo precedente, occorre specificare i moduli Puppet richiesti che librarian-puppet
gestirà per noi.
Sono necessari due moduli:
puppetlabs/postgresql
(http://github.com/puppetlabs/puppetlabs-postgresql/) per installare PostgreSQL supg
VMit2ndq/barman
(http://github.com/2ndquadrant-it/puppet-barman) per installare Barman subackup
Entrambi i moduli verranno installati da Puppet Forge. Per puppetlabs/postgresql
modulo, al momento dovremo utilizzare al massimo la versione 4.2.0, poiché l'ultima versione (4.3.0) sta violando il postgres_password
parametro che useremo in seguito (vedi questa richiesta pull). Creiamo un file chiamato Puppetfile
contenente questo contenuto nella directory del progetto:
forge "http://forgeapi.puppetlabs.com" mod "puppetlabs/postgresql", "<4.3.0" mod "it2ndq/barman" |
Ora possiamo installare i moduli Puppet e le loro dipendenze eseguendo:
$ librarian-puppet install --verbose |
Sebbene non sia essenziale, è preferibile utilizzare l'opzione --verbose
ogni volta librarian-puppet
viene utilizzato. Senza di esso il comando è molto silenzioso ed è utile avere i dettagli su ciò che sta facendo in anticipo. Ad esempio, senza usare --verbose
, potresti scoprire di aver perso tempo prezioso in attesa della risoluzione di un conflitto di dipendenze, per poi vedere un errore molti minuti dopo.
Al completamento con successo del comando, un modules
directory contenente il barman
e postgresql
moduli e le loro dipendenze (apt
, concat
, stdlib
) verrà creato nella nostra directory di lavoro. Inoltre, librarian-puppet
creerà il Puppetfile.lock
per identificare le dipendenze e le versioni dei moduli installati, bloccandoli per impedire futuri aggiornamenti. In questo modo, la successiva librarian-puppet install
run installerà sempre la stessa versione dei moduli invece di eventuali aggiornamenti (nel caso sia richiesto un aggiornamento, librarian-puppet update
farà il trucco).
Ora possiamo dire a Vagrant che stiamo usando un manifest Puppet per eseguire il provisioning dei server. Modifichiamo il Vagrantfile
come segue:
Vagrant.configure("2") do |config| { :pg => { :ip => '192.168.56.221', :box => 'ubuntu/trusty64' }, :backup => { :ip => '192.168.56.222', :box => 'ubuntu/trusty64' } }.each do |name,cfg| config.vm.define name do |local| local.vm.box = cfg[:box] local.vm.hostname = name.to_s + '.local.lan' local.vm.network :private_network, ip: cfg[:ip] family = 'ubuntu' bootstrap_url = 'http://raw.github.com/hashicorp/puppet-bootstrap/master/' + family + '.sh' # Run puppet-bootstrap only once local.vm.provision :shell, :inline => <<-eos if [ ! -e /tmp/.bash.provision.done ]; then curl -L #{bootstrap_url} | bash touch /tmp/.bash.provision.done fi eos # Provision with Puppet local.vm.provision :puppet do |puppet| puppet.manifests_path = "manifests" puppet.module_path = [".", "modules"] puppet.manifest_file = "site.pp" puppet.options = [ '--verbose', ] end end end end |
Con le righe che abbiamo appena aggiunto, abbiamo fornito a Vagrant le istruzioni per effettuare il provisioning delle VM utilizzando manifests/site.pp
come manifest principale e i moduli inclusi nei modules
directory. Questa è la versione finale del nostro Vagrantfile
.
Ora dobbiamo creare i manifests
directory:
$ mkdir manifests |
e scrivici una prima versione di site.pp
. Inizieremo con una configurazione molto semplice:
node backup { class { 'barman': manage_package_repo => true, } } node pg {} |
Ora possiamo avviare le macchine e vederlo su backup
c'è un server Barman con una configurazione predefinita (e nessun PostgreSQL su pg
ancora). Accediamo a backup
:
$ vagrant ssh backup |
e dai un'occhiata a /etc/barman.conf
:
# Main configuration file for Barman (Backup and Recovery Manager for PostgreSQL) # Further information on the Barman project at www.pgbarman.org # IMPORTANT: Please do not edit this file as it is managed by Puppet! # Global options [barman] barman_home = /var/lib/barman barman_user = barman log_file = /var/log/barman/barman.log compression = gzip backup_options = exclusive_backup minimum_redundancy = 0 retention_policy = retention_policy_mode = auto wal_retention_policy = main configuration_files_directory = /etc/barman.conf.d |
Il passaggio successivo è eseguire un'istanza PostgreSQL su pg
. Dobbiamo essere a conoscenza dei parametri richiesti da Barman sul server PostgreSQL, quindi dobbiamo impostare:
wal_level
almeno inarchive
livelloarchive_mode
suon
archive_command
in modo che i WAL possano essere copiati subackup
- una regola in
pg_hba.conf
per l'accesso dabackup
Tutti questi parametri possono essere facilmente impostati tramite puppetlabs/postgresql
modulo. Inoltre, sul server Barman, abbiamo bisogno di:
- una stringa di connessione PostgreSQL
- un
.pgpass
file per l'autenticazione - un comando SSH
- per eseguire lo scambio di chiavi SSH
it2ndq/barman
genera una coppia di chiavi privata/pubblica in ~barman/.ssh
. Tuttavia, lo scambio automatico delle chiavi tra i server richiede la presenza di un Puppet Master che esula dagli obiettivi di questo tutorial (farà parte della prossima puntata, che sarà incentrata sulla configurazione di un Puppet Master e del barman::autoconfigure
class) – quindi quest'ultimo passaggio verrà eseguito manualmente.
Modifichiamo il site.pp
file come segue:
node backup { class { 'barman': manage_package_repo => true, } barman::server {'test-server': conninfo => 'user=postgres host=192.168.56.221', ssh_command => 'ssh [email protected]', } file { '/var/lib/barman/.pgpass': ensure => 'present', owner => 'barman', group => 'barman', mode => 0600, content => '192.168.56.221:5432:*:postgres:insecure_password', } } node pg { class { 'postgresql::server': listen_addresses => '*', postgres_password => 'insecure_password', pg_hba_conf_defaults => false, } postgresql::server::pg_hba_rule {'Local access': type => 'local', database => 'all', user => 'all', auth_method => 'peer', } postgresql::server::pg_hba_rule {'Barman access': type => 'host', database => 'all', user => 'postgres', address => '192.168.56.222/32', auth_method => 'md5', } postgresql::server::config_entry { 'wal_level' : value => 'archive'; 'archive_mode' : value => 'on'; 'archive_command' : value => 'rsync -a %p [email protected]:/var/lib/barman/test-server/incoming/%f'; } class { 'postgresql::server::contrib': package_ensure => 'present', } } |
Dopo aver modificato il manifest, la disposizione deve essere ripetuta:
$ vagrant provision |
Con le macchine in funzione, possiamo procedere con lo scambio delle chiavi. Accediamo a pg
:
$ vagrant ssh pg |
e creiamo la coppia di chiavi per postgres
utente, utilizzando ssh-keygen
, lasciando ogni campo vuoto quando richiesto (quindi premendo sempre invio):
[email protected]:~$ sudo -iu postgres [email protected]:~$ ssh-keygen [email protected]:~$ cat .ssh/id_rsa.pub |
L'ultimo comando restituisce una lunga stringa alfanumerica che deve essere aggiunta al ~barman/.ssh/authorized_keys
file su backup
.
$ vagrant ssh backup [email protected]:~$ sudo -iu barman [email protected]:~$ echo "ssh-rsa ..." >> .ssh/authorized_keys |
Allo stesso modo, copiamo la chiave pubblica del barman
utente nelle authorized_keys
file del postgres
utente su pg
:
[email protected]:~$ cat .ssh/id_rsa.pub ssh-rsa ... [email protected]:~$ logout [email protected]:~$ logout $ vagrant ssh pg [email protected]:~$ sudo -iu postgres [email protected]:~$ echo "ssh-rsa ..." >> .ssh/authorized_keys |
A questo punto, effettuiamo una prima connessione in entrambe le direzioni tra i due server:
[email protected]:$ ssh [email protected] [email protected]:$ ssh [email protected] |
Possiamo eseguire barman check
per verificare che Barman funzioni correttamente:
[email protected]:~$ barman check all Server test-server: ssh: OK PostgreSQL: OK archive_mode: OK archive_command: OK directories: OK retention policy settings: OK backup maximum age: OK (no last_backup_maximum_age provided) compression settings: OK minimum redundancy requirements: OK (have 0 backups, expected at least 0) |
Ogni riga dovrebbe leggere "OK". Ora, per eseguire un backup, esegui semplicemente:
[email protected]:$ barman backup test-server |
Una configurazione realistica
La configurazione di Barman utilizzata finora è molto semplice, ma puoi facilmente aggiungere alcuni parametri a site.pp
e sfrutta tutte le funzionalità di Barman, come le policy di conservazione e il nuovo backup incrementale disponibile in Barman 1.4.0.
Concludiamo questo tutorial con un caso d'uso realistico, con i seguenti requisiti:
- un backup ogni notte all'01:00
- la possibilità di eseguire un Point In Time Recovery in qualsiasi momento dell'ultima settimana
- avere sempre almeno un backup disponibile
- segnalazione di un errore tramite
barman check
nel caso in cui il backup più recente sia più vecchio di una settimana - abilitazione del backup incrementale per risparmiare spazio su disco
Usiamo il file
del pupazzo risorsa per creare un .pgpass
file con i parametri di connessione e un cron
risorsa per generare il lavoro da eseguire ogni notte. Infine, modifichiamo il barman::server
per aggiungere i parametri Barman richiesti.
Il risultato finale è:
node backup { class { 'barman': manage_package_repo => true, } barman::server {'test-server': conninfo => 'user=postgres host=192.168.56.221', ssh_command => 'ssh [email protected]', retention_policy => 'RECOVERY WINDOW OF 1 WEEK', minimum_redundancy => 1, last_backup_maximum_age => '1 WEEK', reuse_backup => 'link', } file { '/var/lib/barman/.pgpass': ensure => 'present', owner => 'barman', group => 'barman', mode => 0600, content => '192.168.56.221:5432:*:postgres:insecure_password', } cron { 'barman backup test-server': command => '/usr/bin/barman backup test-server', user => 'barman', hour => 1, minute => 0, } } node pg { class { 'postgresql::server': listen_addresses => '*', postgres_password => 'insecure_password', pg_hba_conf_defaults => false, } postgresql::server::pg_hba_rule {'Local access': type => 'local', database => 'all', user => 'all', auth_method => 'peer', } postgresql::server::pg_hba_rule {'Barman access': type => 'host', database => 'all', user => 'postgres', address => '192.168.56.222/32', auth_method => 'md5', } postgresql::server::config_entry { 'wal_level' : value => 'archive'; 'archive_mode' : value => 'on'; 'archive_command' : value => 'rsync -a %p [email protected]:/var/lib/barman/test-server/incoming/%f'; } } |
Conclusione
Con 51 righe di manifest Puppet siamo riusciti a configurare una coppia di server PostgreSQL/Barman con impostazioni simili a quelle che potremmo desiderare su un server di produzione. Abbiamo unito i vantaggi di avere un server Barman per gestire i backup con quelli di avere un'infrastruttura gestita da Puppet, riutilizzabile e versionabile.
Nel prossimo e ultimo post di questa serie di articoli vedremo come utilizzare un Puppet Master per esportare risorse tra diverse macchine, consentendo così alle VM di scambiarsi i parametri necessari per il corretto funzionamento tramite il barman::autoconfigure
classe semplificando l'intero processo di configurazione.