Tutorial de Docker: instalar y gestionar la plataforma de contenedores

Con el eslogan “Build, Ship and Run Any App, Anywhere” la plataforma de contenedores de código abierto Docker define su función principal: desarrollar, enviar y ejecutar cualquier aplicación en cualquier sistema, constituyéndose así como una alternativa flexible y capaz de ahorrar recursos frente a la emulación de componentes de hardware basada en máquinas virtuales (VM). Las diferencias entre ambas técnicas de virtualización se desgranan en este tutorial de Docker destinado a todos aquellos que toman contacto por primera vez con la plataforma, al tiempo que se presenta el proyecto en un sencillo manual con instrucciones paso a paso.

Mientras que la virtualización tradicional de hardware se basa en iniciar diferentes sistemas invitados en un mismo sistema anfitrión (host), con Docker las aplicaciones se ejecutan como procesos aislados dentro de un mismo sistema gracias a los denominados contenedores. Se habla entonces de una virtualización basada en contenedores y, por consiguiente, también de una virtualización a nivel de sistema operativo.

En el gráfico se pueden ver las diferencias principales en la arquitectura de ambas técnicas de virtualización:

Aunque ambas tecnologías permiten a los administradores de sistemas y desarrolladores instalar diferentes aplicaciones con distintos requisitos en paralelo en un mismo sistema físico, sus diferencias más notables se basan en el empleo de los recursos y la portabilidad.

Contenedores: virtualización con un overhead mínimo

Para poder encapsular las aplicaciones con un hardware de virtualización clásico es necesario un elemento conocido como hipervisor, que funciona como una capa de abstracción entre el sistema anfitrión y los sistemas huéspedes virtuales. Cada sistema invitado emula a una máquina completa con un kernel de sistema operativo separado, al que el hipervisor asigna los componentes de hardware del host (CPU, memoria, espacio en disco duro y periféricos disponibles) de forma proporcional.

Por el contrario, en la virtualización basada en contenedores no se crea un sistema huésped completo, sino que las aplicaciones se inician en contenedores que, aun compartiendo el mismo kernel, es decir, el del sistema anfitrión, se ejecutan como procesos aislados en el espacio de usuario.

Consejo

Por regla general, los sistemas operativos actuales dividen las memorias virtuales en dos campos separados para proteger al sistema operativo de aplicaciones dañinas o con fallos. Por un lado, presentan el espacio de memoria del kernel, reservado para el funcionamiento del kernel y otros componentes base del sistema operativo y, por el otro, el espacio de memoria del usuario, disponible para las aplicaciones. Esta estricta separación entre el espacio del núcleo y del usuario tiene como objetivo primordial proteger el sistema de aplicaciones dañinas o defectuosas.

La gran ventaja de la virtualización basada en contenedores reside en que las aplicaciones con diferentes requisitos pueden ejecutarse aisladas unas de otras sin que por ello haya que asumir la sobrecarga de un sistema huésped separado. Para ello, la tecnología de contenedores aprovecha dos funciones básicas del kernel de Linux: los grupos de control (Cgroups) y los espacios de nombres Kernel.

  • Los Cgroups limitan el acceso de procesos a la memoria, la CPU y los recursos I/O de manera que evitan que las necesidades en cuanto a recursos de un proyecto concreto afecten a otros procesos en ejecución.
  • Los Namespaces (espacios de nombres) limitan los procesos y sus procesos hijo a una sección específica del sistema subyacente y son usados por Docker para encapsular proyectos en cinco campos concretos:
    • Identificación de sistemas (UTS): los espacios de nombres UTS se usan en la virtualización basada en contenedores para asignar a los contenedores su propio nombre de dominio y de equipo.
    • ID de proceso (PID): cada contenedor Docker usa un espacio de nombres independiente para los identificadores (ID) de proceso. Todos aquellos procesos que tengan lugar fuera del contenedor no se visualizan desde el interior de este, lo que permite que los procesos encapsulados en contenedores dentro de un mismo sistema host posean el mismo PID sin que ello cause problema alguno.
    • Comunicaciones entre procesos (IPC): los espacios de nombres IPC aíslan procesos en un contenedor, impidiendo la comunicación con procesos fuera del contenedor.
    • Recursos de red (NET): los espacios de nombres network permiten adjudicar a cada contenedor recursos de red separados, como direcciones IP o tablas de enrutamiento.
    • Puntos de montaje de los sistemas de ficheros (MNT): gracias a estos sistemas de nombres, un proceso aislado no ve nunca el sistema de ficheros del host completo, sino que accede solo a una pequeña parte de este, en general una imagen creada concretamente para este contenedor.

Aunque hasta la versión 0.8.1 el proceso de aislamiento de Docker se basaba en los contenedores de Linux (LXC), la versión 0.9 ofrece un formato de contenedor desarrollado por el mismo Docker conocido como Libcontainer. Este permite el uso multiplataforma de Docker, así como la ejecución de un mismo contenedor en diferentes sistemas anfitriones. Además, ofrece una versión de Docker para macOS y Windows.

Escalabilidad, alta disponibilidad y portabilidad

La tecnología de contenedores no solo se presenta como una alternativa para ahorrar recursos frente a la virtualización de hardware tradicional, sino que permite también instalar aplicaciones multiplataforma y en diferentes infraestructuras sin necesidad de adaptarlos a la configuración específica de los sistemas de hardware y software de cada sistema host.

Docker utiliza las denominadas imágenes como copias portables del software de contenedores. Estas contienen las aplicaciones junto con todas las bibliotecas, los archivos binarios y de configuración necesarios durante la ejecución de los procesos de aplicación encapsulados. Por este motivo apenas requieren nada del sistema anfitrión, lo que facilita el traspaso de un contenedor-aplicación entre diferentes sistemas operativos Linux, Windows o macOS sin necesidad de ajustes, siempre y cuando la plataforma de Docker se haya instalado como una capa de abstracción. Por todo ello, Docker se convierte en el programa perfecto para llevar acabo arquitecturas de software escalables y de alta disponibilidad. Empresas como Spotify, Google, eBay o Zalando usan Docker como sistema productivo.

