Blog de Felipe Jaramillo Fonnegra

300 Baudios

Opscode Chef - Introducción

Chef es una herramienta de la categoría de manejo de configuracion (configuration management). Este es un post que sirve como introducción a Chef y también como un compendio de los problemas, soluciones y herramientas que me han ayudado en el camino de aprenderlo.

Chef, Puppet y CFEngine hacen parte de una nueva generación de herramientas de administración de configuración.

La administración de configuración es un pilar esencial de la revolución de la Infraestructura como Código y la disciplina de DevOps.

Esto no es un post de Chef vs Puppet pues ambas herramientas son parecidas y resuelven problemas similares.

El Sysadmin como artesano irreemplazable

Un administrador de sistemas (sysadmin) tiene que repetir una y otra vez las tareas de configuración de un servidor. Después de unas semanas, ni siquiera él recuerda qué fué lo que hizo. Si se enferma un día o decide irse de vacaciones sin avisar y la máquina falla, tenemos un problema muy serio.

Por esto las máquinas configuradas a mano, o artesanalmente adquieren demasiada importancia. Una especia de personalidad propia. Se vuelven imprescindibles e irremplazables. A la delicada práctica en que nos encariñamos con una máquina, un hardware y una instalación configurada ‘especialmente’ se le da el término de server hugging o ‘abrazar servidores’.

Las imagenes de máquina no son suficiente (AMI’s o Imagenes)

Cuando usamos una imagen virtual (server image) como un AMI (Amazon Machine Image), una imagen de VirtualBox o VMWare, vamos a tener el mismo problema: si necesitamos variaciones de esa imagen para diferentes proyectos, por ejemplo una versión diferente de MySQL, configuración diferente de PHP o un sistema operativo base (CentOS o Ubuntu), quedamos obligados a crear y mantener una imagen independiente por cada uno. No gracias, prefiero hacer otras cosas con mi tiempo.

La idempotencia

¿Cómo garantizar que el resultado de la ejecución de un comando o un script es el mismo independientemente de cuantas veces lo ejecutamos?

Este principio se conoce como idempotencia: una función arroja el mismo resultado cada vez que se ejecuta.

Este es parte del atractivo principal de Chef:

No definimos acciones, definimos estados.

Así, al definir que una máquina debe tener Apache2, la primera vez que se ejecuta descarga e instala el paquete de Apache2. Las siguientes veces, al tener Apache2 instalado, no hace nada.

Chef usa el concepto de recursos (resources) y (proveedores) para abstraer el qué se debe hacer del cómo se hace.

Por ejemplo, si quiero tener instalado un paquete Apache2 en CentOS usaría yum, pero si se hace en Ubuntu se usa apt-get. El recurso como tal es package, mientras que hay un proveedor (provider) para ambientes diferentes. Esto quiere decir que podemos aprovisionar una máquina en CentOS, RedHat Enterprise, Ubuntu, Debian, Solaris y en algunos casos hasta Windows.

El virtuosismo de aprovisionar con scripts de shell

  • Automatización con scripts de shell. Frecuentemente se crean pequeños scripts de shell (Bash, Zsh) para automatizar labores de provisionamiento de una máquina. El problema es que a medida que crecen los scripts no siempre están organizados claramente. Sólo los entiende quien los creó, pueden no estar bajo control de versiones y son escritos en un lenguaje demasiado viejo para ser divertido o altamente eficiente.

Una hora de Chef ahorra días o semanas

La primera vez que hacemos algo, Chef puede tomar 5x lo que toma hacerlo directamente en la consola. Creamos una cookbook con recetas, usamos una receta de la comunidad y creamos nuestra receta que la usa y la extiende. Lo versionamos y lo probamos. Toma más tiempo pero una receta en Chef es para mí mil veces más comprensible, mantenible, reutilizable, versionable y visible. Una vez lo usamos no hay vuelta atrás.

Bootup Scripts

Cuando las labores son simples y sabemos en qué plataforma se van a correr podemos usar un script de arranque:

apt-get update
apt-get install php5

En el caso de Amazon Web Services, arrancando una imagen, durante el asistente podemos pasar texto de arranque que se ejecuta automáticamente usando una meta-herramienta, parte de la virtualización: CloudInit.

Recetarios y recetas

