Pages Menu
Categories Menu

Posted by on Ago 21, 2015 in General | 5 comments

Docker vs Vagrant, Puppet, Chef o Ansible

Bajo el área de DevOps que está tan de moda y que avanza bastante deprisa, se habla de muchas tecnologías: virtualización, Puppet, Chef, Ansible, Vagrant, ahora Docker… Muchas veces oímos estos términos para cosas tan relacionadas entre sí, que si no tienes claro para qué sirve cada herramienta y estás empezando a meterte en este mundillo te puedes liar con ellas.

Después del post de Puppet (Simplifica drásticamente la administración de sistemas: Puppet en 10 min.) y los posts de iniciación a Docker de hace unas semanas (¿Qué es Docker? ¿Para qué se utiliza? Explicado de forma sencilla.Entendiendo Docker. Conceptos básicos: Imágenes, Contenedores, Links…) hoy quiero que con este post te quedes con una idea general de qué idea hay detrás de cada una de estas tecnologías y qué las diferencia.

Si no sabes qué es Puppet y Docker, te recomiendo que leas los posts que mencioné anteriormente, ya que en este post me centraré más en comparar las herramientas que en decir en qué consiste cada una de ellas.

Y ya que Docker ha sido la tecnología que más hemos tratado en los posts de las últimas semanas, compararé Docker con cada una de las tecnologías más famosas hasta la fecha y que más confusión pueden generar: máquinas virtuales, Vagrant, Puppet, Chef y Ansible.

Docker vs Máquinas virtuales

Ya hablamos de la diferencia entre estas dos tecnologías en el primer post de Docker (te recomiendo que lo leas si no sabes lo que es Docker), pero creo que viene bien refrescar el tema y tener todas las diferencias resumidas dentro del mismo post.

Realmente el concepto de Docker y máquina virtual es algo similar, pero un contenedor no es lo mismo que una máquina virtual. Un contenedor es más ligero, ya que mientras que a una máquina virtual necesitas instalarle un sistema operativo para funcionar, en los aspectos más básicos, un contenedor de Docker funciona utilizando el sistema operativo que tiene la máquina en la que se ejecuta el contenedor (hasta la fecha Docker solo funciona sobre máquinas Linux, ya que esta herramienta viene de los contenedores de Linux LXC).

Digamos que el contenedor de Docker toma los recursos más básicos, que no cambian de un ordenador a otro del sistema operativo de la máquina en la que se ejecuta. Y los aspectos más específicos del sistema que pueden dar más problemas a la hora de llevar el software de un lado a otro, se meten en el interior del contenedor.

Para que te hagas una idea, el concepto de portabilidad de un contenedor de Docker es algo similar a la máquina virtual de Java.

Que un contenedor Docker tome los aspectos básicos de funcionamiento del sistema operativo de la máquina en la que se ejecuta lo vuelve más ligero que una máquina virtual.

Docker vs Vagrant

A grandes rasgos, Vagrant es una herramienta para gestionar máquinas virtuales. Por ello, Vagrant se ejecuta sobre VirtualBox, VMware, etc. Y como aprovisionamiento de dicha máquina (indicar qué quieres que tenga la máquina virtual) puedes utilizar Puppet, Chef o incluso un contenedor de Docker.

Por el contrario Docker no necesita ejecutarse sobre una máquina virtual, se ejecuta directamente sobre una máquina Linux, ya que sirve para crear contenedores y ejecutar tus aplicaciones en dichos contenedores. Por ejemplo, un contenedor con java, un servidor Tomcat y tu aplicación ejecutándose en el servidor.

Digamos que puedes ejecutar tus aplicaciones con todo lo que necesitan ahí dentro, incluso interactuar con ella. Después puedes mover dicho contenedor y ejecutarlo con Docker en otra máquina.

Además se pueden versionar contenedores de Docker con cada cambio que hagas (instalar una nueva librería, un cambio en el código de la aplicación…). Incluso, si por ejemplo a nivel de Docker ya tienes una imagen de Java 8, si te creas otro contenedor que dependa de ese no tendrás que volver a bajarte la imagen de Java 8.

Por otra parte, si necesitas ejecutar contenedores de Docker sobre otros sistemas, tienes que o crearte una máquina virtual con Linux o usar Boot2Docker.

Para entrar en una comparación más igualitaria, no compararía Vagrant con Docker, sino que compararía Vagrant con Boot2Docker, la herramienta que permite ejecutar Docker en máquinas Windows y MacOs.

Boot2Docker es una virtualización que instala Linux y lo necesario para poder ejecutar Docker.

A modo de resumen de este punto, si tengo una máquina Windows y quiero usar Docker, como Docker solo se ejecuta sobre Linux, tengo como alternativas:

– Utilizar Vagrant para montar una máquina virtual Linux y sobre eso ejecutar los contenedores de Docker.

– Montar una máquina virtual Linux y ejecutar Docker.

– Utilizar Boot2Docker.

Docker vs Puppet

