Docker es una herramienta Open Source que nos permite realizar una virtualización liviana, con la que poder empaquetar entornos y aplicaciones que posteriormente podremos desplegar en cualquier máquina que disponga de la tecnología Docker instalado en su sistema. Para ello, Docker extiende LXC (Linux Containers), que es un sistema de virtualización que permite crear múltiples sistemas totalmente aislados entre sí, sobre la misma máquina o sistema anfitrión.
La principal diferencia entre una máquina virtual y un contenedor de Docker, reside en que la máquina virtual necesita contener todo el sistema operativo, mientras que un contenedor Docker aprovecha el sistema operativo sobre el cual se ejecuta. El contenedor comparte el Kernel del sistema operativo anfitrión, e incluso parte de sus bibliotecas.
Qué es Docker
Docker es una plataforma de software que permite a los desarrolladores crear, distribuir y ejecutar aplicaciones de manera rápida y eficiente en entornos aislados llamados contenedores. Estos contenedores encapsulan todo lo necesario para que una aplicación funcione, incluyendo el código, las bibliotecas, las herramientas y las configuraciones, lo que facilita la portabilidad y la implementación en diferentes entornos de desarrollo y producción.
La principal ventaja de Docker está en su tecnología de contenedores, que ofrece una alternativa ligera y eficiente a las máquinas virtuales tradicionales. Mientras que las máquinas virtuales virtualizan todo el hardware de un servidor y ejecutan múltiples sistemas operativos independientes, los contenedores Docker comparten el mismo núcleo del sistema operativo y solo virtualizan los recursos a nivel de sistema de archivos y procesos. Esto los hace más rápidos, eficientes y portátiles que las máquinas virtuales.
Docker utiliza un formato de contenedor estándar llamado Docker Image, que incluye todo lo necesario para ejecutar una aplicación de manera independiente. Las imágenes Docker se crean a partir de archivos de configuración llamados Dockerfile, que especifican los pasos necesarios para construir la imagen, incluyendo la instalación de dependencias, la configuración del entorno y la ejecución de comandos específicos.
Una vez que se ha creado una imagen Docker, se puede distribuir y compartir a través de un repositorio centralizado llamado Docker Hub, que actúa como un almacén de imágenes Docker públicas y privadas. Los desarrolladores pueden descargar y ejecutar imágenes Docker desde Docker Hub en cualquier entorno compatible con Docker, lo que facilita la implementación rápida y escalable de aplicaciones en la nube.
Además de la distribución de aplicaciones, Docker también facilita la gestión y el orden de contenedores en entornos de producción a través de herramientas como Docker Compose y Docker Swarm. Estas herramientas permiten a los desarrolladores definir y gestionar la infraestructura de contenedores, lo que facilita la escalabilidad, la disponibilidad y la tolerancia a fallos de las aplicaciones distribuidas.
Desde el punto de vista del consumo de procesador y de la memoria RAM, los contenedores hacen un uso mucho más eficiente del sistema anfitrión, con lo que únicamente usarán la memoria y la capacidad de cómputo que estrictamente necesiten. Eso es debido que el contenedor del sistema comparte el Kernel, y parte de las bibliotecas como hemos mencionado anteriormente.
Otras ventajas destacables del uso serían:
- Las instancias se arrancan en pocos segundos.
- Es fácil de automatizar e implantar en entornos de integración continua.
- Existen multitud de imágenes que pueden descargarse y modificarse libremente.
Como inconvenientes podemos destacar:
- Sólo puede usarse de forma nativa en entornos Unix, aunque se puede virtualizar gracias a boot2docker tanto en OSX como en Windows.
- Las imágenes sólo pueden estar basadas en versiones de Linux modernas (kernel 3.8 mínimo).
- Como es relativamente nuevo, puede haber errores de código entre versiones.
Imágenes y Contenedores
Los términos que hay que manejar con Docker son principalmente 2, las imágenes y contenedores. Las imágenes se podrían ver como un componente estático, pues no son más que un sistema operativo base, con un conjunto de aplicaciones empaquetadas. Un contenedor es la instanciación o ejecución de una imagen, pudiendo ejecutar varios contenedores a partir de una misma imagen.
Instalación de Docker
Nos dirigiremos a la página principal Docker y descargaremos la versión correspondiente para nuestro sistema operativo. En mi caso descargaré la versión de MacOS. Tan solo tendremos que arrastrar el icono de Docker a nuestra carpeta de Aplicaciones.
Cuando iniciemos por primera vez Docker, tendremos que poner nuestra clave de inicio al sistema por cuestiones de seguridad.
Una vez cumplimentados los pasos de instalación y abriremos una ventana terminal. En esta ejecutaremos el comando Docker y nos aparecerá la lista de opciones.
Pasos para crear virtualización ligera
Una vez tengamos instalado correctamente Docker vamos a empezar a trastear con él, para ello vamos a Docker Hub, que es un repositorio de imágenes pre-configuradas listas para usar (en otras palabras un GitHub de imágenes). DockerHub dispone de las imágenes oficiales de postgresql, redis, mysql, ubuntu, rabbitmq, sonarqube, mongodb, además de una multitud de imágenes que los usuarios van creando y subiendo al repositorio.
En este ejemplo vamos a usar la imagen oficial de sonarqube, para crear un contenedor con Sonar instalado. En el repositorio de sonarqube encontraremos información relativa a la imagen y de cómo se usa, más o menos lo que vamos a describir a continuación.
El primer paso sería descargarnos la imagen:
docker pull sonarqube
Podemos listar las imágenes que tenemos en nuestro equipo con el siguiente comando:
docker images
Una vez tenemos la imagen, ya estamos en disposición de instanciar un contenedor a partir de ella. Este comando lo que realiza es levantar un contenedor con los siguientes parámetros:
docker run -d --name sonarqube -p 9000:9000 sonarqube
- -d: Levanta el contenedor en segundo plano
- –name: Nombre asociado al contenedor
- -p: Mapeamos el puerto 9000 de nuestro equipo con el 9000 del contenedor
Podemos comprobar los contenedores que están levantados:
docker ps
Para acceder al sonar instalado en el contenedor nos bastaría con abrir un al navegador con la URL http://localhost:9000.
docker inspect <containerID>
Ahora ya podemos acceder a nuestro Sonar, tal y como podéis ver a continuación:
¿Y si necesitamos tener otro Sonar? Pues nada, instanciamos de nuevo la imagen para crear otro contenedor.
Sólo necesitamos cambiar el nombre y el mapeo de puertos, volvemos a comprobar los contenedores activos … y ahí tenemos nuestros dos contenedores:
docker run -d --name sonarqube2 -p 7000:9000 sonarqube
docker ps
Podemos acceder al nuevo sonar:
Podemos parar un contenedor con el comando «docker stop sonarqube», tal y como podéis ver a continuación:
Vemos como sólo quedaría activo sonarqube2, podemos listar los contenedores independientemente de su estado con:
docker ps -a
Para borrar un contenedor deberíamos ejecutar el siguiente comando:
docker rm sonarqube
docker rm sonarqube2
Hay que tener en cuenta que, al borrar un contenedor, perderíamos los cambios que hubiésemos realizado en él. Una de las opciones que tendríamos si queremos que los cambios que realicemos al contenedor sean permanentes, sería la de generar una imagen a partir del contenedor, para ello haríamos lo siguiente:
docker commit -m "<comentario>" -a "<autor>" <id_contenedor> <nombre_imagen>:<etiqueta_imagen>
Dockerfile
En este último apartado vamos a ver cómo crear una nueva imagen a través de un fichero llamado Dockerfile. Un fichero Dockerfile es simplemente un fichero de texto que nos permite definir las instrucciones a seguir para construir una imagen, en otras palabras, es como una receta para crear nuestras imágenes, que servirán de forma posterior para correr nuestros contenedores.
En este ejemplo vamos a crear una imagen con un SO Ubuntu y le vamos a instalar el servidor web Apache, para ello contamos con un Dockerfile:
FROM ubuntu
MAINTAINER Redes Zone
ENV http_proxy http://user:pass@proxy/
ENV https_proxy http://user:pass@proxy/
RUN apt-get update
RUN apt-get install apache2 -y
RUN echo "<h1>Apache with Docker</h1>" > /var/www/html/index.html
EXPOSE 80
ENTRYPOINT apache2ctl -D FOREGROUND
Vamos a describir los comandos del Dockerfile:
- FROM : Indica la imagen que tomamos como base, en este caso la imagen oficial de Ubuntu
- MAINTAINER: Especifica el autor de la imagen.
- ENV: Definimos unas variables de entorno en la imagen base.
- http_proxy http://user:pass@proxy/ — Definimos la variable http_proxy
- https_proxy http://user:pass@proxy/ — Definimos la variable https_proxy
- RUN: Ejecuta una sentencia sobre la imagen base
- apt-get update : actualiza los repositorios de Ubuntu
- apt-get install apache2 -y : Instala el apache
- echo “<h1>Apache with Docker</h1>” > /var/www/html/index.html : crea un fichero index.html
- EXPOSE: Exponemos el puerto 80 del contenedor para que pueda ser mapeado por la máquina anfitrión.
- ENTRYPOINT: Indicamos que se ejecute apache2ctl -D FOREGROUND cada vez que arranquemos el contenedor.
Una vez tengamos definido el fichero Dockerfile, vamos a construir la imagen:
docker build –t redeszone/apache
Le estamos indicando a docker que construya una imagen con el nombre redeszone/apache a partir del DockerFile que se encuentra en la misma ruta donde ejecutamos el comando.
Listamos las imágenes disponibles:
Ya estamos en disposición de arrancar un contenedor a partir de la imagen que hemos creado:
docker run --name apache1 -d -p 90:80 redeszone/apache
Arrancamos un contenedor, que llamaremos apache1, mapeando el puerto 80 del contenedor con el 90 de nuestra máquina, a partir de la imagen redeszone/apache.
Hasta aquí hemos llegado con este manual de Docker, tal y como habéis visto, en un principio puede parecer algo complicado, pero una vez que sabemos lo esencial, virtualizar contenedores es realmente fácil, rápido y muy eficiente.