Docker: estructuras y funciones

Docker es el proyecto de software más conocido de todos los que facilitan una tecnología de virtualización basada en contenedores. Esta plataforma de código abierto está constituida por tres componentes principales, estos son, el motor de Docker, las imágenes Docker y el Docker Hub. Ejecutar un contenedor es posible gracias al motor Docker (Docker engine) y a las imágenes Docker, que bien pueden ser creadas por el usuario u obtenerse en el repositorio Docker Hub.

Imágenes Docker

De forma muy similar a las máquinas virtuales, los contenedores de Docker se basan en imágenes, que son plantillas de solo lectura con todas las instrucciones que necesita el motor de Docker para crear un contenedor. Como copia portátil de un contenedor, una imagen Docker se describe en forma de archivo de texto (Dockerfile). Antes de iniciar un contenedor en un sistema, se carga un paquete con la imagen correspondiente si esta no está ya guardada de forma local. La imagen cargada prepara todos los sistemas de archivos con los parámetros necesarios para la ejecución. Un contenedor puede considerarse como un proceso en ejecución de una imagen.

Docker Hub

El Docker Hub es un registro para repositorios de software basado en la nube, es decir, una especie de biblioteca para las imágenes Docker. Este servicio online está formado por repositorios públicos y privados. En los primeros se ofrece a los usuarios la posibilidad de subir sus propias imágenes y compartirlas con la comunidad. Aquí se dispone de un gran número de imágenes Docker oficiales realizadas por el equipo de desarrolladores de la plataforma así como de proyectos de código abierto consolidados. Por el contrario, en los repositorios privados del registro no todo el mundo tiene acceso a las imágenes que se cargan, aunque estas sí pueden ser compartidas dentro de una misma empresa o en un determinado círculo. Al repositorio de Docker Hub se accede a través de hub.docker.com.

Motor de Docker

El corazón de cualquier proyecto Docker es el motor de Docker, esto es, una aplicación cliente-servidor de código abierto disponible para todos los usuarios en la versión actual en todas las plataformas establecidas.

Los componentes que conforman la arquitectura básica de este motor son: un daemon con funciones de servidor, una interfaz de programación (API) basada en REST (Representational State Transfer) y la terminal del sistema operativo (Command-Line Interface, CLI) como interfaz de usuario (client).

  • Daemon de Docker: en el motor de Docker se utiliza un proceso daemon como servidor que funciona en un segundo plano del sistema host y permite el control central del motor de Docker. Además se encarga de crear y administrar todas las imágenes, contenedores o redes.
  • La API REST: especifica una serie de interfaces que permite a otros programas interactuar con el daemon y darle instrucciones. Uno de estos programas es la terminal del sistema operativo.
  • La terminal: Docker utiliza la terminal del sistema operativo como programa cliente, el cual interacciona con el daemon a través de la API REST y permite a los usuarios controlarlo a través de scripts o comandos.

Docker permite ejecutar, parar o gestionar los contenedores de software directamente desde la terminal. Con el comando docker e instrucciones como build (crear), pull (descargar) o run (ejecutar) es posible comunicarse con el daemon, lo que posibilita que tanto cliente como servidor se encuentren en el mismo sistema. Además, es posible dirigirse al daemon en otro sistema diferente. En función del tipo de conexión que se deba establecer, la comunicación entre cliente y servidor se produce bien a través de la API REST, de sockets de UNIX o de una interfaz de red.

En la siguiente imagen se puede ver la forma en que los componentes individuales de Docker se combinan tomando como ejemplo los comandos docker build, docker pull y docker run:

El comando docker build da instrucciones al daemon para crear una imagen (línea punteada), para lo cual debe estar disponible el Dockerfile correspondiente. Si el usuario no ha creado la imagen, sino que la toma de un repositorio en Docker Hub, entonces se ejecuta el comando docker pull (línea discontinua). Cuando se le ordena al daemon iniciar un contenedor con la orden docker run, el programa comprueba primero si la imagen requerida está almacenada de forma local. En caso afirmativo, el contenedor se inicia (línea continua). También puede ocurrir que el daemon no encuentre la imagen, a partir de lo cual extrae una directamente del repositorio.

Instalar el motor de Docker

Aunque en un principio Docker solo se usaba en las distribuciones de Linux, la versión actual del motor de contenedores se caracteriza por una gran independencia de plataforma. Hoy existen paquetes de instalación para Microsoft Windows y macOS, así como para servicios en la nube como Amazon Web Services (AWS)‎ y Microsoft Azur. Entre las distribuciones de Linux que soporta encontramos:

  • CentOS
  • Debian
  • Fedora
  • Oracle Linux
  • Red Hat Enterprise Linux
  • Ubuntu
  • openSUSE
  • SUSE Linux Enterprise

Además hay distribuciones de Docker gestionadas por la comunidad para:

  • Arch Linux
  • CRUX Linux
  • Gentoo Linux

A continuación se muestra el proceso de instalación de un motor de Docker con Ubuntu, la popular distribución de Linux. Para conocer cómo instalar Docker en otras plataformas, accede a estas instrucciones de documentación de Docker en inglés.

Dependiendo de las exigencias y requisitos que se deben cumplir, puedes instalar Docker en el sistema Ubuntu de tres formas diferentes:

  • Manualmente con el paquete DEB
  • Desde el repositorio de Docker
  • Desde el repositorio de Ubuntu

Sin embargo, antes deberías de echar un vistazo a los requisitos del sistema del motor de Docker.

Requerimientos de sistema

Para instalar la versión actual de Docker en la distribución de Ubuntu es necesaria la versión de 64 bits de una de las siguientes versiones de Ubuntu:

  • Yakkety 16.10
  • Xenial 16.04 (LTS)
  • Trusty 14.04 (LTS)
Nota

En sistemas productivos se recomienda la instalación de productos de software con soporte a largo plazo (Long Term Support, LTS), pues de esta forma seguirán recibiendo actualizaciones aunque salgan nuevas versiones al mercado.

