Docker

Docker

Alejandro Caraballo

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.

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:

[code]docker pull sonarqube[/code]

Podemos listar las imágenes que tenemos en nuestro equipo con el siguiente comando:

[code]docker images[/code]

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:

[code]docker run -d –name sonarqube -p 9000:9000 sonarqube[/code]

  • -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:

[code]docker ps[/code]

Para acceder al sonar instalado en el contenedor nos bastaría con abrir un al navegador con la URL http://localhost:9000.

[code]docker inspect <containerID>[/code]

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:

[code]docker run -d –name sonarqube2 -p 7000:9000 sonarqube[/code]

[code]docker ps[/code]

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:

[code]docker ps -a[/code]

Para borrar un contenedor deberíamos ejecutar el siguiente comando:

[code]docker rm sonarqube[/code]

[code]docker rm sonarqube2[/code]

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:

[code]docker commit -m "<comentario>" -a "<autor>" <id_contenedor> <nombre_imagen>:<etiqueta_imagen>[/code]

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:

[code]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

[/code]

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:

[code]docker run –name apache1 -d -p 90:80 redeszone/apache[/code]

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.