A una máquina, entendida como un nodo en Chef le podemos asignar una o más recetas o, para hacerlo más fácil, un rol - que a su vez es una agrupación de recetas -. Las recetas están contenidas en recetarios (cookbooks) que agrupan las recetas, metadatos y recursos y proveedores (imaginenselos como ingredientes por ahora).

Algunas de las más importantes:

Crear recetas como un profesional

Los experimentados en Chef desarrollan cómodamente, prueban sus recetas y las ejecutan en entornos virtualizados en sus propias máquinas y ni siquiera sudan. ¿Necesitamos configurar un cluster de 7 máquinas: 1 balanceador de carga, 2 web servers, 2 servidores de aplicación, 2 servidores de base de datos? Fácil, lo podemos hacer sin salir de nuestra máquina de desarrollo con las herramientas adecuadas.

Veamos cuales son las herramientas principales:

Ruby

Si aún no ha aprendido Ruby, esta es una muy buena disculpa para hacerlo. Aprender es fácil, especialmente con el curso de Ruby en CodeAcademy, o con la serie de Ruby en CodeSchool (TryRuby es de ellos y es gratis).

Ruby fue elegido por Opscode principalmente por su sintáxis limpia que a simple vista parece un archivo de configuración. La ausencia de punto y coma (;), corchetes ({}) y líneas excesivas lo hacen fácil de leer. Si venimos lenguajes como C, C++, C#, PHP puede que tome un poco habituarse a la sintáxis, pero con el tiempo su belleza sale a relucir.

Recomiendo: - Video - Suficiente Ruby para ser Peligroso’ (Enough Ruby to be Dangerous de ChefConf 2012. - Articulo del mismo nombre: Enough Ruby to be Dangerous). - Suficiente Ruby para Chef: (Just Enough Ruby for Chef)

Chef

Chef se puede instalar descargándolo de la página de instalación de Chef. Chef Client se usa para las máquinas (nodos) que aprovisionamos, lo descargaremos muchas veces. Por otro lado Chef Server se instala típicamente una sola vez en una máquina centralizada, o se usa el servicio de Hosted Chef de Opscode (gratis para 5 máquinas).

Chef-Solo

Chef-Solo es una versión de Chef que corre recetas sin necesidad de un servidor de Chef. Cuando usamos Vagrant (descrito abajo) Chef Solo está disponible. Puede ser un buen comienzo pero recomiendo empezar a trabajar con Chef Server lo antes posible.

Chef-Server

Chef Server es Open Source y se puede instalar fácilmente. Permite coordinar el manejo de recetarios, recetas, roles, nodos, bolsas de datos (data bags) y atributos de una manera centralizada.

Por otro lado existe Chef Hosted, un servicio de Chef Server proporcionado y administrado por sus creadores: Opscode. Chef Hosted es gratis para administrar 5 servidores y es la mejor manera de empezar a trabajar con Chef lo más rápido posible.

Knife

Todo cocinero trabaja con un buen cuchillo y Knife es la harramienta que usamos para interactuar con Chef. Nos deja crear recetas, subirlas a un servidor, administrar atributos, configurar máquinas remotas y mucho más.

Lo que debe saber es que Knife espera usar Chef-Server para trabajar completamente. Existe la herramienta Knife-Solo.

Knife es la herramienta principal para crear recetas e interactuar con Chef Server. Desde Knife podemos administrar nodos, recetas, ambientes, roles, recetarios y mucho más. Se installa con un solo comando:

curl -L http://www.opscode.com/chef/install.sh | sudo bash

Git

Para aprovechas al máximo Chef es bueno estar cómodo con Git. Si aún no lo ha hecho, le recomiendo el taller TryGit de Codeschool, es gratuito. En los planes pagos de Codeschool está Git Real y Git Real 2. Se volverá un ninja de Git rápidaente. A mí me ayudaron a entender la maraña multidimensional de universos paralelos que puede ser un sistema de control de versiones distribuido.

 Vagrant

Vagrant es mi principal descubrimiento del 2013. Por si no sabía, ya no hay que usar WAMP (Windows, Apache, MySQL, PHP) o MAMP (Mac, Apache, Mysql, PHP) o cualquier combinación de siglas para definir el miserable proceso de convertir nuestras máquinas de desarrollo en una réplica de un servidor de cualquier cliente.

Vagrant es, en resumen, un administrador de máquinas virtuales gratuiro. Vagrant es mejor para crear máquinas de VirtualBox que el mismo Oracle VirtualBox. Dentro de una nuestras máquinas personales podemos crear imágenes de distintos sistemas operativos. Es el sueño hecho realidad para manejar ambientes de desarrollo.

