Enmarcado en el proyecto personal que estoy desarrollando desde hace unos meses, surge la necesidad de poner en marcha un sistema que permita hacer despliegues en el entorno de desarrollo, antes de llevarlo a producción. La solución para tenerlo todo controlado y poder manejar los despliegues fácilmente en los entornos reside en el uso de herramientas como chef o puppet (si quieres ver una comparativa entre los productos clic aquí). El que uso es puppet y vamos a ver como está montada la base. Puppet requiere conectividad con todos los nodos que comprondrán la infraestructura y estos nodos deberán conocer el nombre del servidor, así que es fundamental el servicio DNS para no perdernos con las direcciones IP y reducir los problemas, que los habrá para hacer más divertido el montaje/aprendizaje.
Requisitos del servidor y el cliente
Resolución DNS y sincronización NTP, sin esto, obtendremos errores de todo tipo, los más habituales, errores de certificado en la descarga de configuraciones por parte de los clientes.
|
|
[root@puppetmaster ~]# cp /usr/share/zoneinfo/Europe/Madrid /etc/localtime [root@puppetmaster ~]# yum install -y ntpdate [root@puppetmaster ~]# ntpdate pool.ntp,org |
Establecer el repositorio
Instalación del repositorio de puppet en el sistema de los servidores, tanto en el que ejecutará puppet master como los clientes:
|
|
[root@puppetmaster ~]# rpm -vih http://yum.puppetlabs.com/el/6/products/x86_64/puppetlabs-release-6-7.noarch.rpm |
Configuración del servidor
Instalación del paquete puppetmaster y todas sus dependencias:
|
|
[root@puppetmaster ~]# yum install puppetmaster -y |
La instalación de estos paquetes generará los scrips de inicio automático en /etc/init.d que tendremos que agregar al inicio del sistema:
|
|
[root@puppetmaster puppet]# chkconfig puppetmaster on [root@puppetmaster puppet]# chkconfig --list | grep -i puppet puppetmaster 0:desactivado 1:desactivado 2:activo 3:activo 4:activo 5:activo 6:desactivado |
Por defecto la instalación del servidor no incluye la sección [master] así que vamos a crearla e introduciremos dos directivas
|
|
[master] certname = puppetmaster.mfernandez.es autosign = /etc/puppet/autosign.conf |
Ahora tenemos que decirle donde están los nodos y como se agrupan. Esto lo vamos a realizar sobre un archivo de nodos llamado nodes.pp y uno general para incluir los nodos y demás configuración, por ahora solo los nodos:
|
|
[root@puppetmaster puppet]# cd /etc/puppet/manifests [root@puppetmaster manifests]# ls nodes.pp site.pp |
El contenido de cada archivo es el siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
[root@puppetmaster manifests]# cat site.pp import "nodes" [root@puppetmaster manifests]# cat nodes.pp # ALL SERVERS node mfernandeznodes { include motd } node 'puppetclient1.mfernandez.es' inherits mfernandeznodes { } node 'puppetclient2.mfernandez.es' inherits mfernandeznodes { } node 'puppetclient3.mfernandez.es' inherits mfernandeznodes { } node 'puppetclient4.mfernandez.es' inherits mfernandeznodes { } # # # # WEB SERVERS # # # # node webservers { } node 'nginx1.mfernandez.es' inherits webservers { } node 'nginx2.mfernandez.es' inherits webservers { } # # # # DATABASE SERVERS # # # # node nosqlservers{ } node 'nosql1.mfernandez.es' inherits webservers { } node 'nosql2.mfernandez.es' inherits webservers { } |
Instalación y configuración de los clientes
Instalación del paquete puppet y todas sus dependencias:
[root@puppetclient1 puppet]# yum install puppet
Cada cliente requiere que le indiquemos cual será su nombre y para ello introduciremos en la sección [agent] del fichero de configuración /etc/puppet/puppet.conf
|
|
server = puppetmaster.mfernandez.es certname = puppetclient1.mfernandez.es |
|
|
[root@puppetclient1 puppet]# chkconfig puppet on [root@puppetclient1 puppet]# chkconfig --list | grep -i pupp puppet 0:desactivado 1:desactivado 2:activo 3:activo 4:activo 5:activo 6:desactivado |
CentOS dispone del fichero de configuración /etc/sysconfig/puppet.conf para personalizar algunas directivas sin que tengamos que editar el fichero principal de configuración de puppet /etc/puppet/puppet.conf En mi caso, he decidido hacerlo sobre el propio de puppet. Este es su contenido:
|
|
[root@puppetclient1 puppet]# cat /etc/sysconfig/puppet # The puppetmaster server #PUPPET_SERVER=puppet # If you wish to specify the port to connect to do so here #PUPPET_PORT=8140 # Where to log to. Specify syslog to send log messages to the system log. #PUPPET_LOG=/var/log/puppet/puppet.log # You may specify other parameters to the puppet client here #PUPPET_EXTRA_OPTS=--waitforcert=500 |
Iniciamos los servicios
Arrancamos el servidor y a continuación los clientes. Recomendable un less en el log del servidor para comprobar que todo va bien. Además, en el primer cliente, será interesante arrancarlo con las opciones indicadas:
|
|
[root@puppetmaster ~]# service puppetmaster start ; less /var/log/puppet/masterhttp.log [root@puppetclient1 puppet]# puppet agent --server=puppetmaster.mfernandez.es --verbose --test --waitforcert 10 |
Vamos a firmar los certificados manualmente, aunque también podemos hacer que se firmen de forma automática. A veces aparece el mensaje Notice: Did not receive certificate precisamente por no estar el certificado firmado.
|
|
[root@puppetmaster ~]# puppet cert --sign puppetclient1.mfernandez.es |
Para que se firmen los certificados automáticamente hay que agregar una directiva en el bloque [master]
|
|
autosign = /etc/puppet/autosign.conf |
Dentro de este fichero vamos a asegurar un poco la infraestructura impidiendo que nadie pueda meter un servidor en ella y se cargue de la configuración que reparte puppet
|
|
[root@puppetmaster puppet]# cat autosign.conf *.mfernandez.es |
Vamos a listar ahora los clientes que tenemos, incluido el servidor:
|
|
[root@puppetmaster manifests]# less /var/log/puppet/masterhttp.log [root@puppetmaster manifests]# puppet cert --list --all + "puppetclient1.mfernandez.es" (SHA256) D4:C4:2E:22:21:A4:10:22:3E:20:7F:B2:0D:C4:AF:2C:80:1F:C5:96:9D:5F:A8:8B:2D:73:30:A1:79:8F:DE:0A + "puppetclient2.mfernandez.es" (SHA256) 56:2D:8D:5B:42:86:5B:15:EA:2F:10:D6:B2:47:67:FD:27:A5:4F:7B:02:24:B3:C1:93:8E:87:B1:4C:0F:3E:A9 + "puppetmaster.mfernandez.es" (SHA256) D6:1C:35:AD:72:63:80:59:F2:4B:99:09:F6:69:C1:C7:57:3E:7D:02:A6:3F:64:5D:2D:48:AC:D1:A6:BF:48:B9 (alt names: "DNS:puppetmaster", "DNS:puppetmaster.mfernandez.es") |
Ahora veamos qué podemos hacer con el “cacharro”.
Para distribuir archivos, paquetes y ejecutar acciones, debemos crear un módulo que nos permita hacer lo que necesitemos.
Los módulos su ubican en la ruta /etc/puppet/modules/ y siguen la estructura de directorios: manifests templates y files. Aunque no siempre requiere de todos los directorios, pero sí del principal, manifests.
En nuestro caso, vamos crear un archivo para distribuirlo a los clientes y nos servirá como ejemplo para ver el lenguaje usado para la construcción de estos archivos y como no, usaremos el famoso motd para el ejemplo.
El primer paso será la creación de un módulo que llamaremos motd
|
|
[root@puppetmaster modules]# /etc/puppet/modules/motd/manifests -p |
Ahora vamos al directorio manifests y creamos un archivo init.pp con el siguiente contenido
|
|
class motd { file { "/etc/motd": owner => root, group => root, mode => 644, source => "puppet:///modules/motd/motd", } } |
Necesitamos colocar en el directorio files un archivo llamado motd con el contenido que deseamos mostrar en los inicios de sesión de los servidores a los que se repartirá.
|
|
[root@puppetmaster modules]# echo "Welcome" > /etc/puppet/modules/motd/files/motd |
Trabajar con un sistema como puppet nos da la posibilidad de repartir software a todos los nodos o simplemente, a los nodos que deseemos. Será sobre el archivo nodes.pp creado al inicio donde tendremos que indicar sobre qué nodos tendrá que ejecutar el reparto de archivos.
reload del servidor puppetmaster
Ahora el proceso repartirá automáticamente el archivo entre los clientes que pertenezcan al grupo mfernandeznodes
Para la siguiente entrada veremos como hacer toda la infraestructura un poco más “visual”
Referencias: http://docs.puppetlabs.com/puppet/