Pasos previos para instalar Docker

En el siguiente tutorial de Docker se usa la versión Ubuntu Xenial 16.04 (LTS), aunque se pueden seguir los mismos pasos con Yakkety 16.10. Se recomienda a los usuarios de Trusty 14.04 (LTS) que antes de proceder a instalar Docker instalen los paquetes linux-image-extra-*, ya que estos permiten que el motor de Docker tenga acceso al driver de almacenamiento AUFS.

El paquete integrado Manager APT (Advanced Packaging Tool) ofrece un método sencillo para proveer al sistema Linux con actualizaciones. Para instalar el paquete adicional para Trusty 14.04 hay que seguir los siguientes pasos:

  1. LLamar a la terminal: inicia Ubuntu y abre la terminal, por ejemplo, con la combinación de teclas [STRG] + [ALT] + [T].
  1. Actualizar listas de paquetes: utiliza el siguiente comando para actualizar el índice local de paquetes de tu sistema operativo y confirma con [ENTER].
$ sudo apt-get update
Nota

El comando apt-get update no instala ningún paquete nuevo, sino que actualiza las descripciones de paquete disponibles de manera local.

Al añadir sudo puedes ejecutar comandos como administrador (superusuario “root”o raíz). Puede ocurrir que Ubuntu requiera derechos admin (root) para introducir comandos específicos, en cuyo caso pedirá la contraseña de administrador. Puedes cambiar de forma permanente a la función de administrador con el comando sudo –s.

Nota

Para instalar la plataforma de contenedores Docker necesitas los derechos admin (root) del sistema host correspondiente

Una vez que te has identificado como usuario raíz con tu contraseña, Ubuntu comienza con el proceso de actualización, mostrando su estado en la terminal.

  1. Instalar paquetes adicionales: tras actualizar todas las descripciones de paquetes, puedes pasar a la instalación de nuevos paquetes. El administrador de paquetes APT facilita para ello el comando apt-get install "nombre de paquete". Para añadir los paquetes adicionales recomendados para Trusty 14.04 del repositorio Ubuntu e instalarlos en el sistema, escribe en la terminal el siguiente comando y confirma con [ENTER]:
$ sudo apt-get install -y --no-install-recommends \
    linux-image-extra-$(uname -r) \
    linux-image-extra-virtual
Nota

Al usar comandos con la opción -y todas las preguntas interactivas se contestan automáticamente con “Sí”. La opción --no-install-recommends impide que Ubuntu instale de forma automática los paquetes recomendados.

Una vez que hayas descargado los paquetes adicionales para Trusty 14.04, todas las funciones de la plataforma de Docker están a tu disposición también para esta versión de Ubuntu.

¿No sabes que versión de Ubuntu está manejando tu sistema?, ¿no estás seguro de si dispones de la estructura en 64 bits necesaria para instalar Docker? Puedes conocer tanto la versión del kernel como la arquitectura de tu sistema en la terminal de Ubuntu con el comando:

$ sudo uname -rm 

La versión de Ubuntu, la edición y los apodos se obtienen con el comando:

$ sudo lsb_release –a

Instalación de Docker manual con un paquete DEB

En principio, Docker se puede descargar como un paquete DEB para proseguir con su instalación manual. El paquete de instalación necesario está disponible en:

apt.dockerproject.org/repo/pool/main/d/docker-engine/ [Descargar Docker como paquete DEB]

Descarga los archivos DEB de la versión de Ubuntu que se desea, tras lo que puedes iniciar el proceso de instalación en la terminal con el comando:

$ sudo dpkg -i /path/to/package.deb 
Nota

Adapta el marcador /path/to/ para que la ruta de archivos remita al lugar de almacenamiento del paquete DEB.

Si realizas la instalación manual, todas las actualizaciones de software se deben llevar a cabo también de esta manera. Es por esto que en la documentación de Docker se aconseja proceder a instalar Docker a través del propio repositorio de la plataforma de contenedores, pues permite realizar la instalación sin mayor complicación desde la terminal de Ubuntu y mantenerla actualizada.

A continuación aclaramos cómo instalar Docker según los procedimientos recomendados.

Instalación desde el repositorio de Docker

Como ya se ha dicho, la forma recomendada para instalar tu plataforma de contendedores es a través del repositorio de Docker. A continuación puedes ver cómo configurar el sistema para que el administrador de paquetes APT tenga acceso al repositorio de Docker a través de HTTPS.

  1. Instalar el paquete: al introducir el comando que aparece a continuación se procede a la instalación de los paquetes necesarios para acceder al repositorio de Docker:
$ sudo apt-get install -y --no-install-recommends \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
  1. Añadir una llave GPG: inserta las llaves GPG oficiales de Docker.
$ curl -fsSL https://apt.dockerproject.org/gpg | sudo apt-key add -
  1. Verificación de la llave GPG: comprueba que la llave GPG coincide con la siguiente identificación 5811 8E89 F3A9 1289 7C07 0ADB F762 2157 2C52 609D. Para ello usa el comando:
$ apt-key fingerprint 58118E89F3A912897C070ADBF76221572C52609D

En la terminal se muestra la salida:

pub   4096R/2C52609D 2015-07-14
        Key fingerprint = 5811 8E89 F3A9 1289 7C07  0ADB F762 2157 2C52 609D
uid                  Docker Release Tool (releasedocker) <docker@docker.com>
  1. Configurar el repositorio Docker: inserta el siguiente comando para garantizar el acceso al repositorio estable de Docker:
$ sudo add-apt-repository \
       "deb https://apt.dockerproject.org/repo/ \
       ubuntu-$(lsb_release -cs) \
       main"

Solo ahora se encuentra el sistema convenientemente configurado y preparado para la instalación de la plataforma de contenedores desde el repositorio de Docker.

Nota

