miércoles, 30 de julio de 2014

Chef: Desplegando nuestro primer cookbook


En el tutorial de hoy vamos a mostrar de forma práctica los pasos necesarios para utilizar la arquitectura cliente-servidor de Chef. Necesitaremos:
  • Un servidor de Chef.
  • Un repositorio local donde almacenar y editar nuestras configuraciones.
  • Una máquina donde instalaremos el cliente de Chef.

Hosted Chef

Vamos a utilizar Hosted Chef, un servicio proporcionado por Opscode, que nos ofrece un Servidor de Chef y una completa interfaz web para su gestión. Con esto evitaremos instalar un Servidor de Chef desde cero.
Para empezar, creamos una cuenta de usuario nueva en la página de Hosted Chef (click en Get Chef). Llegará un correo electrónico con un enlace que debemos abrir para validar la cuenta.
Una vez registrados, entramos en el panel de gestión de Hosted Chef y creamos una organización nueva. Hay que rellenar el nombre e identificador de la organización y escoger un plan. Seleccionamos el plan gratuíto, que ofrece hasta un máximo de 5 nodos gestionados por Chef.

En la siguiente pantalla, tras crear la organización, debemos descargar dos ficheros.

  • [tu-organización]-validator.pem es una clave que nos servirá para registrar en esta organización nuevos clientes de Chef, es decir, los servidores a configurar.
  • knife.rb contiene la configuración necesaria para usar knife, la herramienta de línea de comandos de Chef.
Accedemos al panel de cambio de contraseña de nuestra cuenta de Hosted Chef y, en la sección Reset User Key, hacemos click en Get a new key. Se descargará un fichero que contiene la clave privada que sirve para identificar a nuestro usuario en el servidor de Chef.

Con esto, ya disponemos de los tres ficheros necesarios para configurar el repositorio de Chef.

Puesta a punto del repositorio

Clonamos el repositorio oficial de Chef en un directorio de nuestra máquina local.
$ git clone git://github.com/opscode/chef-repo
Creamos un directorio con nombre .chef dentro de chef-repo y movemos ahí los ficheros que hemos descargado antes. El contenido debería quedar así:
$ ls .chef/
[tu-organización]-validator.pem
[tu-nombre-de-usuario].pem
knife.rb
Nos situamos en el directorio chef-repo y, con la ayuda de knife, comprobamos que nuestras credenciales están bien.
$ knife client list
[tu-organización]-validator
Nota: Si no tienes knife en tu sistema, debes instalar el paquete Omnibus de Chef.

Crear un cookbook

En el anterior post explicamos lo que era una receta, un fichero escrito en Ruby que contiene una configuración para aplicar en la máquina. Hoy introducimos el concepto de cookbook, que no es más que una colección de recetas relacionadas entre sí. Por ejemplo, un cookbook de MySQL podría contener dos recetas: una que instala el servidor y otra que instala el cliente.
El Servidor de Chef no almacena recetas sueltas, así que vamos a ver cómo adaptar la receta del último día a un cookbook.
Creamos un cookbook de nombre clock usando knife.
$ knife cookbook create clock
** Creating cookbook clock
** Creating README for cookbook: clock
** Creating CHANGELOG for cookbook: clock
** Creating metadata for cookbook: clock
En un editor de texto abrimos la receta por defecto del cookbook (está en cookbooks/clock/recipes/default.rb) y copiamos el siguiente código.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Nos aseguramos de que el paquete de ntpdate este instalado
case node['platform']
when 'redhat','centos','scientific','fedora','suse','amazon' then
  package 'ntp'
when 'debian', 'ubuntu' then
  package 'ntpdate'
else
  log('Unsupported platform, trying to guess ntpdate package') { level :warn }
  package 'ntp'
end

# Anyadimos una entrada cron al sistema
cron 'System Clock Synch' do
  user 'root'
  minute '45'
  command '/usr/sbin/ntpdate -u hora.roa.es > /dev/null 2>&1'
end

Subir el cookbook al Servidor de Chef

El cookbook que acabamos de crear está en nuestra máquina local, pero para poder aplicarlo en los nodos es necesario subirlo al servidor de Chef.
$ knife cookbook upload clock
Uploading clock          [0.1.0]
Uploaded 1 cookbook.
Este mismo comando sirve también para subir al servidor actualizaciones que hagamos en nuestro cookbook.

Arranque del nodo

Para probar el cookbook necesitamos una máquina donde tengamos acceso SSH y permiso para ejecutar comandos como root con sudo. Ejecutamos:
$ knife bootstrap HOSTNAME \
  --ssh-user USER \
  --run-list "recipe[clock]" \
  --sudo
