En este post aprenderemos a utilizar la tecnología Docker, la cual nos permite automatizar el despliegue de aplicaciones dentro de contenedores de software o imagen, proporcionando una capa adicional de abstracción y automatización de virtualización de aplicaciones en múltiples sistemas operativos.

Esta tecnología, aplicada a nuestro entorno, nos permitirá desplegar diferentes aplicaciones sin la necesidad de tener que instalar las dependencias necesarias en nuestra máquina, ejecutándose en un entorno virtual y paralelo al sistema operativo. Además, podremos acceder a las diferentes herramientas desde cualquier navegador web de manera remota, haciendo su uso muy accesible.

Por último, Docker hará uso de la herramienta web Portainer, la cual nos permitirá, gestionar los diferentes contenedores de imágenes alojados en nuestro sistema (creación, edición, borrado...).

Concepto de contenedores simples y múltiples

La idea básica de Docker es la creación de un entorno virtual en el que se ejecuten diferentes aplicaciones cuyas dependencias hayan sido previamente descargadas. Y además, que esta virtualización se consiga en cualquier tipo de sistema operativo con solo tener la herramienta Docker instalada. Para ello necesitamos:

  • Obtener dichas dependencias. Esto se consigue gracias a un fichero de texto llamado Dockerfile. En él se alojarán los diferentes comandos y acciones del usuario que permitan la instalación y reubicación de las diferentes dependencias necesarias para construir una imagen completamente funcional.
  • Creación de la imagen. Gracias al fichero Dockerfile, podemos "armar" una imagen con el comando docker build.
  • Creación de nuestro contenedor. O lo que es lo mismo, despliegue de nuestra imagen. Esto se consigue con el comando docker run.

Y ahora es cuando surge la siguientes dudas:

  • ¿Y si queremos desplegar más de una herramienta a la vez? ¿Se podría utilizar un único Dockerfile?
  • ¿Y si queremos que nuestras herramientas tengan un despliegue paralelo? ¿Podemos parar la ejecución de una sin que la otra se interrumpa?

La respuesta a la primera pregunta es SÍ, pero con pequeños matices. El despliegue de diferentes herramientas en una misma imagen mediante un único Dockerfile, es útil cuando ese conglomerado de aplicaciones trabajan juntas. Un ejemplo sería el Stack ELK (Elasticsearch, Logstash y Kibana), donde tenemos un conjunto de herramientas que permiten realizar diferentes dashboards (Kibana), gracias al uso de los índices alojados en una base de datos (Elasticsearch), cuyos datos son extraídos desde múltiples fuentes (como puede ser Logstash).

Por lo tanto, si nuestro conjunto de herramientas no se comportan como "parte de un todo", podemos desplegarlas de forma paralela. Esa es la idea principal de los contenedores múltiples, y la respuesta a la segunda pregunta formulada.

En Docker, cuando hablamos de multicontendores locales (un mismo host) nos referimos al uso de la herramienta Docker Compose (vs uso de multicontenedores en distitnos hosts con Docker Swarm). En nuestro caso, al trabajar sobre un entorno local, utilizaremos la primera herramienta. Esta nos permite desplegar diferentes contenedores a modo de stacks, tal y como veremos más adelante.

Instalación de Docker y Portainer en OMV

Para descargar todas las dependencias necesarias de ambas herramientas, es necesario seguir los siguientes pasos:

  1. Nos dirigimos a Servicios -> OMV-Extras -> Pestaña Docker
  2. Más abajo, en la pestaña Docker, seleccionamos Instalar. Saltará una ventana con el proceso, puede demorarse un tiempo. Al finalizar el proceso pulsamos OK. Una vez finalizado, en el cuadro de abajo nos indica: donde se instalarán las diferentes dependencias, las futuras imágenes y la versión y estado actual de la herramienta.
  3. Justo al lado de la pestaña anterior, aparece Portainer. De nuevo pulsamos sobre Instalar. El proceso puede llevar un tiempo también. Al finalizar, es conveniente que reiniciemos nuestro sistema.

Familiarización con la interfaz web de Portainer

Una vez realizados los pasos anteriores, podremos acceder a la GUI de Portainer dirigiéndonos al puerto habilitado para ella, es decir:

Navegador web -> RASPBERRY_IP:9000

La primera vez que entremos, nos aparecerá una página de Login similar a la de la figura mostrada, donde tendremos que crear un nuevo usuario y contraseña. Una vez hecho, nos aparacerá una nueva ventana, donde nos aparecerá una lista con los diferentes entornos que Portainer puede gestionar (un único host local vs diferentes hosts). En nuestro caso, al trabajar con contenedores locales, elegimos la primera opción.

