¿Que #$%!@& es Docker?

En marzo del año 2013 se empezó a escuchar cada vez con más fuerza el nombre Docker. Algunos que no recordaban el nombre le decían el proyecto de la ballenita”. Otros hablaban de un nuevo proyecto que hacía correr a las máquinas virtuales más rápido y consumiendo menos recursos. Los más avanzados hablaban de un nuevo proyecto que estaba revolucionando el uso de los contenedores en entornos Linux.
Pero de todo lo anterior. ¿Qué cosa es cierta? ¿Qué son los contenedores? Y lo más importante. ¿Qué #$%!@& es Docker?
 

Si nos dirigimos a la definición de Wikipedia encontramos la siguiente.
 
Docker es un proyecto de código abierto que automatiza el despliegue de aplicaciones dentro de contenedores de software, proporcionando una capa adicional de abstracción y automatización de Virtualización a nivel de sistema operativo en Linux.”
 
Pero que la palabra Virtualización” no nos confunda. Lo que quiere decir es que Docker se hace uso de las características de aislamiento de recursos del kernel Linux, tales como cgroups y namespaces para permitir que contenedores” independientes se ejecuten dentro de una sola instancia de Linux, evitando la sobrecarga de iniciar y mantener máquinas virtuales.
Los namespaces aísla de vista, en su mayoría, una aplicación del entorno operativo, incluyendo árboles de proceso, red, ID de usuario y sistemas de archivos montados, mientras que los cgroups del kernel proporcionan aislamiento de recursos, incluyendo la CPU, la memoria, el bloque de E / S y de la red. 
 
Como se explicó los contenedores” ya es una función que se incluye en cualquier kernel Linux. Haciendo una analogía con los contenedores que todos conocemos y vemos en grades estaciones de cargas podemos decir entonces que un contenedor de software” puede albergar cualquier aplicación y mantenerla a salvo miestras está funcionando en cualquier infraestructura como puede ser una laptop, servidor físico o incluso en una nube.

Contenedores vs. máquinas virtuales

Quien se acerca por primera vez a Docker tiende a pensar que es una especie de máquinas virtuales ligeras o una suerte de aplicaciones empaquetadas, pero el concepto dista bastante de estas soluciones. En primer lugar no existe un hipervisor que virtualice hardware y sobre la que se despliegue un sistema operativo completo y se cree un elenco de dispositivos virtuales. En Docker lo que haremos es usar las funcionalidades del Kernel para encapsular un sistema. De esta manera este contenedor tendrá su propio árbol de procesos, sus propias interfaces de red, su propio subsistema, etc. De tal forma que la aplicación que corra dentro de él no sabrá que está en un contenedor. Los contenedores están aislados entre sí  y podemos limitar los recursos que utilizará (RAM, CPU, ancho de banda, i/o de disco, etc.). A todos los efectos se comportarán como máquinas independientes.
 
Además iniciar un contenedor tiene un impacto muy liviano. A diferencia de las máquinas virtuales o físicas no es necesario iniciar un sistema operativo completo con sus chequeos y arranque de procesos iniciales que corren en la fase inicial i/o de disco, CPU y RAM hasta que el sistema se estabiliza. Usando contenedores la demanda de recursos se limitará al consumo de la aplicación que resida dentro. Poner en ejecución un contenedor es cuestión de milisegundos.
 
La segunda ventaja viene dada por el sistema de imágenes. Un contenedor no es más una imagen puesta en ejecución a la que otorgamos recursos. Estas imágenes están compuestas por capas de solo lectura a las que se le añade una capa superior de escritura que perdurará sólo mientras el contenedor está en ejecución. En la construcción de la imagen se crea una capa por cada cambio que hagamos, de tal forma que si imaginamos una aplicación que corra  sobre jboss podríamos simplificar que tendríamos las siguientes capas:
 
  • Sistema operativo base
  • Jboss
  • Nuestra aplicación

¿Qué ventaja aporta esto?

La más evidente es un ahorro de espacio en disco: Si ejecutamos 100 instancias de un mismo contenedor solo tendremos una copia de las capas inferiores. Además si ejecutamos contenedores distintos pero que comparten capas nos ocurrirá lo mismo (Ej: base de datos, backend, frontend que comparten java y el mismo S.O.).

Comparado con las máquinas virtuales no es necesario descargar la imágen completa sino solo las capas que hayan cambiado. Frente a herramientas de gestión de la configuración como Puppet, Chef o Ansible, no tendremos que esperar a que se apliquen sus políticas, se actualicen los paquetes necesarios… en cada instancia, sino que lo haremos una única vez y todos los contenedores que se pongan en ejecución o se actualicen tendrán esos cambios. Esto nos permite realizar despliegues de una forma muy rápida y ordenada sin perder peticiones en el proceso.
 
