Administración centralizada de nodos con Puppet

Hace unos días Steve decía que no había buena documentación sobre Puppet. En ese momento estaba terminando las pruebas en una red grande y me decidí a escribir esto, espero que sea útil.

Introducción

A diferencia de hace un par de años, actualmente hay muchas aplicaciones maduras que le hacen la vida más fácil a un administrador de sistemas en una red compuesta por equipos Linux. En casi cualquier red administrada, sin importar su tamaño, resulta muy útil implementar un administrador centralizado de configuraciones y nodos.

Muchas personas por allí utilizan CFEngine, que es un software bastante útil sin duda, pero desde hace aproximadamente un mes he trabajado con un servidor en producción de Puppet, un administrador de nodos híbridos bastante avanzado, y con un deploy time inferior a CFEngine.

En esta red (~5000 nodos en ubicaciones geográficamente dispersas) resulta crítico minimizar el tiempo que un representante de soporte técnico debe pasar enfrente de cada equipo haciendo tareas de configuración. Eso descarta de lleno a Windows, que es muy poco enterprise friendly en este campo, tomando mucho tiempo para instalar y una vez instalado entregando una cantidad inútil de aplicaciones que necesitan más configuración.

A continuación, muchos de los problemas de configuración fueron resueltos con la realización de un sistema operativo propio, basado en Linux, que automatiza la mayor parte de las actividades de configuración. Eso está bien (y más cuando ese SO es 100% compatible con Debian, cumple con el Policy y usa los mecanismos de Debian para branding) pero es un error mental pensar que eso te va a resolver todos tus problemas (es por eso que muchos proyectos de distribuciones “nacionales” y “corporativas” fallan)

En mi caso, Puppet demostró ser una aplicación completamente adaptada a la filosofía de lo que queríamos hacer: hacer una instalación painless y enviar actualizaciones, cambios y configuraciones particulares sin requerir la presencia de un recurso humano físicamente en el equipo.

¿Qué es Puppet?

Puppet está escrito en Ruby, es realmente muy ligero y envía instrucciones a sus nodos a través de XML-RPC sobre SSL. Puppet es una aplicación compuesta de un conjunto de elementos que funcionan de forma integral: un servidor, un servicio para los clientes, un lenguaje declarativo y un sistema de levantamiento de información (Facter, del cual hablaremos luego y sirve para el plantillaje de Puppet). El servidor (o puppetmaster en la jerga de Puppet) define a través del lenguaje declarativo de Puppet los estados (¡y no las instrucciones!) que se desean en los nodos.

El cliente, simplemente puppet, recibe esa definición de estados desde el servidor y a través de un conjunto de providers genera instrucciones que traduce al lenguaje de la máquina. De esta forma es trivial escribir algo como:

package { "mysql-server":
   ensure => installed
}

Y de esta forma garantizar que el paquete mysql-server estará instalado en todos los nodos, sin importar si utilizan sistemas basados en APT, RPM, ports de BSD (FreeBSD, Darwin), autoinstalables de Apple, Portage o Solaris. Lo mismo ocurre con definiciones de servicios, tareas programadas, manejo de usuarios y grupos, etc., que permite la abstracción a través de un lenguaje declarativo y su traducción a las instrucciones locales mediante las mejores prácticas de cada sistema.

Instalación

Tanto en Debian como en Ubuntu Puppet está disponible para su instalación desde los repositorios oficiales. La aplicación está compuesta por dos paquetes binarios: puppet y puppetmaster. El primero está diseñado para su instalación en los nodos (los clientes) y el segundo para su instalación en los servidores.

puppet depende de ruby, libxmlrpc-ruby, libopenssl-ruby, adduser, facter y lsb-base. puppetmaster depende de ruby, puppet, facter y lsb-base. En Debian, puppet utiliza Ruby 1.8, pero me parece que se podría recompilar para usar 1.9 sin demasiados traumas (y, probablemente, las versiones en Sid ya lo hagan)

Configuración