Además de los repositorios estables, también puedes utilizar los repositorios de prueba de Docker. Para ello llama al archivo /etc/apt/sources.list y sustituye la palabra main por testing. No obstante, no se recomienda su uso para sistemas productivos.

  1. Actualizar el índice de paquetes: antes de proceder con la instalación del motor de Docker se recomienda actualizar el índice de paquetes del sistema operativo de nuevo, para lo cual se vuelve a introducir el comando:
$ sudo apt-get update
  1. Instalar Docker desde el repositorio: existen dos opciones para cargar el motor de Docker desde el repositorio de Docker e instalarlo en el sistema Ubuntu. Si quieres instalar la última versión del motor de Docker utiliza el comando:
$ sudo apt-get -y install docker-engine

La plataforma de contenedores se puede empezar a usar tan pronto como finalice la instalación. El daemon se inicia automáticamente. Si en el momento de instalar Docker había en tu sistema una versión anterior de la plataforma de contenedores, esta se sustituye por el software recién instalado.

Frente a la última versión del motor de Docker se puede optar por instalar una versión anterior, especialmente si estamos tratando con un sistema productivo, ya que en estos casos los usuarios prefieren utilizar versiones ya consolidadas que han sido probadas con éxito antes que versiones nuevas.

Puedes acceder a un listado general de las versiones disponibles de Docker para tu sistema con el comando:

$ apt-cache madison docker-engine

Para instalar una versión concreta de Docker solo hay que completar el comando de instalación con el número de versión correspondiente (por ejemplo 1.12.5-0), que se añade al nombre del paquete (en este caso docker-engine) separado por el símbolo de igualdad (=).

$ sudo apt-get -y install docker-engine=<VERSION_STRING>

Instalación desde el repositorio de Ubuntu

Los usuarios que no quieran recurrir al repositorio de Docker pueden cargar la plataforma de contenedores desde el propio repositorio del sistema operativo.

Utilice el siguiente comando para instalar uno de los paquetes de Docker ofrecidos por la comunidad Ubuntu:

$ sudo apt-get install -y docker.io
Nota

No se debe confundir el paquete de instalación de la plataforma de contenedores   “docker.io” con el paquete “docker”, una bandeja de sistema para aplicaciones Docklet KDE3/GNOME2

Pruebas

Una vez finalizado el proceso de instalación con éxito, debes comprobar que la plataforma de contenedores funciona a la perfección, para lo cual el equipo de desarrolladores pone a disposición del usuario un sencillo contenedor hello-world. Comprueba entonces que has instalado Docker correctamente introduciendo el siguiente comando en la terminal y confirmando con [ENTER]:

$ sudo docker run hello-world 
Nota

El Docker daemon está conectado con un socket de dominio UNIX, esto es, un punto de comunicación (endpoint) proporcionado por el sistema operativo, asignado por defecto al superusuario en la instalación estándar. Para que otros usuarios puedan usar los comandos Docker necesitan la aplicación sudo. No obstante, esta situación puede cambiarse creando un grupo UNIX con el nombre de docker y añadiéndole los usuarios que desees. Para más información accede a la documentación de proyectos de Docker.

El comando docker run le ordena al daemon de Docker que busque e inicie un contenedor con el nombre hello-world. Si Docker se ha instalado correctamente, deberías recibir una salida como la que se muestra en la imagen siguiente:

La salida de la imagen se interpreta de la siguiente forma: para ejecutar el comando docker run hello-world, el daemon busca primero la imagen del contenedor correspondiente en los archivos locales del sistema. Al ser la primera vez que se ejecuta el contenedor hello-world, la búsqueda no obtiene resultados y se muestra el mensaje “Unable to find image” (“la imagen no se ha podido encontrar”)

$ sudo docker run hello-world
[sudo] password for osboxes:
Unable to find image 'hello-world:latest' locally

En caso de que Docker no encuentre la imagen buscada en el sistema local, el daemon inicia un proceso de descarga (pulling) desde el repositorio de Docker.

latest: Pulling from library/hello-world
78445dd45222: Pull complete
Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
Status: Downloaded newer image for hello-world:latest

Tras descargar la imagen con éxito y recibir el mensaje “Downloaded newer image for hello-world:latest” (“se ha descargado la imagen hello-world:latest más reciente”) se inicia el contenedor, que incluye un script hello-world sencillo con el siguiente mensaje de los desarrolladores:

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://cloud.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

En resumen, lo que este texto dice es que Docker funciona correctamente.

Desinstalar Docker

Igual de fácil que instalarla es desinstalar la plataforma de contenedores a través de la terminal. Si quieres eliminar el paquete de Docker del sistema, introduce el siguiente comando en la terminal de Ubuntu y confirma con [ENTER]:

 $ sudo apt-get purge docker-engine

Una vez el sistema ha leído la información necesaria para la desinstalación, debes confirmar el comando de nuevo.

Si quieres continuar, escribe “Y” (yes) y confirma con [ENTER]. Si, por el contrario, deseas interrumpir este proceso introduce “n”.

No obstante, las imágenes y los contenedores no se borran directamente, sino que hay que eliminarlos con el comando:

$ sudo rm -rf /var/lib/docker

Además, también debes eliminar de forma manual todos aquellos archivos de configuración adicionales que hayas instalado.

Trabajar con Docker

¿Te has asegurado de haber instalado el motor de Docker correctamente y que este funciona a la perfección? Entonces ya podemos pasar a explicar las opciones de aplicación de esta plataforma de contenedores. A continuación, aprenderás a manejar el motor de Docker desde la consola, conocerás las posibilidades que ofrece Docker Hub y comprenderás las razones que convierten a estos contendores en una revolución dentro de la gestión de aplicaciones.

Cómo dirigir el motor de Docker

A partir de la versión 16.04, Ubuntu utiliza el programa systemd (abreviatura de “sistema daemon”) para dirigir procesos. Por systemd entendemos un proceso init que también puede usarse con otras distribuciones de Linux como RHEL, CentOS o Fedora y que, por regla general, recibe el ID de proceso 1. Como primer proceso del sistema, el daemon es responsable de iniciar, parar y efectuar el seguimiento del resto de procesos. En versiones previas de Ubuntu (14.10 y anteriores) es el programa upstart el encargado de esta función.