El pensamiento de Puppet es completamente diferente a los conceptos de virtualización, o contenedores. Puppet es una herramienta de gestión de configuración (ojo, de máquinas, sistemas, no lo confundas con la política de ramas, versionado, control de versiones, etc.)

Puppet revolucionó el mundo de sistemas al promover el concepto de tener la configuración, el estado de las máquinas como código, que se puede versionar y se puede cambiar fácilmente (infraestructura como código).

Entre otras cosas, Puppet sirve para aprovisionar máquinas, es decir, indicar qué software, qué paquetes y qué versiones de ese software tiene la máquina sobre la que se ejecuta, que puede ser directamente un servidor, el ordenador de tu casa o una máquina virtual.

El motor de Puppet sigue una arquitectura maestro/agente. En nuestras máquinas, servidores, aquellas cuya configuración queremos tener controladas y automatizadas, instalaremos los agentes de Puppet. Para cada uno de estos nodos, tendremos un archivo propio de Puppet llamado manifest, donde indicaremos qué software queremos que tenga la máquina y en qué versiones.

El maestro de Puppet consultará el estado de nuestras máquinas cada cierto tiempo, y si el software que tienen no coincide con lo que indicamos en dichos archivos, Puppet instalará los componentes necesarios, o cambiará la versión del software automáticamente. Esto nos ahorra tener que cambiar la configuración de todas nuestras máquinas una a una.

Aquí tienes un ejemplo de archivo manifest de Puppet, en el que, entre otras cosas, indicamos que queremos que la máquina tenga instalado un servidor Apache.

manifest

Sacado de http://blog.akquinet.de/2011/11/23/managing-an-apache-server-with-puppet/.

Como puedes apreciar, el lenguaje en el que se escribe el archivo es propio de Puppet, no es un lenguaje de programación, y ni siquiera escribimos comandos de Unix.

Si en este manifest indicamos la versión del software, y la cambiamos, cuando Puppet compruebe el estado de nuestra máquina y vea que la versión del paquete no coincide, automáticamente lo actualizará para que coincida con esa versión.

En cambio con Docker, tenemos imágenes con ciertos software y paquetes instalados (podemos crearlas a través de un fichero llamado DockerFile), que al ejecutarse se transforman en contenedores con los que podemos interactuar y hacer ciertas cosas.

dockerFile

Ejemplo de DockerFile para tener una imagen con Ubuntu y apache. Sacado de https://github.com/kstaken/dockerfile-examples/blob/master/apache/Dockerfile

La primera diferencia que puedes observar entre “los archivos” de Docker y Puppet, es que en un manifest de Puppet no siempre tienes que indicarle con qué comando se instala el paquete de software. En cambio, en un archivo DockerFile, indicas los comandos de Linux necesarios para crear una imagen con los elementos que quieres.

Puppet necesita trabajar sobre una máquina directamente, sobre una máquina virtual, o con Vagrant. Por otra parte, Docker es capaz de crear un contenedor, una unidad de trabajo que contiene todo lo necesario para moverlo entre distintos entornos (desarrollo, test, etc.) por sí solo, sin demasiada dificultad.

Hay gente que utiliza Puppet y Docker de forma conjunta, pero de momento yo no soy capaz de verle el beneficio en cuanto al uso más básico de ambas herramientas.

Docker vs Chef o Ansible

Chef y Ansible, al igual que Puppet, son herramientas de gestión de configuración, su objetivo es tener la infraestructura como código y automatizar la configuración de las máquinas.

Aunque Chef, Ansible y Puppet tienen diferencias entre sí, su objetivo prácticamente es el mismo. Sí que se podría decir que en cuanto a arquitectura y funcionamiento Chef es más parecido a Puppet, aunque los archivos de configuración de las máquinas (en Chef se llaman recipes) se escriben en Ruby y no en un lenguaje propio.

Por otra parte, Ansible está escrito en Python, y la mayoría de la gente que ha usado Puppet y Ansible comenta que la curva de aprendizaje de Ansible es mucho menor que la de Puppet.

Por lo tanto, las diferencias de concepto entre Docker y Chef o Ansible, son las mismas que en el punto anterior de Docker vs Puppet. Docker crea una unidad autocontenida, aislada, con la que podemos interactuar y llevar a distintas máquinas. Puppet, Chef, Ansible sirven para gestionar la configuración de las máquinas, ya sean virtuales, aprovisionar máquinas de Vagrant o físicas.

Terminando…

Y la pregunta de siempre: de todas estas tecnologías…¿cuál es mejor? Pues depende de lo que necesites y lo que quieras conseguir. ¿Quieres optar por virtualización o por contenedores? ¿Algo a gran escala o a pequeña escala? En mi opinión, no creo que ninguna de estas tecnologías sea completa y solucione todos los problemas de sistemas por sí sola. Dependiendo del caso deberás usarlas de forma complementaria o con otras herramientas que solucionen otras cuestiones que te encuentres en su implantación. Ya ves como en los propios ejemplos que he puesto, muchas de ellas se utilizan de forma conjunta (Vagrant y Puppet…etc.).