El proceso puede tardar unos minutos. La salida del comando terminará con:
localhost Chef Client finished, 1 resources updated
Este comando instala el cliente de Chef en la máquina y ejecuta el cookbook indicado en run_list. Si no devuelve ningún error significa que el estado del nodo es equivalente al especificado en la configuración. Esto es lo que se conoce como convergencia en Chef.
Comprobamos que el nodo aparece entre los gestionados por el servidor:
$ knife node list
[nombre-del-nodo]
También podemos loguearnos por SSH en la máquina y comprobar que el paquete ntpdate está instalado y la entrada del crontab añadida.

Borrar el nodo

Desde el momento en el que se ha realizado el bootstrap del nodo, éste ha quedado registrado en el servidor de Chef. Esto sirve para que el cliente pueda recibir actualizaciones del cookbook desde el servidor. Para derregistrarlo podemos hacerlo desde el listado de nodos del panel de gestión, o desde la línea de comandos utilizando knife:
$ knife node delete NOMBRE_DEL_NODO
$ knife client delete NOMBRE_DEL_NODO

Conclusiones

En este tutorial hemos visto la forma de configurar una máquina con Chef. Podemos intuir la potencia que se esconde tras esta herramienta sabiendo que es posible gestionar de esta manera cientos o miles de nodos.
También hemos aprendido varios comandos básicos de la herramienta knife, que va a demostrar ser una gran aliada mientras nos sumergimos en el universo de Chef.
En próximos post profundizaremos en la creación de cookbooks y veremos cómo podemos usar cookbooks creados por la comunidad de Chef.

Cómo Instalar y Configurar Chef

Cómo Instalar y Configurar Chef

Detalles del Tutorial
  • Dificultad: Aprendiz
  • Duración: 20 min


La semana pasada hablamos de Vagrant, una herramienta muy útil que cumple el propósito de facilitar el proceso de construcción de ambientes virtuales de manera automatizada; sin embargo la instalación de software y su configuración en los ambientes es quizás una de las tareas más importantes de este proceso, es por ello que esta semana hablaremos de una de las más utilizadas herramientas de automatización y suministro, Chef.

¿Qué es Chef?

Es un framework de automatización de infraestructura de sistemas, esto permite desplegar aplicaciones y sistemas a cualquier ambiente físico, virtual o en la nube fácilmente con un enfoque en la preparación de instalación y configuración previa del ambiente. Como su nombre lo indica, la herramienta pretende seguir un conjunto de pasos o recetas con el propósito de presentar un producto final ya listo para trabajar y/o probar.
Existen 2 tipos de versiones:
Chef Server está enfocado a ser el servidor central que, en comunicación con los equipos de trabajo, permite suministrar a los diferentes ambientes o nodos con las diversas configuraciones que sean necesarias, las cuales se mantienen alojadas en el servidor. Además ofrece varias ventajas particulares del trabajo de varios nodos como balanceo de carga, escalabilidad, búsquedas rápidas por tipo (Ej. todos los ambientes Ubuntu Precise, o todos los ambientes con 4GB de RAM), y mucho más.
Por el contrario, Chef Solo es la versión de código abierto y reside localmente en el nodo, esto quiere decir que toda la información y recetas necesarias para configurar el nodo deben estar presentes en su disco duro.
Para nuestro caso, esta última será la versión que utilizaremos a lo largo de este escrito.

¿De qué esta compuesto?

Como mencionamos anteriormente se encuentran los servidores finales llamados Nodos, los cuales son los principales destinos de todo el proceso que se ejecutará, además tenemos las Estaciones de Trabajo, como su nombre lo indica, es el sistema que los desarrolladores manipulamos directamente para crear las piezas que luego serán desplegadas a los nodos.
También tenemos las Recetas, son archivos escritos en lenguaje Ruby que ejecutan una serie de comandos para instalar y configurar software, mientras que un conjunto de recetas relacionadas con un mismo procedimiento se denomina Recetario. Supongamos el caso de un sencillo servidor web, tendríamos una receta que instale Nginx y otra MySQL, podríamos crear un recetario llamado simple web server cookbook que contenga estas recetas.
A la configuración reutilizable a implementar en cada nodo se le denomina Rol, retomando el ejemplo del servidor web, quisiéramos que cualquier nodo con dicho tipo de rol sea configurado para tener abierto los puertos 80 y 443 (http y https) y que se instale Nginx (mediante una receta), en este caso se crea un rol para el cual se especificarán los atributos involucrados (como los puertos abiertos) y las recetas a utilizar (como la de instalación de Nginx).
Hablando del tema de almacenamiento, entra en juego el Repositorio Chef, también denominado Cocina este se encarga de reunir toda ese código fuente de instalaciones y configuraciones que creamos en nuestras estaciones de trabajo, por lo que es altamente recomendable que sea sincronizado con un control de versiones como Git.