Una vez realizado lo anterior, accederemos a la página principal o Home de Portainer. Aquí tenemos múltiples opciones disponibles en el panel lateral: gestión de extensiones para la herramienta, creación/manipulación de usuarios/grupos y sus permisos, opciones generales de la aplicación, etc. Y en el panel central tenemos un resumen de nuestro despliegue: endpoint (en este caso local), nº de contenedores e imágenes, estado de los mismos...

Si pulsamos sobre el cuadro central, pasaremos a la ventana de gestión de nuestras imágenes y contenedores locales. Aqui tenemos un listado con diferentes opciones:

  • Dashboard: podemos observar un resumen del estado actual de nuestra herramienta.
  • App Templates: utilización de diferentes plantillas imágenes de Docker Hub muy conocidas (MySQL, Nginx, Jenkins, Wordpress...).
  • Images: creación, manipulación y eliminación de las diferentes imágenes descargadas de Docker Hub.
  • Containers: desde aquí podemos manipular los diferentes contenedores disponibles: iniciarlos, pararlos, matarlos, observar sus logs, ip-puerto/s utilizado/s, estado actual, etc.
  • Stack: quizá el apartado más interesante. Desde aquí podemos crear diferentes stacks o grupos de contenedores desplegados de manera simultánea, tal y como veremos más adelante.
  • ...

Desplegando nuestro primer contenedor Docker

Para crear nuestro primer contenedor, debemos hacer uso de Docker Hub, la mayor librería de contenedores de imágenes del mundo. Desde ella descargaremos cada imagen, para después desplegarla en nuestra RPi.

Requisitos y parámetros previos al despliegue

La gran mayoría de imágenes necesitan de diferentes parámetros del usuario para poder enlazar nuestra RPi con Portainer. Suelen ser tres: PUID, PGID y volúmenes:

  • PUID y PGID: se corresponden al UID y GID del sistema Linux de nuestra RPi. Permite a los contenedores mapear al usuario y grupos internos de nuestra máquina. Para obtenerlos basta con conectarnos remótamente a nuestra RPi (con Putty, por ejemplo), y escribir en el terminal id admin.

  • Volúmen: esta es la ruta absoluta o path de nuestro HDD. Son necesarias para las imágenes, ya que indican donde ubicar, por ejemplo: sus archivos de configuración, descargas, etc. Para obtener la ruta, nos dirigimos al panel de OMV (192.168.1.X en nuestro navegador), y en la sección Permiso de Acceso -> Carpetas Compartidas, realizamos lo siguiente:

    • Para observar la ruta absoluta, hacemos click en una de las columnas, en el desplegable pulsamos sobre Columns -> Absolute Path.
    • Para obtener la ruta en texto, hacemos click derecho en la ruta deseada, le damos a Inspeccionar, y en el DOM que nos aparece, seleccionamos y copiamos la ruta (que será tipo /srv/disk-by-label...).

Creación de stacks y despliegue del contenedor

Para obtener la imagen de Docker Hub, debemos dirigirnos a la sección Stacks, desde menú de gestión de contenedores. Una vez aquí, debemos hacer click sobre Add Stack, y nos aparecerá una ventana para configurar la imagen deseada. Desde aquí, debemos seguir los siguientes pasos:

  1. Dar un nombre intuitivo a nuestro stack (elasticsearch, grafana, ubuntu, apache...).
  2. Seleccionando Web Editor, debemos introducir un fichero de texto tipo Docker Compose. Para ello, existen diferentes plantillas, como las proporcionadas por el perfil de Linux Server en Docker Hub. Para este ejemplo, usaremos la imagen del famoso cliente P2P qBitTorrent.
  3. Una vez tenemos la plantilla en nuestro editor, debemos configurarla a nuestro caso concreto. El ejemplo con qBitTorrent se muestra en la figura inferior.
  4. Al finalizar, pulsamos sobre el botón Deploy Container. Este proceso puede demorarse bastante, ya que Portainer tiene que descargar la imagen y desplegar el contenedor (todo depende del peso de la imagen).

Mantenimiento de los contenedores

Una vez que se despliega cada contenedor, podremos observar su estado desde la sección Containers. Si ha habido algún error al desplegar, quedará registrado en los logs del contenedor (icono tipo documento en la columna Quick actions). También podemos, desde la misma columna:

  • Observar el consumo de recursos del contenedor (CPU y RAM).
  • Obtener acceso a su interior con una intuitiva consola (gracias a docker exec).
  • ...