Vagrant también manejar ambientes de VMWare con su plugin pago Vagrant VMWare.

Vagrant es escencial para cualquier desarrollador o sysadmin. Mi mejor descubrimiento de principio de 2013.

Para instalar Vagrant, en este caso en un Mac con Homebrew:

brew install vagrant

HomeBrew en Mac del comando brew as mi administrador de paquetes favorito en Mac. Si usa Debian (ej. Ubuntu), lo felicito pues apt es excelente.

Para ser un maestro recomiendo el libro de O’Reilly Vagrant: Up and Running de su creador Mitchell Hashimoto.

Recetarios de la Comunidad

En el sitio de Opscode Community encontrarán cientos de recetas ya hechas para instalar y configurar todo tipo de herramientas.

Foodcritic

Todo Chef necesita un buen crítico gastronómico y en el caso de los que hacemos código de infraestructura con Chef, lo mejor es usar foodcritic. Es una herramienta de revisión de código y buenas prácticas (similar a Lint en Javascript). Tiene una serie de principios con sugerencias. Se ejecuta antes de subir o hacer commit de código y evita errores o malas prácticas. Para nuestros estándares podemos crear reglas propias y adicionarlas a Food Critic.

Knife EC2

El plugin de Knife - knife ec2 permite arrancar y aprovisionar una máquina de Amazon EC2 usando nuestro servidor de Chef o el servicio de Chef Hosted con un solo comando de shell.

Chef-Shell / Shef

A pesar de su desafortunado nombre inicial, esta herramienta es tremendamente útil: es una consola interactiva de Ruby con Chef. Inicialmente se llamaba Shef pero después de que nadie lo pudiera pronunciar sin confundirlo con Chef lo renombraron Chef-Shell.

~ chef-shell
loading configuration: none (standalone session)
Session type: standalone
Loading...done.
This is the chef-shell.
 Chef Version: 11.4.4
 http://www.opscode.com/chef
 http://wiki.opscode.com/display/chef/Home
run `help' for help, `exit' or ^D to quit.
Ohai2u felipejaramillo@mpro-2.local!

Después de iniciar aparece el comando:

chef >

Estos son los comandos básicos de Chef-Shell:

================================================================================
| Command                  | Description
================================================================================
| help                     | prints this help message
| version                  | prints information about chef
| recipe_mode              | switch to recipe mode
| attributes_mode          | switch to attributes mode
| run_chef                 | run chef using the current recipe
| chef_run                 | returns an object to control a paused chef run
| chef_run.resume          | resume the chef run
| chef_run.step            | run only the next resource
| chef_run.skip_back       | move back in the run list
| chef_run.skip_forward    | move forward in the run list
| reset                    | resets the current recipe
| become_node              | assume the identity of another node.
| echo                     | turns printout of return values on or off
| echo?                    | says if echo is on or off
| tracing                  | turns on or off tracing of execution. *verbose*
| tracing?                 | says if tracing is on or off
| ls                       | simple ls style command
| node                     | returns the current node (i.e., this host)
| ohai                     | pretty print the node's attributes
| edit                     | edit an object in your EDITOR
| clients                  | Find and edit API clients
| clients.all              | list all api clients
| clients.show             | load an api client by name
| clients.search           | search for API clients
| clients.transform        | edit all api clients via a code block and save them
| cookbooks                | Find and edit cookbooks
| cookbooks.all            | list all cookbooks
| cookbooks.show           | load a cookbook by name
| cookbooks.transform      | edit all cookbooks via a code block and save them
| nodes                    | Find and edit nodes via the API
| nodes.all                | list all nodes
| nodes.show               | load a node by name
| nodes.search             | search for nodes
| nodes.transform          | edit all nodes via a code block and save them
| roles                    | Find and edit roles via the API
| roles.all                | list all roles
| roles.show               | load a role by name
| roles.search             | search for roles
| roles.transform          | edit all roles via a code block and save them
| databags                 | Find and edit +databag_name+ via the api
| databags.all             | list all items in the data bag
| databags.show            | load a data bag item by id
| databags.search          | search for items in the data bag
| databags.transform       | edit all items via a code block and save them
| environments             | Find and edit environments via the API
| environments.all         | list all environments
| environments.show        | load an environment by name
| environments.search      | search for environments
| environments.transform   | edit all environments via a code block and save them
| api                      | A REST Client configured to authenticate with the API
================================================================================