Complementos

Knife, el cuchillo de Chef, es una herramienta de linea de comandos que provee una interface de comunicación entre el repositorio Chef que tenemos localmente en nuestra estación de trabajo y el Chef Server. En nuestro caso como estaremos utilizando Chef Solo, necesitaremos la versión particular de Knife Solo, debido a que el enfoque “Solo” refiere a que no existe un Chef Server sino que nuestro propio nodo actúa como tal, siguiendo el concepto de Knife, su versión Solo nos ofrece una interface de comunicación directa con otros nodos.
Librarian, el bibliotecario, nos ofrece un manejo de dependencias de los recetarios en el repositorio, además de facilitar el manejo e recetarios fuera de él, ofreciendo la gran ventaja de utilizar el código de los mismos directo desde la fuente.
Y por supuesto Vagrant, el cual se integra muy bien con Chef, en caso de que quieras desplegar a ambientes virtuales esta herramienta te ayudará a crearlos con una enorme facilidad, de lo contrario igual le puedes sacar gran provecho al crear un ambiente virtual “conejillo de indias” para probar tus configuraciones y recetas de Chef.

¿Cómo comienzo?

Instalemos Vagrant y creemos un ambiente virtual de prueba, posteriormente procedemos a instalar el resto de los componentes que nos harán falta (se recomienda tener una versión de Ruby superior a 1.9.2):
Basta con solo instalar knife-solo debido a que entre sus dependencias se encuentran Chef y Librarian.
Luego creemos un directorio para nuestra cocina e iniciémosla:
Esto hará que knife cree una archivo de configuración básico (utilizado principalmente en Chef Server pero si no lo creamos Knife no nos dejará trabajar) y construya la estructura de directorios y archivos que sigue los estándares de Chef para definir una cocina.
Ahora crearemos con Librarian el archivo Cheffile que nos permitirá manejar los recetarios:
Ahora procedemos a abrir el nuevo Cheffile y le indicamos algunos recetarios a usar, puedes ingresar al portal de Opscode y ver todos los que tienen disponibles, para nuestro ejemplo seguiremos el caso del servidor web sencillo así que agregaremos la siguiente línea al archivo:
En este caso estamos asignando el recetario de Nginx, notemos además que hemos especificado el repositorio Git donde se debe buscar el código fuente del mismo, si no especificamos este parámetro Librarian lo buscará en el sitio especificado en la variable site, en este caso sería el sitio del API de la comunidad de Opscode (site 'http://community.opscode.com/api/v1').
Finalmente dejamos que Librarian se encargue de buscar y descargar las recetas que necesitamos:
Como podemos notar, Librarian ha instalado los recetarios que especificamos y además se encargó de instalar sus dependencias. Ahora las podremos encontrar en el directorio cookbooks.

Nodo normal

Crearemos nuestro primer nodo, supongamos que este no tiene el soporte nativo para el suministro de Chef, para esto usaremos nuestro ambiente conejillo de indias de Vagrant sin hacer uso del dicha funcionalidad. Editemos el Vagrantfile y verifiquemos que el script de suministro que teníamos en el tutorial de Vagrant esté comentado:
Para crear el nodo debemos especificar la dirección en la que se encuentra y su nombre de usuario, para esto debemos agregar la siguiente línea al Vagrantfile y colocar algo así:
Esto le asignará una dirección IP estática al ambiente virtual (no tiene que ser esta misma), lo cual nos permitirá acceder a él una vez esté instalado un servidor web, además necesitamos esta dirección para crear el nodo.
Ahora sabiendo esta IP podremos crear el nodo:
El nombre de usuario y contraseña por defecto del ambiente es vagrant.
Esto detectará automáticamente la versión del sistema operativo que se encuentra en el servidor e instalará Chef, Ruby y Rubygems en él, con la intención de preparar el ambiente para el suministro que se llevará a cabo.
Este proceso creará el directorio /nodes un archivo cascarón .json para que especifiquemos la configuración e instalación, si lo abrimos veremos que se encuentra casi vacío, lo que nos da entrada a jugar con la configuración, agreguemos algunos detalles:
La variable run_list posee los roles o recetas a instalar en el nodo, en este caso instalaremos la receta source del recetario Nginx. En la parte superior podemos especificar diferentes atributos que tomarán las recetas, en este caso especificamos la versión de Nginx y que queremos que se incluya el modulo de SSL.
Por último debemos suministrar al ambiente con nuestra cocina y la configuración de recetas que hemos creado:
Para verificar que en efecto se ha instalado la receta de Nginx que especificamos, vayamos al explorador de internet y verifiquemos la dirección del servidor:
Notemos que la parte inferior refleja que, en efecto, Nginx v1.2.3 está instalado y está sirviéndonos esta página 404.

