Diseñar, construir y analizar las prestaciones de un centro de proceso de datos virtual.
Documentar y mantener una plataforma virtual.
Realizar tareas de administración en infraestructura virtual.
Los gestores de configuraciones trabajan sobre máquinas virtuales ya creadas y en funcionamiento, describiendo la configuración que necesitan para ejecutar una aplicación determinada. Estas aplicaciones se ejecutan directamente si ya tenemos tal máquina provisionada, pero es más eficiente e independiente de la configuración específica trabajar con ellos desde programas de orquestación de máquinas virtuales como Vagrant
Hay muchos gestores: Chef, Salt y Puppet, por ejemplo. Todos son libres, pero tienen características específicas que hay que tener en cuenta a la hora de elegir uno u otro. En el caso específico de sistemas operativos, que es del que vamos a hablar aquí, se trata de gestionar automáticamente todas las tareas de configuración de un sistema, automatizando la edición de ficheros de configuración, instalación de software y configuración del mismo, creación de usuarios y autenticación, de forma que se pueda hacer de forma automática y masiva.
Para poder configurar máquinas virtuales específicas primero hay que instanciarlas. Dejaremos para más adelante cómo hacerlo de forma independiente del proveedor de tales servicios y veremos a continuación cómo preparar una máquina virtual para ser provisionada.
Se puede crear una máquina virtual de muchas formas, usando el interfaz web o el de línea de órdenes del proveedor de servicios correspondiente. Consulta el manual de la misma sobre cómo hacerlo. Sin embargo, si quieres hacer el provisionamiento desde fuera, no puedes usar una imagen cualquiera. Esta imagen tendrá que tener:
Un servidor ssh
activado. Casi todas las imágenes de sistemas
operativos en los servicios de nube lo tienen, pero a menudo también
hay que activar los puertos correspondientes (llamados
endpoints). Esto es imprescindible para la conexión.
Algún lenguaje de programación, el que sea necesario para el sistema de provisionamiento que se use. Normalmente se trata de Python (Ansible) o Perl (Rex), pero puede ser también otro lenguaje de scripting como Ruby.
A veces hace falta instalar algún paquete adicional. Por ejemplo
python-apt
si quieres usar directamente las órdenes
correspondientes de Ansible en vez de ejecutar otras órdenes. Chef
tiene que estar instalado en el destino o target, por lo que en
muchos casos los servicios de nube ofrecen imágenes con él ya
instalado.
Cada imagen suele tener un usuario con privilegios de administrador configurado. Consultar en cada lugar cuál es, pero una vez hecho eso, el siguiente paso en el provisionamiento es crear un par de clave pública/privada y copiar la pública al objetivo. A partir de ahí ya se puede provisionar, empezando por Chef.
Chef es una herramienta que, en
general, se usa en un servidor que se encarga no sólo de gestionar la
configuración, sino también las versiones. Empezar a usarlo
es complicado.
Sin embargo, como
introducción a la gestión de configuraciones se puede usar
chef-solo
, una versión
aislada que permite trabajar en una máquina desde la misma y que, por
tanto, se puede usar como introducción y para probar
configuraciones.
Hay varios tutoriales que te permiten, con relativa rapidez, comenzar a trabajar con Chef-solo en un servidor; este te proporciona una serie de ficheros que puedes usar y este otro es más directo, dando una serie de órdenes. En todo caso, se trata básicamente tener acceso a un servidor o máquina virtual, instalar una serie de aplicaciones en él y ejecutarlas sobre un fichero de configuración
En una máquina tipo ubuntu, hay que comenzar instalando Ruby y Ruby Gems, el gestor de librerías
sudo apt-get install ruby1.9.1 ruby1.9.1-dev rubygems
chef
se distribuye como una gema, por lo que se puede instalar
siempre como
sudo gem install ohai chef
ohai acompaña a chef
y es usado
desde el mismo para comprobar características del nodo antes de
ejecutar cualquier receta.
Una forma más rápida de instalar Chef es descargarlo directamente desde la página web:
curl -L https://www.opscode.com/chef/install.sh | bash
La última tendrá que ser sudo bash
en caso de que se quiera instalar como administrador (que será lo normal).
Instalar chef-solo
en la máquina virtual que vayamos a usar
Una receta de Chef
consiste en crear una serie de ficheros:
una lista de ejecución que especifica qué es lo que se va a
configurar; esta lista se incluye en un fichero node.json
,
o recetario (cookbook) que incluye una serie de recetas que
configuran, efectivamente, los recursos y, finalmente, un fichero de
configuración que dice dónde están los dos ficheros anteriores y
cualquier otro recursos que haga falta. Estos últimos dos ficheros
están escritos en Ruby.
Vamos a empezar a escribir una recetilla del Chef. Generalmente,
escribir una receta es algo más complicado,
pero comenzaremos por una receta muy simple que instale el
imprescindible emacs
y le asigne un nombre al nodo. Creamos el
directorio chef
en algún sitio conveniente y dentro de ese
directorio irán diferentes ficheros.
El fichero que contendrá efectivamente la receta se
llamará default.rb
package 'emacs'
directory '/home/jmerelo/Documentos'
file "/home/jmerelo/Documentos/LEEME" do
owner "jmerelo"
group "jmerelo"
mode 00544
action :create
content "Directorio para documentos diversos"
end
El nombre del fichero indica que se trata de la receta por omisión, pero el nombre de la receta viene determinado por el directorio en el que se meta, que podemos crear de un tirón con
mkdir -p chef/cookbooks/emacs/recipes
Este fichero tiene tres partes: instala el paquete emacs
, crea un
directorio para documentos y dentro de él un fichero que explica, por
si hubiera duda, de qué se trata. Evidentemente, tanto caminos como
nombres de usuario se deben cambiar a los correspondientes en la
máquina virtual que estemos configurando.
El siguiente fichero, node.json
,
incluirá una referencia a esta receta
{
"run_list": [ "recipe[emacs]" ]
}
Este fichero hace referencia a un recetario, emacs
y dado que no se
especifica nada más se ejecutará la receta por defecto.
Finalmente, el fichero de configuración solo.rb
incluirá referencias a ambos.
file_cache_path "/home/jmerelo/chef"
cookbook_path "/home/jmerelo/chef/cookbooks"
json_attribs "/home/jmerelo/chef/node.json"
Una vez más, cambiando los caminos por los que correspondan. Para ejecutarlo,
sudo chef-solo -c chef/solo.rb
(si se ejecuta desde el directorio raíz). Esta orden producirá una serie de mensajes para cada una de las órdenes y, si todo va bien, tendremos este útil editor instalado.
Crear una receta para instalar nginx
, tu editor favorito y algún
directorio y fichero que uses de forma habitual.
Para usar chef-solo
hay simplemente que instalar unos cuantos
programas, pero en gran parte ya está automatizado:
aquí explica como usarlo en Ubuntu,
por ejemplo basándose en
este Gist (programas cortos en GitHub)
que instala todas las herramientas necesarias para comenzar a ejecutar
chef.
Este curso en vídeo te enseña también a trabajar con Chef
De ninguna manera JSON es un lenguaje universal para gestión de configuraciones. Prácticamente todo el resto de los sistemas de configuración usan YAML (yet another markup language). Recientemente se ha publicado una introducción al tema que será suficiente para el uso que le vamos a dar más adelante
Escribir en YAML la siguiente estructura de datos en JSON
{ uno: "dos",
tres: [ 4, 5, "Seis", { siete: 8, nueve: [ 10, 11 ] } ] }
Normalmente estas recetas van a estar bajo control de un sistema de gestión de fuentes; de esta forma se pueden probar diferentes configuraciones, crear nuevas versiones de la misma pero, sobre todo, tener claro en cada momento qué configuración es la que se está ejecutando en producción, que será habitualmente la que esté en una rama designada de la misma.
Salt es otra herramienta de configuración
que se ha hecho popular en los últimos años. Aunque algo más
complicada de configurar que Ansible, tiene como ventaja que permite
modularizar la configuración para poder adaptarla a sistemas de la
forma más conveniente. salt-ssh
está basado en Python y sólo
requiere, en principio, que este lenguaje esté instalado en el sistema
que se va a provisionar.
La mejor forma de empezar es
instalarlo desde Github aunque
nosotros vamos a trabajar con
salt-ssh
, un
sistema que no requiere ningún tipo de instalación en el ordenador
objetivo y que se puede usar, hasta cierto punto, como Ansible. Vamos
a usarlo para
instalar los servicios necesarios para el bot de Telegram en Scala
que hemos visto en alguna otra ocasión.
Una vez instalado salt-ssh
, una de los principales problemas es que
requiere una cierta cantidad de configuración global. Generalmente
vamos a usar un directorio tal como ~/lib/salt/
como directorio de
trabajo y configuración; y este directorio va a estar fuera del
repositorio y en un directorio de superusuario por omisión. Se puede
usar el directorio local, pero en ese caso habrá que decir
específicamente donde se encuentra cada tipo de fichero. En el
README.md
del bot
vienen las instrucciones necesarias para crear ese fichero de
provisionamiento y la configuración global.
Pero para configurar nuestro propio sistema, uno de los
más importantes es el fichero roster
:
app:
host: 104.196.9.185
user: one_user
sudo: True
Aquí no sólo se declara la dirección a la que vamos a conectar, sino también si hace falta ser sudo o no. Con esto podemos ejecutar ya parte de la configuración que vamos a ejecutar más adelante:
salt-ssh '*' --roster-file=./roster -r "sudo apt-get install python-apt" -c ~/lib/salt --force-color
En este caso, se trata de ejecutar una orden para poder instalar
python-apt
, un módulo para poder ejecutar órdenes de instalación de
paquetes directamente desde Python.
Pero para efectivamente provisionar se usan ficheros salt-stack
. Por
ejemplo,
estos ficheros instalan Java
en la versión necesaria para poder instalar más adelante Scala. Y
Scala lo instalamos en
este fichero
include:
- javasetup
scala:
pkg.installed
Este fichero se ejecutaría con
salt-ssh app state.apply scala --roster-file=./roster -c ~/lib/salt --force-color
Este programa, como Ansible, actúa de manera descriptiva. Indica que
el paquete scala tiene que estar instalado, pero para ello tiene que
cumplir una serie de prerrequisitos incluidos en el fichero
javasetup.sls
; el nombre de estado se tiene que corresponder con el
nombre del fichero en sí. Este a su vez requiere la instalación de otra serie
de paquetes, e incluye otro fichero. Lo bueno es que esos dos
ficheros, javasetup
y java
, se pueden usar para todos los paquetes
que usen esa máquina virtual; para instalar Scala sólo hay que crear
este último fichero.
Todos estos, por cierto, tienen que ejecutarse desde directorios
específicos, al menos la forma más simple de hacerlo es copiar todos
los ficheros .sls
a ~/lib/salt/states
y hacerlo desde ahí.
En general, y por la forma que tiene un poco rígida de hacer las
cosas, resulta algo más complicado usarlo que Ansible o incluso
Chef. Sin embargo y limitado a salt-ssh
, una vez que la
configuración está completa y si se tienen configuraciones base,
construir a partir de ellas es relativamente sencillo.
Provisionar una máquina virtual en algún entorno con los que trabajemos habitualmente usando Salt.
Las principales alternativas a Chef son Ansible, Salt y Puppet. Todos ellos se comparan en este artículo, aunque los principales contendientes son Puppet y Chef, sin que ninguno de los dos sea perfecto.
De todas ellas, vamos a ver Ansible que parece ser uno de los que se está desarrollando con más intensidad últimamente. Ansible es sistema de gestión remota de configuración que permite gestionar simultáneamente miles de sistemas diferentes. Está basado en YAML para la descripción de los sistemas y escrito en Python.
Se instala como un módulo de Python, usando por ejemplo la utilidad de
instalación de módulos pip
(que habrá que instalar si no se tiene)
sudo pip install paramiko PyYAML jinja2 httplib2 ansible
El resto de las utilidades son también necesarias y en realidad se instalan automáticamente al instalar ansible. Estas utilidades se tienen que instalar en el anfitrión, no hace falta instalarlas en el invitado, que lo único que necesitará, en principio, es tener activada la conexión por ssh y tener una cuenta válida y forma válida de acceder a ella.
Cada máquina que se añada al control de Ansible se tiene que añadir a un fichero, llamado inventario, que contiene las diferentes máquinas controladas por el mismo. Por ejemplo
$ echo "ansible-iv.cloudapp.net" > ~/ansible_hosts
se puede ejecutar desde el shell para meter (echo
) una cadena con
una dirección (en este caso, una máquina virtual de Azure) en el
fichero ansible_hosts
situado en mi directorio raíz. El lugar de ese
fichero es arbitrario, por lo que habrá que avisar a Ansible donde
está usando una variable de entorno:
export ANSIBLE_HOSTS=~/ansible_hosts
Y, con un nodo, ya se puede comprobar si Ansible funciona con
$ ansible all -u jjmerelo -m ping
Esta orden hace un ping, es decir, simplemente comprueba si la
máquina es accesible desde la máquina local. -u
incluye el nombre
del usuario (si es diferente del de la máquina local); habrá que
añadir --ask-pass
si no se ha configurado la máquina remota para
poder acceder a ella sin clave.
De forma básica, lo que hace Ansible es simplemente ejecutar comandos de forma remota y simultáneamente. Para hacerlo, podemos usar el inventario para agrupar los servidores, por ejemplo
[azure]
iv-ansible.cloudapp.net
crearía un grupo azure
(con un solo ordenador), en el cual podemos
ejecutar comandos de forma remota
$ ansible azure -u jjmerelo -a df
nos mostraría en todas las maquinas de azure la organización del
sistema de ficheros (que es lo que hace el comando df
). Una vez más,
-u
es opcional.
Esta orden usa un módulo de ansible y se puede ejecutar también de esta forma:
$ ansible azure -m shell ls
haciendo uso del módulo shell
. Hay muchos
más módulos a los que se le
pueden enviar comandos del tipo “variable = valor”. Por ejemplo, se
puede trabajar con servidores web o
copiar ficheros
o
incluso desplegar aplicaciones directamente usando el módulo git
Desplegar los fuentes de una aplicación cualquiera, propia o libre, que se
encuentre en un servidor git público en la máquina virtual Azure (o
una máquina virtual local) usando ansible
.
Finalmente, el concepto similar a las recetas de Chef en Ansible son los playbooks, ficheros en YAML que le dicen a la máquina virtual qué es lo que hay que instalar en tareas, de la forma siguiente
---
- hosts: azure
sudo: yes
tasks:
- name: Update emacs
apt: pkg=emacs state=present
Esto se guarda en un fichero y se le llama, por ejemplo, emacs.yml, y se ejecuta con
ansible-playbook ../../ejemplos/ansible/emacs.yml
(recordando siempre el temita del nombre de usuario), lo que dará, si todo ha ido bien, un resultado como el siguiente
En el fichero YAML lo que se está expresando es un array asociativo
con las claves hosts
, sudo
y tasks
. En el primero ponemos el
bloque de servidores en el que vamos a actuar, en el segundo si hace
falta hacer sudo o no y en el tercero las tareas que vamos a ejecutar,
en este caso una sola. El apartado de tareas es un vector de hashes,
cada uno de los cuales tiene en name
el nombre de la tarea, a título
informativo y en las otras claves lo que se va a hacer; apt
indicará
que hay que instalar un paquete (pkg
) llamado emacs
y que hay que
comprobar si está presente o no (state
). El que se trabaje con
estados y no de forma imperativa hace que los playbooks sean
idempotentes, es decir, si se ejecutan varias veces darán el mismo
resultado que si se ejecutan una sola vez.
El siguiente tema sería el de orquestación de máquinas virtuales, donde se aprenderá a trabajar con configuraciones más complejas que usen varias máquinas virtuales a la vez.
A partir de aquí se puede seguir aprendiendo sobre devops en el blog o en IBM. Libros como DevOps for Developers pueden ser también de ayuda. Esta comparativa de sistemas de configuración te permite ver todos los que hay, ver la última columna cuáles son los más recientemente actualizados y qué esperar de cada uno de ellos. También en este gist explica las diferencias entre herramientas en este área, incluyendo también Puppet e incluso Docker. En presentaciones como esta se habla de CAPS: Chef, Ansible, Puppet and Salt como una categoría en sí. En este artículo también los comparan y en este último llevan a cabo la configuración de un servidor simple usando los cuatro.