¿Qué es Docker y qué ventajas tiene trabajar con sus contenedores?

Docker es una plataforma de virtualización a nivel de sistema operativo —software containerization platform, en inglés—. Una plataforma de este tipo permite crear una aplicación y empaquetarla junto con sus dependencias y librerías en un contenedor o  container, como se conocen habitualmente. Este contenedor software, a su vez, puede ejecutarse en otras máquinas.

Si nos fijamos, el término virtualización ya nos está dando una pista de cómo funciona este sistema. En realidad, estamos hablando de una evolución del concepto de virtualización con importantes diferencias que inclinan la balanza del lado de los contenedores. En esencia, se podrían realizar las mismas tareas mediante máquinas virtuales, pero el resultado no sería muy eficiente.

Diferencias entre la virtualización y los contenedores

En general, se entiende que la virtualización es la creación a través de software de una versión virtual de algún recurso tecnológico. Estos recursos pueden ser desde un dispositivo de almacenamiento, pasando por un recurso de red, cualquier tipo de hardware o un sistema operativo.

La creación de máquinas virtuales que recrean sistemas operativos es algo costoso a nivel de recursos —memoria RAM, capacidad de procesamiento o almacenamiento— puesto que el sistema operativo virtualizado se ejecuta sobre el sistema operativo host, y tendrá su propio kernel y un conjunto de bibliotecas y dependencias.

Los recursos que utiliza cada máquina virtual son finitos, pero son recursos que se restan de la capacidad total de la máquina que las soporta. Por ello, no es una solución muy eficiente en algunos contextos.

En cuanto a la virtualización a nivel de sistema operativo —en inglés, containerization—, lo que se consigue es la abstracción del sistema operativo. En el caso de la virtualización nos abstraemos del hardware. Es una diferencia sutil, pero decisiva. Esta abstracción del sistema operativo implica que el contenedor dispondrá de los recursos necesarios para que la aplicación que contiene pueda ejecutarse en cualquier sistema —siempre y cuando disponga de las herramientas necesarias, como veremos—.

La virtualización a nivel de sistema operativo es mucho más eficiente porque, básicamente, no hay que virtualizar un sistema operativo: se trabaja directamente con el SO de la máquina que ejecutará los contenedores. Cada contenedor alberga las librerías específicas para la aplicación y no las comparte con otros contenedores. Son unidades autocontenidas, lo que las hace más rápidas y eficientes que las máquinas virtuales.

Es necesaria una capa extra para la gestión de los contenedores. Se denomina conteinarization layer y lo que permite es la creación y ejecución de los contenedores en nuestro sistema operativo.

Docker y sus contenedores

Docker es una plataforma de virtualización a nivel de sistema operativo, como definimos en la primera línea del artículo. Ahora ya sabemos en qué consisten los contenedores, así que podemos decir que con esta plataforma podemos crear diferentes contenedores para nuestras aplicaciones y sus dependencias. De esta manera, dicha aplicación puede ejecutarse sin problema alguno en cualquier entorno, es 100% portable.

Cada aplicación se ejecuta en un contenedor independiente con, como hemos dicho, las librerías y dependencias necesarias para poder funcionar con normalidad —eso las hace independientes de la versión del sistema operativo o de las versiones de librerías y dependencias disponibles en el SO, o incluso que estas no existan siquiera en nuestro sistema— lo que garantiza el aislamiento perfecto de dicho software.

Por ese motivo, los contenedores dan al desarrollador la tranquilidad de que pueden desarrollar y probar aplicaciones que no interfieren con ninguna otra.

La ventaja de Docker resulta ser muy evidente: es posible encapsular todo el entorno de trabajo, de manera que los desarrolladores pueden estar trabajando en su servidor local con la seguridad de que, al llegar el momento de poner la aplicación en producción, se va a ejecutar con la misma configuración sobre la que se han hecho todas las pruebas.

Otras ventajas claras de Docker son su ligereza —al no virtualizar un sistema completo el consumo de recursos es mínimo, ahorrando alrededor de un 80% de dichos recursos—, la portabilidad y su autosuficiencia, pues Docker se encarga de la gestión del contenedor y de las aplicaciones que contenga.

Se trata, por tanto, de un entorno de pruebas seguro que, gracias a sus características, proporciona un aislamiento suficiente que garantiza al desarrollador la ejecución de su aplicación en el entorno original, sin preocuparse de hacer nada para garantizar la portabilidad, tal y como comentábamos en el artículo ¿Por qué utilizar Docker en nuestros desarrollos?.

Componentes de Docker

Para entender Docker hemos de entender el concepto de container image. Aunque extenderemos estas explicaciones en futuros contenidos, hay que decir que un contenedor se considera la instanciación de una imagen. La imagen es una especificación estática de lo que debería ser el contenedor en tiempo de ejecución, incluido el código de la aplicación y las configuraciones de tiempo de ejecución.

Las imágenes de Docker contienen capas de solo lectura. Es decir, una vez que se crea una imagen, nunca se modifica. Un contenedor es, entonces, la instanciación de una imagen, y múltiples instancias conformarán contenedores idénticos con una diferencia: la capa de contenedor, que sí se puede escribir. En ella se almacenan los cambios en tiempo de ejecución, incluidas las escrituras y actualizaciones de datos y archivos.

Existen dos componentes específicos de Docker que los diferencian de los contenedores más tradicionales:

  • Docker Daemon, o Docker Engine, se trata de una capa delgada entre los contenedores y el kernel de Linux. Es el entorno de tiempo de ejecución persistente que administra los contenedores de aplicaciones, y es independiente del sistema operativo subyacente.
  • Dockerfile. Se utilizan para crear imágenes de contenedor. Un Dockerfile es un documento de texto que contiene toda la información de configuración y los comandos necesarios para ensamblar una imagen de contenedor —tarea que realiza el Docker Daemon—.

Sobre estos y otros temas, como la distribución de contenido mediante Docker, hablaremos en otro artículo futuro en el que entraremos en un mayor detalle y profundidad.