¿Cuál es la desventaja de este método?

Debido a que el suministro del ambiente se hace en vivo con knife, si el ambiente es destruido perderemos la configuración y tendremos que volver a suministrarlo utilizando:
Este comando es equivalente a hacer prepare y luego cook.

Nodo Vagrant con soporte nativo

Debido a una incompatibilidad entre la versión de Chef que trae la caja de Vagrant que usamos en el tutorial pasado y la ultima versión del recetario apt nos vemos en la necesidad de editar el Cheffile y usar recetarios más antiguos, quedando de la siguiente manera:
Luego, usando Librarian, volvemos a construir los recetarios:
Ahora retomando nuevamente el paso, construimos nuestro archivo .json con la misma estructura que el método anterior y la guardamos en el directorio /nodes:

vagrant_node.json

Ahora debemos editar el Vagrantfile y agregar lo siguiente:
Lo que hemos colocado en el Vagrantfile es la configuración de suministro nativa de Chef que ofrece Vagrant y la relacionamos con los directorios de nuestra cocina y el archivo json que dictará la configuración e instalación de las piezas de software. Este procedimiento será ejecutado durante el período de levantamiento del ambiente, probémoslo ahora:
En la salida que va expulsando el terminal mientras se levanta el ambiente podremos notar acciones referentes al proceso de suministro como por ejemplo:

¿Cuál es la ventaja de este método?

Debido a que el suministro se hace durante el proceso de levantamiento y que la configuración de dicho suministro está ligada al Vagrantfile, no importa si los ambientes son destruidos, con solo ejecutar vagrant up nuevamente tendremos nuestro ambiente virtual previamente configurado.

Conclusión

Aprendimos que instalar y configurar software en diferentes ambientes puede ser una tarea menos tediosa de lo que estamos acostumbrados, el truco está en construir correctamente todas las piezas que necesitamos para al suministrar a un ambiente podamos empezar a trabajar de una vez. Muchas otras cosas son posibles con Chef, puedes crear tus propias recetas, crear tus roles completamente personalizados para cuando necesites implementar la misma configuración en varios ambientes, y mucho más.

Cómo entender el entorno de configuración de Chef en un VPS

Las herramientas de gestión de configuración proporcionan una vía rápida para el despliegue de varios equipos con una configuración similar. Entre estas herramientas, una de las más utilizadas es Chef, que utiliza Ruby y se encarga de la configuración de las máquinas por medio de archivos de configuración que denominan “recetas”.
Chef proporciona una forma rápida y sencilla de configurar entornos enteros en vez de sólo una serie de aplicaciones individuales. En cualquier proceso donde necesitemos instalar un determinado software o modificar cierta configuración del servidor, podemos hacer uso de Chef para automatizar este proceso.
A lo largo de esta entrada, vamos a ofrecer una visión general de cómo se organiza Chef y que herramientas nos proporciona para lograr sus objetivos.

Términos utilizados por Chef

Antes de nada, es importante entender los diferentes componentes que forman parte de Chef.
1.- Infraestructura de funcionamiento de Chef
Vamos a empezar por ver los diferentes modelos que componen la estrategia de despliegue de alto nivel.
El sistema Chef define roles que cada máquina o recurso desempeña en el proceso de implementación:
  • Chef Server: Es la ubicación central donde se almacenan las recetas de configuración, el nodo y las definiciones de la estación de trabajo. Es la máquina central que se utilizará para la configuración de cualquier otra máquina de la infraestructura.
  • Chef Nodes: son los equipos que están configurados por el Chef. Cada nodo representa una máquina separada, contenido que puede ser un hardware físico o bien virtual. Estos entornos contienen una aplicación cliente que puede conectarse con el servidor Chef.
  • Chef Workstations: Son donde se crean o editan los detalles de la configuración del Chef. Estos archivos de configuración son llevados al servidor Chef, donde están listos para ser desplegados en cualquier nodo.