En el cliente, simplemente necesitamos especificar la dirección del servidor puppetmaster en el archivo /etc/puppet/puppet.conf:

  [puppet]
  server=mi-servidor
  ... resto del archivo ...

Asegúrese de que el nombre del servidor sea accesible desde la red. Si no especifica un servidor, el cliente Puppet contactará a un equipo llamado puppet cada 30 minutos.

Existen otros factores que deben ser configurados en un cliente Puppet para su funcionamiento en producción, por ejemplo el intervalo de contacto con el puppetmaster (la variable de configuración runinterval, especificada en segundos — tenga cuidado con especificar tiempos demasiado pequeños) y las llaves y certificados X.509 para identificarse con el puppetmaster que se manejan con la aplicación puppetca

Puede consultar la Configuration Reference si desea información adicional para esto.

La configuración del servidor consta de dos fases: generación y mantenimiento del site manifest y generación y mantenimiento de las clases e instrucciones

El site manifest (manifiesto del sitio) es el archivo principal que define como se comportará el servidor Puppet. En general, especifica el conjunto de funciones que se ejecutará en los nodos de la red. Se pueden especificar distintos conjuntos de funciones para todos los nodos (palabra clave host default) y nodos específicos (palabra clave host NOMBRE_EQUIPO)

Un ejemplo de /etc/puppet/manifests/site.pp:

  import "classes/*"
  node default {
          include prueba
  }

En este ejemplo, se importan todos los archivos (terminados en .pp) disponibles bajo el directorio /etc/puppet/manifests/classes y posteriormente se declara que para todos los nodos, se deberá incluir el archivo classes/prueba.pp.

En la sección anterior incluimos el archivo classes/prueba.pp. Este archivo, que hemos diseñado a manera de prueba, contiene:

  class prueba {
     file { "/tmp/somefile":
      ensure => exists,
      owner  => "root",
     }
  }

En este archivo definimos la clase prueba, que contiene una definición del tipo file que se puede leer de la siguiente forma: el archivo /tmp/somefile debe existir y root debe ser su dueño.

Existen otros tipos de definición que podemos utilizar y que son particularmente útiles en nuestro contexto. Estos son: package, para el manejo de los elementos atómicos de software de un sistema operativo, cron, para programar tareas en un sistema y exec, para ejecutar comandos en un sistema. Existen otros tipos de definiciones, que podemos ver en el Type Reference del Trac de Puppet.

Certificados

Cuando un cliente intenta hablar con el puppetmaster, de forma predeterminada las comunicaciones se impiden, debido a que el servidor debe autenticar al cliente utilizando certificados X.509. Esto lo podemos monitorear utilizando puppetca:

  puppetca --list
  puppetca --sign cliente1

Una vez realizado este proceso, el puppet funcionará como se indica en el resto de este documento.

Pruebas

Tanto en el cliente como en el servidor los servicios deben estar operativos:

  # /etc/init.d/puppetmaster start
  o bien
  # /etc/init.d/puppet start

Se pueden monitorear los archivos de registro bajo /var/log/puppet para verificar las operaciones del servidor. Recuerde que el tiempo predeterminado para contactar al puppetmaster es de 30 minutos.

Ni puppet ni puppetmaster requieren ser reiniciados cuando se cambien los archivos de configuración. El servidor está monitoreando los archivos de configuración y los reelerá a los pocos segundos de ser cambiados con un mensaje como (en el caso de puppet):

  puppetd[32711]: Reparsing /etc/puppet/puppetd.conf

2 Comments.

Leave a comment
  1. Gracias por la referencia. Es muy buena explicando los conceptos en los que se base puppet y me han quedado claras muchas cosas.

    Los artículos de Steve Kemp están muy bien, desde luego, pero no pueden considerarse una introducción al sistema.

    Atentamente

Leave a Reply

( Ctrl + Enter )

Trackbacks and Pingbacks:

Este blog refleja única y exclusivamente mis opiniones, y no las de mis empleadores, las de las organizaciones de las que formo parte ni las de ninguna otra persona natural o jurídica, pública o privada, nacional o extranjera.