También se puede controlar al Docker daemon a través de systemd. En la instalación estándar, la plataforma de contenedores está configurada de tal forma que el daemon se inicia automáticamente cuando el sistema arranca. No obstante, este ajuste predeterminado puede modificarse gracias a la herramienta de líneas de comando systemctl.

Con el objetivo de controlar un proceso o conocer su estado, puedes mandar órdenes a systemd con systemctl. La sintaxis de un comando tal presenta la siguiente sintaxis:

Systemctl [OPTION] [COMMAND]

Algunos comandos hacen referencia a determinados recursos (como Docker). La terminología de systemd se refiere a ellos como units (unidades). En este caso, el comando deriva de las instrucciones correspondientes y del nombre de la unidad a la que se dirige. 

Si deseas activar (enable) o desactivar (disable) el inicio automático del Docker daemon, debes utilizar la herramienta systemctl con las siguientes órdenes:

$ sudo systemctl enable docker
$ sudo systemctl disable docker

Esta misma herramienta también permite consultar el estado de una unit:

$ sudo systemctl status docker

Si el motor de Docker está activo en el sistema Ubuntu, la salida en la terminal debería ser así:

Si el motor de Docker se encuentra desactivado en este momento, te aparecerá el estado como inactivo (dead) por lo que será necesario iniciar de forma manual el Docker daemon para ejecutar los contenedores.

En caso de que quieras iniciar, parar o reiniciar el motor de Docker de forma manual, dirígete a systemd con uno de los siguientes comandos.

Para iniciar el daemon desactivado utiliza systemctl junto con el comando start:

$ sudo systemctl start docker

Si lo que deseas es parar el daemon de Docker, entonces deberás usar el comando stop:

$ sudo systemctl stop docker

Para reiniciar el motor se usa restart:

$ sudo systemctl restart docker

Cómo usar Docker Hub

Si el motor de Docker representa el corazón de la plataforma de contenedores, Docker Hub constituye el alma del proyecto de código abierto, ya que es aquí donde se reúne la comunidad. Los usuarios encuentran en el registro basado en la nube todo lo que necesitan para dar vida a la instalación de Docker.

El servicio online ofrece diversos repositorios oficiales con más de 10.000 aplicaciones gratuitas. También los usuarios tienen la posibilidad de crear sus propios archivos de imágenes y compartirlos con grupos de trabajo. Además del soporte profesional que ofrece el equipo de desarrolladores, también es posible conectarse aquí con la comunidad de usuarios. En GitHub, los usuarios pueden acceder también a un foro de soporte.

Registrarse en Docker Hub

Registrarse en Docker Hub es gratis. Para ello los usuarios solamente necesitan una dirección de correo y un ID Docker propio que servirá más tarde como espacio de nombre personal para el repositorio y permitirá a los usuarios tener acceso a todos los servicios de Docker. La oferta incluye por ahora, junto a Docker Hub, a la Docker Cloud, la Docker Store y algunos programas Beta. Además, con el ID de Docker tienes acceso al centro de asistencia de Docker, así como al Docker Success Portal y a los foros de Docker.

Puedes registrarte en cinco pasos:

  1. Elige un ID Docker: en el registro debes elegir un nombre de usuario que más tarde va a convertirse en tu ID. El nombre de usuario para Docker Hub y el resto de servicios de Docker debe constar de entre 4 y 30 caracteres y contener únicamente cifras y minúsculas.
  2. Escribe la dirección de correo: introduce una dirección de correo electrónico activa, ya que servirá para confirmar la inscripción en Docker Hub.
  3. Elige una contraseña: elige una contraseña de entre 6 y 128 caracteres.
  4. Envía la inscripción: haz clic sobre “Sign up” para confirmar tu inscripción. Si todos los datos se han completado correctamente, se envía un enlace de verificación a la dirección indicada
  5. Confirma la dirección de correo: confirma tu cuenta de correo haciendo clic en el enlace de verificación.

Podrás acceder directamente a los servicios online del proyecto de Docker tras registrarte desde el navegador. Aquí puedes crear repositorios y grupos de trabajo así como buscar a través de “Explore” los recursos con acceso público.

También es posible registrarse directamente en la consola del sistema operativo a través de docker login. Una explicación detallada de este comando está disponible en la documentación de Docker.

En principio, los usuarios sin cuenta ni ID en Docker también pueden acceder a Docker Hub, aunque solo podrán descargar imágenes de los repositorios de acceso público y tienen vetado subir (push) imágenes propias.

En principio, los usuarios sin cuenta ni ID en Docker también pueden acceder a Docker Hub, aunque solo podrán descargar imágenes de los repositorios de acceso público y tienen vetado subir (push) imágenes propias.

Crear repositorios en Docker Hub

La cuenta gratuita en Docker Hub alberga un repositorio de acceso privado y permite crear tantos repositorios de acceso público como se desee. No obstante, puedes desbloquear más repositorios de acceso privado con una actualización de pago.

Para instalar un repositorio hay que:

  1. Elegir un espacio de nombres: cuando se crea un repositorio, este recibe de forma automática el espacio de nombres de tu ID Docker, aunque también se le puede dar el de una organización a la que pertenezcas.
  2. Dar un nombre al repositorio: asigna un nombre al repositorio recién creado.
  3. Añadir una descripción: incluye una pequeña descripción así como instrucciones detalladas de uso.
  4. Configurar la seguridad: decide si quieres crear un repositorio de acceso público (public) o uno al que solo puedas acceder tú o tu organización (private).

Haz clic sobre “Create” para confirmar

Create teams and organizations

Con el Hub, Docker ofrece una plataforma basada en la nube donde se puede gestionar la creación de imágenes de manera central y compartirlas fácilmente con los grupos de trabajo, a los que Docker denomina organizaciones. Como ocurre con las cuentas de usuario, las organizaciones también reciben ID individuales con los que se descargan imágenes o las comparten con otros usuarios. Los derechos y el papel que cada miembro desempeña se organizan en equipos. De esta forma, por ejemplo, solo los usuarios que están en el equipo “Owners” pueden crear repositorios privados o públicos y asignar permisos de acceso.

