it2ndq/barman
(parte due)Nella prima parte di questo articolo abbiamo configurato Vagrant per avviare due VM Ubuntu 14.04 Trusty Tahr, chiamate rispettivamente pg
e backup
. In questa seconda parte vedremo come utilizzare Puppet per installare e configurare un server PostgreSQL su pg
e effettuarne il backup via Barman dalla seconda macchina.
Dopo aver definito le macchine come nell’articolo precedente, occorre definire i moduli Puppet necessari, che lasceremo gestire a librarian-puppet
.
I moduli sono due:
puppetlabs/postgresql
(https://github.com/puppetlabs/puppetlabs-postgresql/) per installare PostgreSQL sulla VM pg
it2ndq/barman
(https://github.com/2ndquadrant-it/puppet-barman) per installare Barman su backup
.Per il primo useremo la versione presente su Puppet Forge, per il secondo effettueremo il clone da GitHub del progetto, per poterne sfruttare le modifiche più recenti.
Creiamo nella directory corrente un file chiamato Puppetfile
con questo contenuto:
forge "https://forgeapi.puppetlabs.com" mod "puppetlabs/postgresql" mod "it2ndq/barman", :git => "git://github.com/2ndquadrant-it/puppet-barman.git" |
Possiamo ora installare il modulo Puppet e le sue dipendenze eseguendo:
$ librarian-puppet install --verbose |
Per quanto non indispensabile, il consiglio è quello di utilizzare sempre l’opzione --verbose
ogni volta che si usa librarian-puppet
. Il comando è molto silenzioso ed è bene avere dettagli su quello che sta facendo, prima di scoprire (ad esempio) di avere buttato tempo prezioso aspettando che risolvesse senza successo un complicato conflitto di dipendenze.
Al completamento del comando, all’interno della directory corrente sarà presente la nuova directory modules
che conterrà i moduli richiesti (barman, postgresql) e le loro dipendenze (apt, concat, stdlib). Inoltre, sarà stato creato il file Puppetfile.lock
, che identifica dipendenze e versioni dei moduli installati, fissandole a protezione di aggiornamenti futuri. In questo modo, i successivi librarian-puppet install
installeranno le stesse identiche versioni definite nel Puppetfile.lock
, invece di possibili aggiornamenti.
A questo punto, aggiungiamo alla configurazione di Vagrant il fatto di utilizzare un manifesto Puppet per effettuare il provisioning dei server al termine dell’installazione di Puppet.
Modifichiamo quindi il Vagrantfile in questo modo:
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 = 'https://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 linee che abbiamo appena aggiunto, abbiamo dato a Vagrant l’istruzione di effettuare il provision delle macchine a partire dal file manifests/site.pp
e che i moduli necessari al manifesto sono da cercare all’interno della directory modules
. Il Vagrantfile
è adesso nella sua forma definitiva.
Creiamo perciò la directory manifests
all’interno della nostra directory di lavoro:
$ mkdir manifests |
Andiamo quindi a scrivere in manifests
una prima versione di site.pp
, iniziando con una configurazione di default.
node backup { class { 'barman': manage_package_repo => true, } } node pg {} |
A questo punto, avviamo le due macchine virtuali. Se le avete distrutte al termine dell’articolo precedente, tutto quello che serve è eseguire:
$ vagrant up |
Altrimenti, se le macchine sono ancora attive, occorreranno i comandi:
$ vagrant reload $ vagrant provision |
Possiamo osservare che sulla VM è stato creato un server Barman con una configurazione di base, senza alcun server configurato, connettendoci
$ vagrant ssh backup |
e controllando il contenuto del file /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 |
Procediamo adesso ad avviare un server PostgreSQL sulla macchina virtuale pg, m
odificando il site.pp
. Dobbiamo tenere presente di quali siano i parametri richiesti da Barman al server, per cui dovremo impostare:
wal_level
almeno a livello archive
archive_mode
a on
archive_command
in modo che i WAL possano essere copiati su Barmanpg_hba.conf
per consentire l’accesso al database dal server backup
Tutti questi parametri sono facilmente configurabili attraverso il modulo puppetlabs/postgresql
.
Inoltre, aggiungiamo i parametri minimi di configurazione per il backup del server PostgreSQL pg
sul nodo backup
. Avremo bisogno di:
.pgpass
per l’autenticazioneit2ndq-barman
genera automaticamente una coppia di chiavi pubblica/privata in ~barman/.ssh/
. Scambiare in automatico le chiavi richiede la presenza di un puppet master per l’esportazione delle risorse. Configurare un puppet master è fuori dagli obiettivi di questo tutorial (ma sarà parte del prossimo, incentrato proprio sull’utilizzo di un puppet master e della classe barman::autoconfigure
), quindi questo ultimo passo sarà eseguito manualmente.
Modifichiamo quindi il file site.pp
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 postgres@192.168.56.221', } 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 barman@192.168.56.222:/var/lib/barman/test-server/incoming/%f'; } class { 'postgresql::server::contrib': package_ensure => 'present', } } |
Avendo modificato la configurazione delle macchine, è necessario rieseguire il provision:
$ vagrant provision |
Quando le macchine sono su, possiamo procedere allo scambio di chiavi. Connettiamoci a pg
:
$ vagrant ssh pg |
e creiamo le chiavi per l’utente postgres
, lasciando vuoto ogni campo durante l’esecuzione di ssh-keygen
(ovvero, premendo sempre invio):
vagrant@pg:~$ sudo -iu postgres postgres@pg:~$ ssh-keygen postgres@pg:~$ cat .ssh/id_rsa.pub |
L’ultimo comando emette una lunga stringa alfanumerica che deve essere inserita nel file ~barman/.ssh/authorized_keys
su backup
.
$ vagrant ssh backup vagrant@backup:~$ sudo -iu barman barman@backup:~$ echo "ssh-rsa ..." >> .ssh/authorized_keys |
Allo stesso modo, copiamo la chiave dell’utente barman
nel file authorized_keys
dell’utente postgres
su pg:
barman@backup:~$ cat .ssh/id_rsa.pub ssh-rsa ... barman@backup:~$ logout vagrant@backup:~$ logout $ vagrant ssh pg vagrant@pg:~$ sudo -iu postgres postgres@pg:~$ echo "ssh-rsa ..." >> .ssh/authorized_keys |
A questo punto, facciamo una prima connessione in entrambe le direzioni fra i due server:
postgres@pg:$ ssh barman@192.168.56.222 barman@backup:$ ssh postgres@192.168.56.221 |
Eseguiamo un barman check
per verificare il corretto funzionamento di Barman:
barman@backup:~$ 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 risultare OK. Adesso, per effettuare un backup, basterà lanciare:
barman@backup:$ barman backup test-server
|
La configurazione di Barman effettuata finora è molto semplice, ma è facilmente possibile aggiungere pochi parametri al site.pp
per sfruttare al meglio tutte le feature di Barman, come le retention policy e il nuovo backup incrementale disponibile con Barman 1.4.0.
Concludiamo questo tutorial con un caso d’uso realistico, in cui i requisiti sono:
barman check
nel caso il backup più recente sia più vecchio di una settimana;Usiamo quindi la risorsa file
di Puppet per creare un .pgpass
con i parametri di connessione al db e la risorsa cron
per generare il job da ripetere ogni notte. Infine, modifichiamo il barman::server
per aggiungere i parametri Barman necessari.
Il risultato finale è quello che segue:
node backup { class { 'barman': manage_package_repo => true, } barman::server {'test-server': conninfo => 'user=postgres host=192.168.56.221', ssh_command => 'ssh postgres@192.168.56.221', retention_policy => 'RECOVERY WINDOW OF 1 WEEKS', 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 barman@192.168.56.222:/var/lib/barman/test-server/incoming/%f'; } } |
Con 51 righe esatte di Puppet siamo riusciti a configurare una coppia di server PostgreSQL/Barman con delle impostazioni molto simili a quelle che potremmo volere in produzione. Abbiamo così combinato i vantaggi dell’avere un server Barman che gestisce i backup a quelli di avere un’infrastruttura gestita da Puppet, riutilizzabile e versionabile.
Nella prossima e ultima parte di questa serie di articoli vedremo come utilizzare un Puppet master per approfittare della possibilità di esportare risorse fra macchine diverse e così permettere alle due macchine di scambiarsi i parametri necessari al loro corretto funzionamento tramite la classe barman::autoconfigure
.
ciao, ottimo walkthrough vagrant/puppet/barman/postgres :D
un suggerimento: per lo scambio chiavi è sempre meglio usare ssh-copy-id (http://linux.die.net/man/1/ssh-copy-id) il quale è facilmente integrabile nel provisioning puppet
gg
[…] seconda parte di questa serie di articoli abbiamo configurato via Puppet due virtual machine con un server PostgreSQL e un server Barman in […]