En la primera parte de este artículo configuramos Vagrant para ejecutar dos máquinas virtuales Ubuntu 14.04 Trusty Tahr, llamadas respectivamente pg
y backup
. En esta segunda parte, veremos cómo usar Puppet para instalar y configurar un servidor PostgreSQL en pg
y haz una copia de seguridad a través de Barman desde la backup
caja.
Marioneta:configuración 
Después de definir las máquinas según el artículo anterior, debemos especificar los módulos Puppet necesarios que librarian-puppet
administrará por nosotros.
Se requieren dos módulos:
puppetlabs/postgresql
(http://github.com/puppetlabs/puppetlabs-postgresql/) para instalar PostgreSQL enpg
máquina virtualit2ndq/barman
(http://github.com/2ndquadrant-it/puppet-barman) para instalar Barman enbackup
Ambos módulos se instalarán desde Puppet Forge. Para puppetlabs/postgresql
módulo, tendremos que usar la versión 4.2.0 como máximo en este momento, ya que la última versión (4.3.0) está rompiendo la postgres_password
parámetro que usaremos más adelante (ver esta solicitud de extracción). Vamos a crear un archivo llamado Puppetfile
que contiene este contenido en el directorio del proyecto:
forge "http://forgeapi.puppetlabs.com" mod "puppetlabs/postgresql", "<4.3.0" mod "it2ndq/barman" |
Ahora podemos instalar los módulos de Puppet y sus dependencias ejecutando:
$ librarian-puppet install --verbose |
Aunque no es imprescindible, es preferible utilizar la opción --verbose
cada vez librarian-puppet
se usa Sin él, el comando es muy silencioso y es útil tener detalles sobre lo que está haciendo de antemano. Por ejemplo, sin usar --verbose
, es posible que descubra que ha perdido un tiempo precioso esperando que se resuelva un conflicto de dependencia, solo para ver un error muchos minutos después.
Al completar con éxito el comando, un modules
directorio que contiene el barman
y postgresql
módulos y sus dependencias (apt
, concat
, stdlib
) se creará en nuestro directorio de trabajo. Además, librarian-puppet
creará el Puppetfile.lock
archivo para identificar dependencias y versiones de los módulos instalados, fijándolos para evitar futuras actualizaciones. De esta forma, la librarian-puppet install
subsiguiente las ejecuciones siempre instalarán la misma versión de los módulos en lugar de posibles actualizaciones (en caso de que se requiera una actualización, librarian-puppet update
hará el truco).
Ahora podemos decirle a Vagrant que estamos usando un manifiesto de Puppet para aprovisionar los servidores. Alteramos el Vagrantfile
de la siguiente manera:
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 las líneas que acabamos de agregar, le hemos dado a Vagrant las instrucciones para aprovisionar las máquinas virtuales usando manifests/site.pp
como manifiesto principal y los módulos incluidos en los modules
directorio. Esta es la versión final de nuestro Vagrantfile
.
Ahora tenemos que crear los manifests
directorio:
$ mkdir manifests |
y escribe en él una primera versión de site.pp
. Comenzaremos con una configuración muy básica:
node backup { class { 'barman': manage_package_repo => true, } } node pg {} |
Ahora podemos iniciar las máquinas y ver eso en backup
hay un servidor Barman con una configuración predeterminada (y no PostgreSQL en pg
aún). Iniciemos sesión en backup
:
$ vagrant ssh backup |
y echa un vistazo 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 |
El siguiente paso es ejecutar una instancia de PostgreSQL en pg
. Debemos conocer los parámetros requeridos por Barman en el servidor PostgreSQL, por lo que debemos configurar:
wal_level
al menos enarchive
nivelarchive_mode
aon
archive_command
para que los WAL se puedan copiar enbackup
- una regla en
pg_hba.conf
para acceder desdebackup
Todos estos parámetros se pueden configurar fácilmente a través de puppetlabs/postgresql
módulo. Además, en el servidor de Barman, necesitamos:
- una cadena de conexión de PostgreSQL
- un
.pgpass
archivo para autenticación - un comando SSH
- para realizar el intercambio de claves SSH
it2ndq/barman
genera un par de claves privadas/públicas en ~barman/.ssh
. Sin embargo, el intercambio automático de claves entre los servidores requiere la presencia de un Puppet Master, lo que va más allá de los objetivos de este tutorial (será parte de la próxima entrega, que se centrará en la configuración de un Puppet Master y el barman::autoconfigure
clase) – por lo tanto, este último paso se realizará manualmente.
Editamos el site.pp
archivo de la siguiente manera:
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', } } |
Habiendo cambiado el manifiesto, la disposición debe volver a ejecutarse:
$ vagrant provision |
Con las máquinas funcionando, podemos proceder con los intercambios de llaves. Iniciamos sesión en pg
:
$ vagrant ssh pg |
y creamos el par de llaves para el postgres
usuario, usando ssh-keygen
, dejando todos los campos vacíos cuando se le solicite (siempre presionando Intro):
[email protected]:~$ sudo -iu postgres [email protected]:~$ ssh-keygen [email protected]:~$ cat .ssh/id_rsa.pub |
El último comando genera una cadena alfanumérica larga que debe agregarse al ~barman/.ssh/authorized_keys
archivo en backup
.
$ vagrant ssh backup [email protected]:~$ sudo -iu barman [email protected]:~$ echo "ssh-rsa ..." >> .ssh/authorized_keys |
Del mismo modo, copiamos la clave pública del barman
usuario en las authorized_keys
archivo del postgres
usuario en 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 |
En este punto, hacemos una primera conexión en ambas direcciones entre los dos servidores:
[email protected]:$ ssh [email protected] [email protected]:$ ssh [email protected] |
Podemos ejecutar barman check
para verificar que Barman funciona correctamente:
[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) |
Cada línea debe decir "OK". Ahora, para realizar una copia de seguridad, simplemente ejecute:
[email protected]:$ barman backup test-server |
Una configuración realista
La configuración de Barman utilizada hasta ahora es muy simple, pero puede agregar fácilmente algunos parámetros a site.pp
y aproveche todas las funciones de Barman, como las políticas de retención y la nueva copia de seguridad incremental disponible en Barman 1.4.0.
Concluimos este tutorial con un caso de uso realista, con los siguientes requisitos:
- una copia de seguridad todas las noches a la 1:00 a.m.
- la posibilidad de realizar un Point In Time Recovery a cualquier momento de la última semana
- tener siempre al menos una copia de seguridad disponible
- informar un error a través de
barman check
en caso de que la copia de seguridad más reciente tenga más de una semana - habilitar la copia de seguridad incremental para ahorrar espacio en disco
Usamos el archivo file
de Puppet recurso para crear un .pgpass
archivo con los parámetros de conexión y un cron
recurso para generar el trabajo para ejecutar cada noche. Finalmente, editamos el barman::server
para agregar los parámetros necesarios de Barman.
El resultado final es:
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'; } } |
Conclusión
Con 51 líneas del manifiesto de Puppet, logramos configurar un par de servidores PostgreSQL/Barman con configuraciones similares a las que podríamos desear en un servidor de producción. Hemos combinado las ventajas de tener un servidor Barman para manejar copias de seguridad con las de tener una infraestructura administrada por Puppet, reutilizable y versionable.
En la próxima y última publicación de esta serie de artículos, veremos cómo usar un Puppet Master para exportar recursos entre diferentes máquinas, lo que permite que las máquinas virtuales intercambien los parámetros necesarios para el correcto funcionamiento a través de barman::autoconfigure
clase que facilita todo el proceso de configuración.