También puedes crear y gestionar los grupos de trabajo a través del panel de control. Para más información con respecto a la gestión de equipos y organizaciones visita la documentación de Docker.

Cómo trabajar con imágenes y contenedores

Como punto de acceso primario para recursos oficiales de Docker, Docker Hub se constituye como punto de partida para nuestra introducción a la gestión de imágenes y contenedores. El equipo de desarrolladores presenta aquí, entre otras, la imagen demo whalesay que se utilizará como base en el tutorial de Docker que sigue.

Descargar imágenes Docker

Para encontrar la imagen whalesay, accede a la página de inicio de Docker Hub e introduce el término whalesay en la barra de búsqueda que se encuentra a la derecha del logo de Docker.

Haz clic en los resultados de búsqueda sobre el recurso con título docker/whalesay para acceder al repositorio público de esta imagen.

Los repositorios Docker muestran siempre la misma estructura: en la cabecera se lee el título de la imagen, la categoría del repositorio y el momento de la última carga (last pushed).

Cada repositorio Docker incluye también los siguientes apartados:

  • Short Description: breve descripción de los recursos.
  • Full Description: descripción detallada e instrucciones de uso.
  • Docker Pull Command: consola de línea de comandos para descargar imágenes del repositorio (pull).
  • Owner: información sobre el creador del repositorio.
  • Comments: zona de comentarios al final de la página.

En las ventanas de información del repositorio aparece que whalesay es una modificación del script Perl de código abierto cowsay. El programa desarrollado por Rony Monroe en el año 1999 genera en su formato de origen una gráfica ASCII en forma de vaca que aparece en la terminal del usuario junto con un mensaje.

Para descargar docker/whalesay utiliza el comando docker pull con la siguiente estructura:

$ docker pull [OPTIONS] NAME [:TAG|@DIGEST]

El comando docker pull ordena al daemon que cargue una imagen del repositorio. Para que pueda identificar la imagen, hay que introducir el título de esta (NAME). Además puedes indicarle a Docker cómo debe ejecutar el comando deseado (OPTIONS) y, de forma opcional, introducir tags (:TAG) o números de identificación únicos (@DIGEST) que permiten descargar una versión concreta de una imagen.

Para crear una copia local de la imagen docker/whalesay introduce el comando:

$ docker pull docker/whalesay

Este último no suele ser necesario pues, cuando se quiere iniciar un contenedor, el Docker daemon descarga las imágenes automáticamente del repositorio si no las puede encontrar en el sistema local.

Iniciar imágenes de Docker como contenedores

Para iniciar una imagen de Docker, utiliza el comando docker run con la siguiente estructura base:

$ docker run [OPTIONS] IMAGE [:TAG|@DIGEST] [CMD] [ARG...]

La única parte obligatoria del comando docker run la constituye el título de la imagen de Docker deseada, aunque cuando se inicia un contenedor se pueden definir también otras opciones, TAG y DIGEST. Además, es posible combinar el comando docker run con otros comandos que se ejecutan en el momento en el que se inicia el contenedor. En este caso se sobrescribe CMD (COMMAND), comando establecido por el creador que se ejecuta de forma automática cuando se inicia un contenedor. Con argumentos adicionales pueden definirse otras configuraciones opcionales, permitiendo añadir a usuarios o transferir variables de entorno (environment variables).

Utiliza el comando:

$ docker run docker/whalesay cowsay boo 

para descargar el script de Perl correspondiente como imagen y ejecutarlo en un contendor. Verás que whalesay se diferencia en gran medida del script de origen.

Al ejecutar la imagen docker/whalesay, el script muestra en la consola una gráfica ASCII en forma de ballena, así como el mensaje “boo” entregado con el comando cowsay.

Como ocurría en la prueba, el daemon busca en primer lugar la imagen en el directorio de archivos locales. Si no encuentra aquí un paquete con el mismo nombre se inicia un pulling desde el repositorio de Docker. Finalmente, el daemon inicia el programa cowsay modificado. Si este se ha ejecutado, el contenedor se cierra automáticamente.

Como ocurre con cowsay, whalesay de Docker también ofrece la posibilidad de intervenir en la marcha del programa para influir en la salida de texto en la terminal. Prueba la función sustituyendo el mensaje “boo” en el comando de salida con otra cadena de caracteres, por ejemplo, con un chiste de ballenas.

$ sudo docker run docker/whalesay cowsay What did the shark say to the whale? What are you blubbering about?

Visualizar todas las imágenes Docker en el sistema local

Puedes comprobar si has descargado una imagen determinada al acceder a la vista general de todas las imágenes de tu sistema local a través del comando:

$ sudo docker image 

El comando docker image muestra todas las imágenes locales junto con información sobre el tamaño de archivo, tag e ID de la imagen.

Cuando inicias un contenedor, se descarga la imagen subyacente del repositorio como copia y se guarda permanentemente en tu ordenador, lo que te permite ahorrar tiempo si en otro momento quieres tener acceso a ella. Solo será necesaria una nueva descarga si cambia la fuente de la imagen, por ejemplo, cuando en el repositorio existe una versión actualizada.

Visualizar todos los contenedores en el sistema local

Si quieres visualizar todos los contenedores que se están ejecutando o han sido ejecutados en el sistema debes usar el comando docker ps junto con la opción --all (abreviado: -a):

$ sudo docker ps -a

La salida en la terminal muestra el ID del contendor correspondiente, la imagen subyacente, el comando ejecutado al iniciarlo, el momento de inicio de este y su estado actual.

Para visualizar los contendores que se están ejecutando en este momento, usa el comando docker ps sin opción:

$ sudo docker ps

No obstante, ahora no debería haber ningún contenedor ejecutándose en tu sistema.

Crear imágenes Docker

