Docker y la magia de los containers

Hola con todos :) mucho tiempo desde mi úlitmo post, debo admitir, pero tras poder solucionar unas cuantas situaciones personales y externas, al fin estoy en condiciones de poder escribir nuevamente. Y el primer tema que quiero compartir con ustedes es esta tecnología, que aunque ya bastante tiempo lleva en entornos de producción a nivel mundial, es algo que he descubierto últimamente.

¿Qué es Docker?

Para ponerlo de forma sencilla, Docker es la siguiente generación de virtualización. Esto quiere decir que en su uso, aplicamos las bases de lo que podría considerarse una virtualización ultra ligera. Y esta ligereza radica en su implementación a nivel de kernel.

Docker y el kernel

Antiguamente la virtualización se realizaba a nivel de hardware, esto quiere decir que teníamos sistemas operativos corriendo un kernel especialmente diseñado para generar distintas instancias de máquinas virtuales directamente conectadas con el hardware. Estas soluciones son bastante eficientes y seguras, y permiten una conexión directa cuando hablamos en términos físicos. Con el tiempo se pasó a un modelo de virtualización a nivel de software, donde teníamos un equipo denominado host en el cual se generaba un proceso que producía instancias de máquinas virtuales de tipo guest.

Este es un modelo muy utilizado en equipos personales, al menos yo lo he utilizado durante mucho tiempo y siempre había tenido un tipo de máquina virtual para poder realizar cada trabajo de programación.

Con el paso del tiempo el kernel fue desarrollando nuevas tecnologías que aceleraron el proceso de virtualización, pero también tecnologías alternas que abrieron nuevas puertas.

El overheat

Crear máquinas virtuales no es un proceso sencillo a nivel de recursos, puesto que en las abstracciones necesarias, los equipos tanto host como guest generan todo un árbol de procesos, muchos de los cuales son completamente innecesarios en distintos escenarios, y es este el motivo por el cual en un sistema no siempre puedas tener una gran cantidad de máquinas virtuales, por darles un ejemplo… en mi laptop yo he llegado a ejecutar 4 máquinas virtuales guest en paralelo, pero mi procesador i7 no daba para más, puesto que en todas el trabajo era bastante lento.

Cuando hablábamos de estas nuevas tecnologías, existieron dos que abrieron paso a la era de los containers: cgroups (control groups)namespaces.

Control groups, namespaces y containers

Los cgroups son una característica del kernel que permite controlar la cantidad de recursos que un proceso ocupa, esto quiere decir que puedo indicar si un proceso tiene un tope de RAM, o de capacidad de entrada y salida, entre otras cosas.

Los namespaces proporcionan contextos de ejecución tanto para usuario como para grupos, en palabras sencillas quiere decir que distintos grupos de procesos pueden contar con un tipo específico de privilegios que no necesariamente aplican para el resto del sistema.

Los containers aplican estas dos tecnologías de la siguiente manera: antes, la virtualización generaba un kernel base, y sobre este se colocaban capas de kernels abstractos o puentes entre host guest. Ahora el mismo kernel puede manejar todos los procesos, asignando un espacio y una capacidad mínima o máxima. Esto permite que en lugar de la gran cantidad de proceso que una máquina virtual ejecuta, solo se generen 2 o 3 servicios en un espacio aislado.

Imágenes y containers

Las imágenes de Docker son estructuras superpuestas de filesystems que permiten trabajar en la parte superior. Existen imagenes “base” sobre las cuales se van agregando configuraciones y archivos para generar entornos funcionales. Una vez que un entorno funcional se ejecuta, docker genera un container con el proceso que deseemos correr.  Esto nos brinda un ambiente aislado donde solo se ejecutan uno o unos cuantos procesos. Esto nos brinda la posibilidad de lanzar cientos o incluso miles de containers dentro del mismo host. Pero como sé que mejor es mostrar que explicar, vamos a ver un ejemplo bastante sencillo :)

Docker y Jenkins

Una vez tengamos el demonio de docker corriendo, vamos a utilizar una de sus principales características, buscar imágenes :) Docker nos brinda un servicio parecido al de Github, en donde podemos descargar imágenes ya diseñadas por otros, en mi caso voy a buscar Jenkins, y como podrán ver, tengo varios resultados. Cuando un nombre no tiene una separación con / se le considera una imágen base. Por lo que vamos a descargar la imagen de jenkins con

docker pull jenkins

Una vez descargado vamos a ejecutar el siguiente comando:

docker run -P --name myjenkins jenkins

Esto generará una lista de logs que son el proceso de jenkins que se está ejecutando :) ya tenemos un jenkins funcionando, pero necesitamos conocer el puerto en donde está trabajando, para eso utilizamos el siguiente comando:

docker port myjenkins

Como pueden ver, tenemos dos puertos activos, y el conocido 8080 nos redirige a 327669, vamos a abrir ese puerto en nuestro navegador :)

¡Ya casi tenemos todo listo! Ahora nos habla sobre una clave generada, pues sencillo :) en nuestra terminal de logs debe aparecer una clave que podamos usar:

Y eso es todo, ahora tenemos jenkins trabajando en nuestro sistema, pero en su propio container.

Lo genial de todo esto es que ¡tan solo han sido 3 comandos! Y 3 bastante sencillos vale la pena mencionar. Ahora bien, este es solo el principio, pero qué tal si les digera que Docker puede generar redes internas, ambientes de prueba, funcionar como cluster, y muchas otras cosas más… pues ahora entienden por qué tenía ganas de compartir este tema con ustedes :)

Pero son muchos los puntos y un post no alcanza para poder contarlo todo, así que tal vez con un poco de tiempo podramos seguir este tema si lo han encontrado interesante :) Un saludo y gracias por su visita. Ahh y lo olvidaba, para detener el container y volverlo a encender en otro momento pueden usar:

docker stop/start/restart myjenkins

Sencillo ;)