Hay que pensar que nuestra imagen contiene todo y solo lo necesario para ejecutar la aplicación que reside dentro de él. No necesitamos librerías, ejecutables, módulos o drivers de los que nuestra aplicación no haga uso con lo cual el tamaño es más contenido que en un sistema completo, es decir, una imagen es autocontenida y nos garantiza que se ejecutará igual en cualquier host que tenga el engine de Docker, ya sea la laptop de un desarrollador, una máquina virtual o la nube.
 

La seguridad a un nivel básico se mejora de varias maneras

Las buenas prácticas de Docker indican que solo un proceso debe correr por contenedor, esto implica una menor exposición de procesos y un menor número componentes ofrece menos superficie” en la que buscar exploits o realizar ataques. Las capas además están identificadas por un hash que se genera en función de su contenido, lo que garantiza la integridad de estas. Y si aún necesitamos más confianza podemos habilitar el firmado de las imágenes. También podemos llevar prácticas como la infraestructura inmutable al extremo y poner en ejecución contenedores en solo lectura que no permitan escrituras en ellos imposibilitando que en una intrusión se inyecte código.

Un poco de historia

Desde el 13 de marzo de 2013 cuando Docker libera su código bajo la licencia Apache 2.0 y Creative Commons se le añadieron funcionalidades automatizando las existentes para hacerlo más portable y ampliando su alcance. Tal es así que en la actualidad Docker Inc mantiene más de 20 proyectos que abarcan desde la coordinación de contenedores para ayudar al desarrollador hasta la orquestación de grandes clusters distribuidos.
El 13 de marzo de 2014 decide crear su propia librería escrita en Go, posibilitando la eliminación de la necesidad de parchear el Kernel y creando herramientas alrededor de su motor. 
A partir del año 2015 muestra su potencia y robustéz consiguiendo la financiación y colaboración por parte de Red Hat, IBM, Microsoft, Ubuntu. Google, la empresa empieza a crear un vasto ecosistema de aplicaciones alrededor de este motor. En la actualidad en prácticamente todas las etapas del ciclo de vida de una aplicación podemos usar alguna de sus herramientas:
 
Como dijimos, todos los proyectos (salvo las herramientas comerciales) están liberadas bajo la licencia Apache 2.0 y el código está disponible en GitHub. Además construye todo el sistema de cañerías (plumbing) para que terceros puedan crear productos y plugins usando su base tecnológica sin generar incompatibilidades.

¿Se puede usar Docker en otros sistemas operativos que no sean Linux?

Sí. Dado el auge de los contenedores, Microsoft llega a un acuerdo con la compañía y decide incorporar esta tecnología a su sistema operativo. Podemos usar contenedores nativos Docker con Kernel Windows en Windows 2016 y Wwndows 10 aniversary edition. Además Microsoft es el mayor contribuyente al código tras Docker Inc y ha firmado acuerdos para garantizar que Docker se ejecute correctamente en sus sistemas ya sea nativamente o usando Kernel Linux mediante virtualización (hyper-V). También da soporte en Azure a nivel de IaaS, PaaS y Web App. En los sistemas MacOS también se utiliza una herramienta que virtualiza el motor de Docker permitiendo su utilización y administración.

¿En qué casos debería usar Docker?

Muchos desarrolladores ajenos a Docker se preguntan si deberían usar Docker en sus proyectos, en qué casos deberían usarlos y en cuáles no. A todas estas preguntas y desde mi opinión y experiencia profesional les diría que deberían usar Docker en todos sus proyectos, ya que gracias a sus ventajas, rapidez y facilidad de uso Docker empodera a los desarrolladores en términos de configuración, empaquetamiento y distribución de su aplicación, fomentando la creatividad y la flexibilidad en el proceso de desarrollo. En los únicos casos muy puntuales en los que no usaría Docker es en los que el cliente no lo permita, en los que el proyecto ya incluya ciertos estandares que no faciliten el uso de Docker o en el que un superior así nos lo indique.
 

Una presentación en video para poder aclarar mejor las cosas.

 
 
 
 
Les dejo la presentación para que puedan utilizarla y mejorarla donde lo crean necesario.
 
 
 
 
Como siempre, les recuerdo que este artículo pretende compartir mis conocimientos y experiencias. Pero me gustaría que ustedes me comentan sus experiencias y conocimientos para poder nutrir los míos y el de otros visitantes.
 

 

Enlaces útiles

Apuntes IT - Compartiendo conocimiento.
Tech Nerd theme designed by Siteturner
Share
Share