Lo que si está claro, es que da igual el enfoque que sigas: la automatización de la gestión de la configuración de máquinas ahorra mucho tiempo, muchos fallos humanos y facilita los despliegues.

Por otra parte, nos da la oportunidad de tener entornos de desarrollo o de test muy próximos al de producción, y ayuda a reducir los fallos debidos a las diferencias entre entornos. Todo ello, para que podamos escuchar menos nuestra típica frase de “pues a mí en local me funcionaba”.

Ana M. del Carmen García Oterino

Ana M. del Carmen García Oterino

Ingeniera Software QA at BQ
https://www.linkedin.com/in/amgarciao

Apasionada por la calidad del software (procesos, producto y equipos) y buenas prácticas en general.

Especializada en testing, automatización de pruebas e integración continua.
Ana M. del Carmen García Oterino

5 Comments

  1. Hola, os planteo nuestra situación porque llevo algún tiempo leyendo vuestros artículos sobre virtualización pero no me queda claro si alguna de estas herramientas nos podrían ayudar a mejorar:

    En nuestro departamento de desarrollo montamos una máquina virtual para cada proyecto y cuando un equipo tiene que implementar un desarrollo sobre la aplicacion A cogen la máquina virtual MA del repositorio general con todo lo necesario para el desarollo de dicha aplicación (IDE, servidor, java, certificados, bdd, ldap etc.), cada uno se la importa en local, hacen lo que sea, entregan el evolutivo y luego un miembro del equipo devuelve la máquina al repositorio general si ha habido cambios.

    Los problemas:
    1) Cada máquina de VirtualBox son 10Gb, y las de algunos proyectos necesitan 4Gb de ram dedicados para ejecutarse con fluidez con lo cual a veces lo pasamos mal con el espacio y la memoria.
    2) No tenemos control sobre los cambios, nos gustaría poder identificar los cambios desde la máquina virtual del repositorio general a la que se devuelve (e incluso entre las diferentes personas del equipo): cambios de librerías, programas instalados, versiones de java, servidores etc. Ya que actualmente el único control que hay es un changelog.txt muy dependiente de errores humanos y olvidos

    Estuve investigando Docker pero creo que no nos vale, ya que lo veo más para tener montado un servidor en el que desplegar cosas manteniendo un entorno pero no puedo tener un IDE con interfaz gráfica. Puppet por lo que he visto tampoco me vale, porque lo que haría seria forzar a tener ciertas versiones de software instalado pero en realidad lo que queremos es que los equipos tengan libertad de cambiar lo que sea necesario en la máquina pero que estos cambios queden registrados, y entiendo que Chef o Ansible son tres cuartos de lo mismo, corregidme si me equivoco. Vagrant me faltaría indagar un poco más.

    En resumen si tenéis cualquier indicación al respecto, incluida la respuesta “tus 2 problemas no se pueden solucionar con estas tecnologías” me sería de gran ayuda.

    • Hola Alex,
      Aunque no se si te será de utilidad, te cuento como tratamos de hacerlo nosotros.
      La idea de docker es que el entorno donde corre la aplicación sea prácticamente igual en cualquier máquina donde se ejecute, por lo que la imagen de docker debería de llevar el mismo stack de software que va a correr tanto para el entorno de desarrollo, como de test, producción … En nuestro caso, las imágenes de desarrollo suelen llevar todo el stack necesario y ejecutar todos los servicios necesarios en un único container, pero en producción esos servicios están divididos, cada servicio en su propio container.
      Aunque son prácticamente imágenes distintas, también usamos chef para construirlas, por lo que el proceso de pasar de una imagen monolítica a varias cada una con su servicio está bastante automátizado.
      Una opción interasente además, que permite docker es el concepto de volumen, el cual es muy útil para compartir un directorio entre el anfitrión donde corre el container y el interior del mismo, es por así decir, como una carpeta compartida.
      Nosotros, en nuestro entorno de desarrollo, usamos los volumenes, para montar el código del proyecto dentro del container, de forma que podamos editarlo desde el exterior (con un IDE instalado localmente) pero a su vez, podamos probar la aplicación desde dentro del container (Usamos un ) para facilitar esto.
      En producción ese volumen no existe sino que la propia imagen se construye con la última actualización del código del proyecto.

  2. bueno, yo utilizo conjuntamente docker con puppet. Según mi opinión son dos herramientas completamente diferentes y para lo que yo quiero se acoplan perfectamente. Utilizo docker para no tener que montar máquinas virtuales y puppet para automatizar procesos en servidores externos.

  3. se puede utilizar vagrant, y provisionar con shell, puppet,ansible, etc..
    solo habria que guardar el Vagrantfile y los ficheros de configuracion que se utilizen para provisionar.

  4. jaja la máxima del programador “pero en mi maquina si funciona”

Post a Reply

Tu dirección de correo electrónico no será publicada.

Share This