Configurando diversas máquinas virtuales y vigilarlas con puppet

Este sera mi primer post,

Les explico en el trabajo, producción consta de diversas máquinas (usan ubuntu), en las cuales corren diversas cosas:

nginx

haproxy

uwsgi

python

Usualmente ocurren problemas que hacen que se caiga todo y eso causa mucha molestia, ya que la mayoría de las cosas para levantarlas de vuelta, es necesario hacerlo mano.

Por ello se decidió usar alguna herramienta de administración automática, pero primero se tenía que montar el ambiente de pruebas. Se uso VirtualBox.

Se hizó lo siguiente:

  1. Se creó una imagen base
  2. La máquina donde se colocan las máquinas virtuales no tiene X, por lo que todo se hizo por cónsola, cosa que era necesaria ya que la idea es hacer un shell script que teniendo la imagen base cree el resto de las cosas. En las máquinas creadas se agregó la clave pública, que es la misma en todas las máquinas creadas, en .ssh/authorized_keys de forma que no preguntara el password a la hora de usar ssh y además se quitó la necesidad de tener que colocar clave para hacer sudo. Tardó un buen rato ver la manera más eficaz y sencilla de crear las cosas mediante VirtualBox (se copia el disco duro, el archivo .vdi),  además lograr darle las capacidad de que tomen ip propia de la red usando la configuración bridged . El problema es que hay que eliminar un archivo en /etc/udev/rules.d/70-net… (no me acuerdo bien), de forma que tomaran una macadress única y el servidor dhcp diera ip distintas. Luego cada una se le agregan los hosts a /etc/hosts para que cada una se comunicara con las otra sin la necesidad de colocar alguna ip.
  3. A cada máquina se le creo un script que la configurar con las consas necesarias. También se tuvo que crear 3 servicios, que reiniciaran diversas cosas que no corren como demonios, eso también robó un buen rato, la mejor forma de correr programas como demonios es start-stop-daemon, permite darle toda la configuración necesaria.
  4. Ya con las máquinas corriendo las cosas, la tarea era ver que herramienta usar para la administración automática usar. Existen varias. Se empezó a leer de CFEngine, la cual es conocida y es muy capaz. Estuve un buen rato leyendo su documentación y todo el mundo la pintaba como una maravilla, cosa que no dudo. Pero debo decir que la documentación es muy básica y mala, no me agradó en nada. El lenguaje de programación que usa, está basado en la teoría de promesas. Éste es no intuitivo y complicado en su forma de uso. Tiene cosas muy complejas que se pueden hacer con el. Pero lo que menos me gustó, fue que todos los ejemplos que conseguí eran para probar y no lo que buscaba:  algo que estuviera cada cierto tiempo vigilando el sistema y lo recuperará, avisando de todas formas que paso algo.  Leí y si tiene la capacidad, pero no conseguí un ejemplo práctico.
  5. Al ver no lograr nada, decidí tomar otro camino usando otra herramienta. Me tope con otras dos muy usadas: chef y puppet. Ambas están escritas en ruby. Busque full información de ambas. Unos amaban chef y otro puppet. A la final tome la decisión de usar puppet por diversas razones: el lenguaje es MUY fácil, es MUY usado y esta apoyado por google y otras compañías. Chef recién salió, y fue creado por una persona que estuvo involucrado con puppet, pero sentía que le faltaba.  Me parece algo complejo también además, y por no se muy viejo, podía tener falta de documentación.

Configurando puppet

Puppet es super fácil de configurar. Su arquitectura consta de dos componentes:

  • Servidor(es) maestro(s)
  • Cliente(s)

Lo primero es instalar las cosas en cada máquina.

Configurando el servidor maestro

Instala lo siguiente:

aptiude install puppetmaster

Luego edita el archivo /etc/puppet/fileserver.conf agregando que direcciones de ips quieres permitir.

Een mi caso: allow 192.168.24.0/24. (ejecuté el comando sed -i ’12s/#  allow 192.168.0.0\/24/allow 192.168.24.0\/24/’  /etc/puppet/fileserver.conf)

Finalmente a edita /etc/puppet/puppet.conf y agrega al final las siguientes líneas:

certname=servidormaestro

autosign=false

Ésta última anda por default, pero para estar seguro. Eso es para que se tenga que certificar a los nodos.

Configurando los clientes

Instala lo siguiente:

sudo apitude install puppet

Luego edita el /etc/puppet/puppet.conf

En la sección [main] agrega

server=servidormaestro

runinterval=segundos

Se puede ejecutar:

sudo sed -i '/\[main\]/a\server=servidormaestro' /etc/puppet/puppet.conf
sudo sed -i '/server=servidormaestroa\runinterval=60' /etc/puppet/puppet.con

Y agrega la siguiente sección:

[agent]

certaname=nombre del cliente

Puedes ejecutar:

sudo sh -c "echo \"[agent]\ncertname=${NAME}\" >> /etc/puppet/puppet.conf"

Ésta última para indicar cada cuantos segundos uno quiere que puppet se ejecute.

Recuerda ejecutar lo siguiente:

sudo sed -i 's/START=no/START=yes/g' /etc/default/puppet

Agregando los certificados

Luego de un rato los clientes hacen una petición al sevidor y se va a emitir un falló. Éste sucede porque puppet usa certificados y el servidor debe agregar a los clientes. Para ello primero en los clientes ejecuta:

sudo service puppet stop
sudo puppetd --waitforcert 30 -v
sudo service puppet start

Después en el servidor

for mc in `sudo puppetca --list | sed 's/([A-Z0-9:]*)//g'`
do
 sudo puppetca --sign ${mc}
do

Probando

En el servidor crea las carpetas /etc/puppet/modules/nginx/manifests (sudo mkdir -p /etc/puppet/modules/nginx/manifests) . Ahí crea el archivo init.pp (si tiene que ser este nombre sino no lo importa). Si quieres colocarle el nombre que desee debes importarlo así include ngnix::nombre y tener el archivo dentro de /etc/puppet/modules/nginx/manifests

Ahí coloca lo siguiente:

class nginx
{
 package
 {
    "nginx":
     ensure => installed
 }
 service
 {
     "nginx":
     ensure => running,
     hasrestart => "true",
     enable => "true",
 }
}

Luego en /etc/puppet/manifests crea dos archivos nodes.pp y site.pp (ambos son convención de puppet)

En nodes colocas como el va a mapear los nodos que se conoecten. Supongamos que la máquina que queremos que reinicie el nginx si se cae se llama, clienteweb. Para ello se coloca lo siguiente en el archivo:

node /^clienteweb/
{
 include nginx
}

Algo muy bueno es que se pueden colocar expresiones regulares, lo que facilita muchísimo.

Finalmente en site.pp colóca lo siguiente:

import "nodes.pp"

Ahora procede a probar que las cosas anden bien, para ellos puede tumbar el servicio puppet y correr puppetd -t, que es para hacer pruebas. Algo muy bueno ademas es que puppet tiene opción de debugeo (-debug), cosa fenomenal.

En teoría si configuraste todo como debías si tumbas los sevicios en clienteweb, despues del tiempo que colocaste, este debe reiniciarse.

Espero que esto sea de ayuda,  hasta luego