Berkshelf

Berkshelf puede ser definido como un manejador de dependencias de recetarios (cookbook dependency manager). Es una alternativa más nueva y un poco más popular que Librarian.

¿Para qué se usa? El caso es que una receta puede depender de otras. Es bueno en concepto y permite desacoplar las acciones pero la declaración, descarga, instalación y manejo de versiones puede ser un dolor de cabeza.

Ahí entra Berkshelf. El nombre es una variación de la palabra bookshelf y es un manejador de recetas con varias mejoras:

  • Controla las dependencias de recetas. Las descarga y las pone disponibles solo con declararlas en el archivo Berksfile
  • Facilita el patrón de un repositorio Git por cada recetario(cookbook). Por defecto, Chef usa un chef-repo que contiene todos los recetarios incluidos los propios o externos. Se vuelve complicado publicar una receta en su propio repositorio o colaborar con otros.
  • Los desarrolladores de Opscode lo usan internamente así como varios de la comunidad y los del show radial Food Fight.
  • Algunos usaban antes Librarian pero se pasaron a Berkshelf.
  • Se integra perfectamente con nuestro administrador de máquinas virtuales favorito: Vagrant a través de vagrant-berkshelf.

La conferencia y el blog post de “The Berkshelf Way” de Jamie Winsor es la mejor referencia para entender el por qué y cómo usar Berkshelf. Es tal vez la mejor hora que he dedicado a aprender cómo usar Chef efectivamente.

Test Kitchen

Test Kitchen es una suite de pruebas para validar recetarios y recetas de Chef en diferentes entornos. Es una herramienta avanzada que ayuda a garantizar que una receta funcione correctamente en diferentes entornos.

Referencias de aprendizaje

Conferencias en línea

Más que una herramienta es una manera para aprender Opscode moderno y buenas prácticas. Opscode organiza una conferencia sobre Chef cada año.

Los archivos históricos de las conferencias están en el canal de Opscode en Youtube. Sirven mucho para aprender tendencias de Chef.

Un tip especial: las conferencias de Puppet, publicadas por Puppet Labs también están en línea. Aún siendo una plataforma similar a Chef he encontrado casos excelentes de experiencias de diferentes empresas.

Food Fight

Este es un podcast o show radial en que expertos de Chef se reúnen ha hablar sobre temas de chef, sysadmin y devops.

Documentación de Chef

La documentación de Chef está en doc.opscode.com. Bien organizada y simple. Uso mucho la referencia de recursos (resources).

Tutorial de Getting started with Chef

Este sitio, que no es oficial de Chef tiene un excelente tutorial para configurar una máquina completa para correr Wordpress desde cero. Cuando empezaba me demoré algo más de 2 horas para terminarlo y me funcionó bien. Al terminar disfrutaba mostrandole a mis colegas cómo arrancaba una máquina de Ubuntu sin nada y a los cinco minutos tenía un servidor completo de Wordpress, con PHP, Apache, MySQL y la última versión de Wordpress. Luego terminaba la instancia y lo volvía a hacer desde cero, disfrutandolo. Ese proyecto sirve de base para proyectos mucho más complicados.

Chef en IRC

Hace tiempo no usaba el chat (IRC). Chef tiene un canal #chef en freenode.net en el que podemos pedir ayudar y, con suerte, recibir una respuesta. Los registros históricos del chat salen publicados en la página de Opscode.

Libros de Chef

Principales Problemas

  • Llaves erróneas. Tener las llaves de Chef Server (client.pem o validation.pem) impide correr Knife.

  • Versión de Ruby. El Mac viene con una versión de Ruby muy antigua. Intenté actualizarla con Homebrew pero lo mejor resultó ser usar rvm (Ruby Version Manager) y la versión de Ruby 1.9.3. Hay muchos problemas que dependen de la versión de Ruby y arrojan errores casi indescifrables de otras gemas.

  • Máquina muy pequeña. Al correr Chef Server* lo hice en una de Amazon EC2 t1.micro pero después de que se colgara lo decidí mejorar a una m1.small. Hay que estar pendiente de que el buscador Solr esté corriendo en la máquina en adición a Chef Server.

  • Al arrancar una máquina virtual, es importante actualizar los paquetes de sistema. El recetario apt actualiza los paquetes y evita errores en otras recetas posteriores.