Ya sabes cómo encontrar imágenes en Docker Hub, descargarlas y ejecutarlas en cualquiera de los sistemas en los que haya sido instalado el motor de Docker. Pero Docker no solo pone a tu disposición la enorme oferta de aplicaciones del registro, sino que también ofrece un gran abanico de recursos para crear tus propias imágenes y compartirlas con otros desarrolladores.

En los capítulos introductorios se ha visto que cada imagen de Docker se basa en un Dockerfile que funciona a modo de instrucciones de montaje para imágenes, ya que se trata de un archivo de texto simple donde están todas las instrucciones que Docker necesita para crear una imagen. En los siguientes apartados se explicará cómo escribir este tipo de Dockerfile y ordenar a Docker que lo use como base para una imagen propia.

  1. Crear un directorio nuevo: el equipo de desarrolladores de Docker recomienda crear un directorio propio para cada Dockerfile, acción que se puede realizar fácilmente con Linux en la terminal. Si usas el programa de línea de comandos que aparece a continuación, puedes crear un directorio con el nombre mydockerbuild:
$ mkdir mydockerbuild
  1. Explorar el nuevo directorio: para ello usa el comando cd
$ cd mydockerbuild
  1. Crear un nuevo archivo de texto: también es posible crear archivos de texto en la terminal de Ubuntu usando para ello editores como Nano o Vim. Crea un archivo de texto con el nombre Dockerfile en el directorio mydockerbuild.
$ nano Dockerfile
  1. Escribir Dockerfile: el archivo de texto recién creado sirve de guía para la imagen que vayas a desarrollar. En vez de programar la imagen desde cero, este tutorial de Docker usa la imagen de muestra docker/whalesay como plantilla, la cual se integra en el Dockerfile con el comando FROM. Para señalar la versión más actual de la imagen usa :latest como tag.
FROM docker/whalesay:latest

Hasta ahora el funcionamiento de docker/whalesay se basa en permitir al usuario elegir las palabras que aparecen en la boca de la ballena, de modo que en la terminal aparece exactamente este texto junto con el comando de inicio del contenedor. Pero sería mucho más interesante si el script generase automáticamente nuevas salidas de texto. Esto se puede hacer gracias a programas como fortunes, disponible para el sistema Linux, y cuya función principal es generar proverbios y divertidos aforismos. Puedes actualizar el índice de paquetes locales e instalar fortunes con el comando:

RUN apt-get -y update && apt-get install -y fortunes

Finalmente define una declaración CMD. Esta se ejecuta tras el comando RUN, siempre y cuando no haya sido reescrita en la llamada (docker run image CMD). Utiliza:

CMD /usr/games/fortune -a | cowsay

para ejecutar el programa fortunes con la opción –a (“seleccionar de todas las bases de datos”) y mostrar el output en la terminal mediante el programa cowsay.

El dockerfile debería de mostrarse ahora como:

FROM docker/whalesay:latest
RUN apt-get -y update && apt-get install -y fortunes
CMD /usr/games/fortune -a | cowsay

Ten en cuenta: los comandos dentro de un Dockerfile tienen una única línea y empiezan siempre con una palabra clave. La sintaxis no distingue entre mayúsculas o minúsculas, aunque sí se ha establecido que las palabras clave deben ir escritas en mayúsculas.

  1. Guardar archivos de texto: guarda tus entradas. Si usas el editor Nano utiliza la combinación de teclas [STRG] + [O] y confirma con [ENTER]. Nano te comunica que se han escrito tres líneas en el archivo seleccionado. Cierra el editor de textos con la combinación [STRG] + [X].

  2. Crear imágenes a partir de Dockerfile: para crear una imagen a partir de un Dockerfile, dirígete primero al directorio en el que se encuentran los archivos de texto. La creación de la imagen se inicia con el comando docker build. Si quieres nombrar la imagen de forma individual o proveerla de una tag, usa la opción -t junto con la combinación del nombre seleccionado y del tag. El formato estándar es name:tag.

En el siguiente ejemplo se crea la imagen con el nombre docker-whale:

$ docker build -t docker-whale .

EL punto final indica que el Dockerfile subyacente se encuentra en el directorio seleccionado, aunque también tienes la posibilidad de añadir una ruta de archivos o un URL a los archivos fuente.

El proceso build comienza tan pronto como se haya confirmado el comando con [ENTER]. Primero el Docker daemon comprueba si dispones de todos los archivos necesarios para la creación de una imagen, a los que se conoce como “Context” de acuerdo con la terminología de Docker. En la terminal aparece la siguiente notificación de estado:

Sending build context to Docker daemon 2.048 kB 

Finalmente se ubica la imagen docker/whalesay con el Tag  :latest

Step 1/3 : FROM docker/whalesay:latest
   ---> 6b362a9f73eb

Si el Context necesario para la creación de una imagen está completo, el daemon de Docker inicia la plantilla integrada de la imagen a través de FROM en un contenedor temporal y pasa al siguiente comando en el Dockerfile. En nuestro ejemplo se trata de un comando RUN que desencadena la instalación del programa fortunes.

Step 2 : RUN apt-get -y update && apt-get install -y fortunes
   ---> Running in 80b81eda1a11
…etc. 

Al finalizar cada paso en el proceso de creación de una imagen, Docker asigna un ID para la capa (layer) creada en ese paso. Hay que tener en cuenta que cada línea del Dockerfile subyacente se corresponde con una capa de la imagen en construcción.

Cuando se finaliza el comando RUN, el Docker daemon detiene el contenedor creado para ello, lo elimina e inicia un nuevo contenedor temporal para la capa de la declaración CMD.

Step 3/3 : CMD /usr/games/fortune -a | cowsay
 ---> Running in c3ac46675e7a
 ---> 4419af61d32d
Removing intermediate container c3ac46675e7a

Al final del proceso de creación, el contenedor temporal creado en el paso 3 también se cierra y elimina. Docker muestra el ID de la nueva imagen:

Successfully built 4419af61d32d

La imagen creada se muestra con el nombre de docker-whale en la lista de imágenes guardadas de forma local.

