Dans la première partie de cet article, nous avons configuré Vagrant pour exécuter deux machines virtuelles Ubuntu 14.04 Trusty Tahr, respectivement appelées pg
et backup
. Dans cette seconde partie nous verrons comment utiliser Puppet pour mettre en place et configurer un serveur PostgreSQL sur pg
et sauvegardez-le via Barman à partir de la backup
boîte.
Marionnette :configuration
Après avoir défini les machines conformément à l'article précédent, nous devons spécifier les modules Puppet requis que librarian-puppet
gérera pour nous.
Deux modules sont requis :
puppetlabs/postgresql
(http://github.com/puppetlabs/puppetlabs-postgresql/) pour installer PostgreSQL sur lepg
MVit2ndq/barman
(http://github.com/2ndquadrant-it/puppet-barman) pour installer Barman enbackup
Les deux modules seront installés à partir de Puppet Forge. Pour puppetlabs/postgresql
module, nous devrons utiliser la version 4.2.0 au plus pour le moment, car la dernière version (4.3.0) casse le postgres_password
paramètre que nous utiliserons plus tard (voir cette pull request). Créons un fichier appelé Puppetfile
contenant ce contenu dans le répertoire du projet :
forge "http://forgeapi.puppetlabs.com" mod "puppetlabs/postgresql", "<4.3.0" mod "it2ndq/barman" |
Nous pouvons maintenant installer les modules Puppet et leurs dépendances en lançant :
$ librarian-puppet install --verbose |
Bien que non indispensable, il est préférable d'utiliser l'option --verbose
à chaque fois librarian-puppet
est utilisé. Sans cela, la commande est très silencieuse et il est utile d'avoir des détails sur ce qu'elle fait à l'avance. Par exemple, sans utiliser --verbose
, vous découvrirez peut-être que vous avez perdu un temps précieux à attendre la résolution d'un conflit de dépendance, pour voir une erreur plusieurs minutes plus tard.
Une fois la commande terminée avec succès, un modules
répertoire contenant le barman
et postgresql
modules et leurs dépendances (apt
, concat
, stdlib
) sera créé dans notre répertoire de travail. De plus, librarian-puppet
créera le Puppetfile.lock
fichier pour identifier les dépendances et les versions des modules installés, en les épinglant pour empêcher de futures mises à jour. De cette façon, l'librarian-puppet install
suivante les exécutions installeront toujours la même version des modules au lieu d'éventuelles mises à niveau (au cas où une mise à niveau serait nécessaire, librarian-puppet update
fera l'affaire).
Nous pouvons maintenant dire à Vagrant que nous utilisons un manifeste Puppet pour provisionner les serveurs. Nous modifions le Vagrantfile
comme suit :
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 |
Avec les lignes que nous venons d'ajouter, nous avons donné à Vagrant les instructions pour provisionner les machines virtuelles à l'aide de manifests/site.pp
comme manifeste principal et les modules inclus dans les modules
annuaire. Ceci est la version finale de notre Vagrantfile
.
Nous devons maintenant créer les manifests
répertoire :
$ mkdir manifests |
et écrivez-y une première version de site.pp
. Nous allons commencer par une configuration très basique :
node backup { class { 'barman': manage_package_repo => true, } } node pg {} |
Nous pouvons maintenant démarrer les machines et voir cela sur backup
il y a un serveur Barman avec une configuration par défaut (et pas de PostgreSQL sur pg
encore). Connectons-nous à backup
:
$ vagrant ssh backup |
et jetez un oeil à /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 |
L'étape suivante consiste à exécuter une instance PostgreSQL sur pg
. Nous devons être conscients des paramètres requis par Barman sur le serveur PostgreSQL, nous devons donc définir :
wal_level
au moins àarchive
niveauarchive_mode
àon
archive_command
afin que les WAL puissent être copiés sur labackup
- une règle dans
pg_hba.conf
pour l'accès depuis labackup
Tous ces paramètres peuvent être facilement définis via puppetlabs/postgresql
module. De plus, sur le serveur Barman, nous avons besoin de :
- une chaîne de connexion PostgreSQL
- un
.pgpass
fichier d'authentification - une commande SSH
- pour effectuer l'échange de clé SSH
it2ndq/barman
génère une paire de clés privée/publique dans ~barman/.ssh
. Cependant, l'échange automatique des clés entre les serveurs nécessite la présence d'un Puppet Master ce qui dépasse les objectifs de ce tutoriel (cela fera partie du prochain tome, qui portera sur la mise en place d'un Puppet Master et du barman::autoconfigure
class) – cette dernière étape sera donc effectuée manuellement.
Nous éditons le site.pp
fichier comme suit :
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', } } |
Après avoir modifié le manifeste, la provision doit être réexécutée :
$ vagrant provision |
Les machines étant en marche, nous pouvons procéder aux échanges de clés. Nous nous connectons à pg
:
$ vagrant ssh pg |
et nous créons la paire de clés pour le postgres
utilisateur, en utilisant ssh-keygen
, en laissant chaque champ vide lorsque vous y êtes invité (en appuyant toujours sur Entrée) :
[email protected]:~$ sudo -iu postgres [email protected]:~$ ssh-keygen [email protected]:~$ cat .ssh/id_rsa.pub |
La dernière commande génère une longue chaîne alphanumérique qui doit être ajoutée au ~barman/.ssh/authorized_keys
fichier sur backup
.
$ vagrant ssh backup [email protected]:~$ sudo -iu barman [email protected]:~$ echo "ssh-rsa ..." >> .ssh/authorized_keys |
De même, on copie la clé publique du barman
utilisateur dans les authorized_keys
fichier du postgres
utilisateur sur 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 ce stade, nous établissons une première connexion dans les deux sens entre les deux serveurs :
[email protected]:$ ssh [email protected] [email protected]:$ ssh [email protected] |
Nous pouvons exécuter la barman check
pour vérifier que Barman fonctionne correctement :
[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) |
Chaque ligne doit indiquer "OK". Maintenant, pour effectuer une sauvegarde, exécutez simplement :
[email protected]:$ barman backup test-server |
Une configuration réaliste
La configuration de Barman utilisée jusqu'à présent est très simple, mais vous pouvez facilement ajouter quelques paramètres à site.pp
et profitez de toutes les fonctionnalités de Barman, telles que les politiques de rétention et la nouvelle sauvegarde incrémentielle disponible dans Barman 1.4.0.
Nous concluons ce tutoriel avec un cas d'utilisation réaliste, avec les exigences suivantes :
- une sauvegarde tous les soirs à 1h00
- la possibilité d'effectuer une récupération ponctuelle à n'importe quel moment de la semaine dernière
- avoir toujours au moins une sauvegarde disponible
- signaler une erreur via
barman check
si la sauvegarde la plus récente date de plus d'une semaine - activation de la sauvegarde incrémentielle pour économiser de l'espace disque
Nous utilisons le file
Puppet ressource pour créer un .pgpass
fichier avec les paramètres de connexion et un cron
ressource pour générer le travail à exécuter chaque nuit. Enfin, nous éditons le barman::server
pour ajouter les paramètres Barman requis.
Le résultat final est :
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'; } } |
Conclusion
Avec 51 lignes de manifeste Puppet, nous avons réussi à configurer une paire de serveurs PostgreSQL/Barman avec des paramètres similaires à ceux que nous pourrions souhaiter sur un serveur de production. Nous avons combiné les avantages d'avoir un serveur Barman pour gérer les sauvegardes avec ceux d'avoir une infrastructure gérée par Puppet, réutilisable et versionnable.
Dans le prochain et dernier post de cette série d'articles nous verrons comment utiliser un Puppet Master pour exporter des ressources entre différentes machines, permettant ainsi aux VMs d'échanger les paramètres nécessaires au bon fonctionnement via le barman::autoconfigure
classe facilitant l'ensemble du processus d'installation.