2.- Detalles del servidor
El servidor es el punto central que es accedido por el resto de máquinas. Básicamente se trata de un gran repositorio con todos los detalles de configuración.
Gestiona las conexiones y permisos de nodos y estaciones de trabajo y organiza los datos para que pueda ser accedido de forma sencilla por los clientes. El servidor también puede incluir una interfaz web con el fin de administrar o configurar algunos detalles.
3.- Detalles de los nodos
Como ya comentamos anteriormente, un nodo puede ser una máquina física o virtual. Sus únicos requisitos son que tiene que tener acceso a la red y que se pueda comunicar con el servidor Chef.
Cada nodo se comunica con el servidor central utilizando una aplicación llamada “chef-client”. Esta se encarga de la extracción de datos fuera del servidor y ejecución de los pasos de configuración para obtener el resultado deseado en el nodo. El cliente y el servidor se comunican a través del uso de una autenticación basada en claves RSA.
El cliente también hace uso de una herramienta llamada “Ohai” para obtener información sobre el nodo. Esto se utiliza con el fin de configurar ciertos detalles y rellenar variables contenidas dentro de los archivos de configuración.
4.- Detalles de la estación de trabajo
Una estación de trabajo cuenta con las herramientas necesarias para crear y modificar los detalles de configuración para cualquiera de los nodos disponibles y se puede comunicar con el servidor Chef para que estén disponibles.
Una herramienta importante para la gestión es “Knife”. Se trata de una puerta de enlace por la que se puede configurar cualquier cosa que se almacene en el servidor. Se puede gestionar los nodos y configuraciones y, en general se puede utilizar para acceder al servidor de la manera especificada por el Chef.
Las configuraciones y definiciones que se crean y modifican en una estación de trabajo están comprometidos con el control de versiones y luego empujados al servidor. El repositorio se llama el “chef-repo”.

Estructura de archivos Chef-repo

Chef maneja la información de configuración acorde a una estructura de directorios especificada. Es importante comprender esta jerarquía con el fin de crear recetas de manera efectiva.
Como mencionamos anteriormente, los archivos de configuración del servidor se deben mantener en el control de versiones en el repositorio se conoce como el “chef-repo”. Esto es sólo un directorio donde podemos encontrar una estructura similar a la siguiente.
  • certificates/: Contiene los certificados SSL que pueden estar asociados con los clientes para la autenticación.
  • chefignore: Muestran los archivos y directorios dentro de la estructura que no se deben incluir en el empuje hacia el servidor.
  • config/: Contiene uno de los dos archivos de configuración del repositorio.
  • cookbooks/: Contiene todas las recetas que configuran la infraestructura de su organización.
  • data_bags/: Contiene varios paquetes de datos para su configuración.
  • environments/: Contiene la ubicación del nivel superior que contiene todos los detalles para el despliegue.
  • Rakefile: Este archivo define las tareas que el Chef puede realizar en sus configuraciones.
  • roles/: Contiene los ficheros que define los roles que pueden ser asignados a los nodos.

Estructura de archivos Chef CookBook

Dentro del directorio cookbooks que forma parte del “chef-repo”, los subdirectorios que nos encontramos dentro de él definen recetas específicas para las aplicaciones. Dentro de cada directorio se especifica cómo se debe instalar ese servicio y qué cambios deben hacerse para que funcione correctamente.
A continuación os indicamos los archivos y definiciones que nos permiten indicar como deben actuar.
El fichero metadata.rb o metadata.json contiene información de metadatos sobre el servicio. Esto incluye información básica como el nombre y la versión pero también es el lugar donde se almacena la información de dependencia. Si este libro de cocina depende de otros libros de cocina que se instalen, puede enumerarlos en este archivo y Chef los instalará antes del libro que este.
El directorio attributes contiene las definiciones de atributos que se pueden utilizar para anular o definir los valores que los nodos tendrán en ese servicio.
El directorio difinitions contiene los archivos de definiciones que indican los recursos a utilizar.
El directorio files describe cómo el Chef debe distribuir los archivos en todo el nodo en el que se está desplegando.
El directorio recipes contiene las recetas que definen cómo se debe configurar el servicio. Las recetas son generalmente pequeños archivos que configuran aspectos específicos del sistema.
El directorio templates se utiliza para proporcionar una gestión de configuración más compleja. Puede proporcionar archivos completos de configuración que contienen comandos de Ruby embebidos.

Por medio de este post hemos intentado explicar la estructura utilizada por Chef a la hora de gestionar sistemas. Próximamente veremos algún ejemplo de cómo crear una receta básica.