$ sudo docker images

Para iniciar un contenedor desde la imagen recién creada usa el comando sudo docker run junto con el nombre de la imagen:

$ sudo docker run docker-whale 

Si la imagen se ha creado correctamente desde el dockerfile, la ballena debería llenarte de sabiduría con sus doctas palabras. Aviso: cada vez que se inicie un contenedor se genera una frase nueva.

Hacer tagging a tus imágenes de Docker y subirlas a Docker Hub

Antes de poder subir a Hub la imagen creada y de este modo compartirla con la comunidad o con un grupo determinado, debes enlazarla con un repositorio homónimo en tu espacio de nombres personal. Si seguimos la terminología de Docker, este proceso se denomina tagging.

Para publicar una imagen en Docker Hub sigue los siguientes pasos:

  1. Crear un repositorio: regístrate en Docker Hub con tu ID de Docker y la contraseña personal y crea un repositorio público con el nombre de docker-whale.
  1. Obtener el ID de la imagen: obtén el identificador de la imagen que has creado con ayuda del comando docker images.
$ sudo docker images
REPOSITORY      TAG     IMAGE ID       CREATED        SIZE
docker-whale    latest  4419af61d32d   22 hours ago   275 MB
hello-world     latest  48b5124b2768   6 weeks ago    1.84 kB
docker/whalesay latest  6b362a9f73eb   21 months ago  247 MB

En este caso, el ID de la imagen es 4419af61d32d, necesario para realizar el tagging en el siguiente paso.

  1. Realizar el tagging de la imagen: para realizar el tagging de la imagen docker-whale usa el comando docker tag con este esquema:
$ sudo docker tag [Image-ID][Docker-ID]/[Image-Name]:[TAG]

En este ejemplo concreto el comando reza:

$ sudo docker tag 4419af61d32d myfreedockerid/docker-whale:latest

Para comprobar si se ha llevado a cabo el tagging de la imagen correctamente accede a la vista general con docker images. El nombre del repositorio debería de mostrar ya tu ID de Docker.

  1. Subir la imagen: para ello, primero debes acceder a Docker Hub. Usa para ello el comando docker login
$ sudo docker login

La terminal te pide el nombre de usuario (ID de Docker) así como la contraseña.

Una vez dentro, introduce el comando docker push para cargar la imagen en el repositorio recién creado.

$ sudo docker push myfreedockerid/docker-whale

El proceso de carga no debe de tardar más de unos segundos. En la terminal se muestra el estado actual.

Si entras en Docker Hub desde el navegador podrás ver tu imagen.

Si deseas cargar más de una imagen por repositorio, entonces usa tags diferentes para mostrar las imágenes en versiones distintas, como por ejemplo:

myfreedockerid/docker-whale:latest
myfreedockerid/docker-whale:version1
myfreedockerid/docker-whale:version

En la pestaña Tags puedes acceder a una vista general de todas las versiones de imágenes de un repositorio.

Por el contrario, las imágenes de proyectos diferentes deberían aparecer en repositorios separados.

Una vez hayas subido la imagen con éxito, esta estará disponible para los usuarios de todo el mundo en el repositorio público.

  1. Comprobación: para comprobar que la imagen se ha subido correctamente, intenta descargarla.

No olvides que primero hay que borrar la versión local de la imagen para poder descargarte una copia con el mismo tag, porque Docker podría notificarte que la imagen deseada ya se encuentra en la versión actual.

Para borrar las imágenes locales de Docker, utiliza el comando docker rmi en combinación con el ID de la imagen, que se obtiene con docker images. En caso de que Docker mostrara que el ID de la imagen se esté usando en más repositorios, esté siendo utilizado por un contenedor u otro tipo de conflicto, se corrobora el comando con la opción --force (abreviado: -f) y de esta forma se fuerza la eliminación.

sudo docker rmi -f 4419af61d32d

Vuelve a acceder a la vista general de todas las imágenes:

$ sudo docker Images

En la salida de la terminal no deberían aparecer los elementos borrados. Usa únicamente el comando Pull indicado en el repositorio para descargar una copia nueva de la imagen desde Docker Hub:

$ sudo docker pull myfreedockerid/docker-whale

Salta al nivel profesional en Docker

En este tutorial de Docker se muestran los puntos esenciales que diferencian a las plataformas de contenedores de la virtualización tradicional de hardware. En este caso, Docker se basa en un software de contenedores evitando así el coste de un sistema operativo huésped virtual. Esto se debe a que los contenedores comparten el kernel de un mismo sistema host y generan, a modo de procesos aislados en el espacio de usuario, todo lo que necesitan para la ejecución de aplicaciones, obteniendo como resultado la máxima portabilidad. Con Docker es posible ejecutar un mismo contenedor de software en diversas plataformas con distintos sistemas e infraestructuras y solo se impone como requisito la instalación de un motor de Docker de forma local y el registro al Docker Hub basado en la nube.

Tomando como base Ubuntu, la conocida distribución de Linux, en nuestro tutorial de Docker hemos mostrado cómo en poco tiempo puedes crear una plataforma de contenedores preparada para funcionar. Has aprendido a instalar y ejecutar Docker con Ubuntu, así como a descargar aplicaciones como imágenes desde Docker Hub y a ejecutarlas de forma local en contenedores. Además, has escrito un Dockerfile para crear una imagen propia y la has puesto a disposición de todos los usuarios a través de Docker Hub. En definitiva, ya posees las nociones fundamentales sobre la plataforma de contenedores Docker.

Sin embargo, el universo de Docker es enorme. Con el paso del tiempo este proyecto de código abierto ha desarrollado un ecosistema vivo. Además un gran número de competidores rodean al líder con otros productos de software alternativos. No obstante, Docker se presenta como una plataforma especialmente atractiva para los administradores que quieren gestionar aplicaciones complejas con muchos contenedores en diferentes sistemas operativos de forma paralela. Para orquestar esto, Docker ofrece diferentes funciones entre las que se pueden destacar las herramientas de Docker Swarm y Compose.