Introducción a los Contenedores y a Docker

La contenerización, como la llamaremos en esta guía (del inglés containerization), es un enfoque de desarrollo de software en el que una aplicación o servicio, sus dependencias y su configuración (en forma de ficheros de manifiesto para despliegue) se empaquetan juntos como una imagen de contenedor (o simplemente imagen para simplificar, cuando no haya ambigüedad). Una aplicación basada en contenedores se puede probar como una unidad y desplegar como una instancia de la imagen, en el sistema operativo que funciona como host.

Así como los contenedores de carga facilitan el transporte por barco, tren o camión, sin importar el contenido, los contenedores de software funcionan como una unidad estándar que puede agrupar distintos programas y dependencias. La contenerización permite que los desarrolladores y los responsables de infraestructura puedan desplegar aplicaciones o servicios en diferentes entornos, con pocas o ninguna modificación.

Los contenedores también aíslan las aplicaciones de otras instaladas en un sistema operativo (SO) compartido. Las aplicaciones contenerizadas se ejecutan en un host de contenedores que, a su vez, se ejecuta sobre el sistema operativo (Linux o Windows). Por eso, los contenedores son significativamente más livianos que las imágenes de máquinas virtuales (VM).

Cada contenedor puede ejecutar una aplicación o servicio, como se muestra en la figura 2-1. En este ejemplo en host Docker es un host de contenedores y App1, App2, Svc1 y Svc2 son aplicaciones y servicios contenerizados.

Image

Figura 2-1. Múltiples contenedores corriendo en un host de contenedores

Otro beneficio de la contenerización es la escalabilidad. Se puede ampliar rápidamente la capacidad creando nuevos contenedores para cargas o tareas de corta duración. Desde el punto de vista de la aplicación, el instanciar una imagen (crear un contenedor) es similar a instanciar un proceso como un servicio o una aplicación web. Sin embargo, por razones de confiabilidad y disponibilidad, cuando se ejecutan múltiples instancias de una imagen, típicamente se distribuyen entre varios servidores o máquinas virtuales en diferentes dominios de falla.

En resumen, los contenedores ofrecen los beneficios de aislamiento, portabilidad, agilidad, escalabilidad y control, a lo largo de todo el ciclo de vida de la aplicación. El beneficio más importante es la separación o independencia de la aplicación de los entornos de desarrollo (Dev) y operaciones (Ops).

¿Qué es Docker?

Docker es un proyecto open-source para automatizar el despliegue de aplicaciones como contenedores independientes y autosuficientes, que se pueden ejecutar en la nube o en servidores internos. Docker es también una compañía que promociona y desarrolla esta tecnología, colaborando con varios proveedores de Linux, Windows y plataformas en la nube, incluyendo a Microsoft.

Image

Figura 2-2. Con Docker se pueden desplegar contenedores en todas las capas de la nube híbrida

Las imágenes Docker pueden correr de forma nativa en Linux o Windows, sin embargo, las imágenes Windows sólo se pueden ejecutar en hosts Windows y las imágenes Linux sólo en hosts Linux, entendiendo host como un servidor o una máquina virtual.

El entorno de desarrollo puede ser Windows, Linux o macOS. En la máquina de desarrollo se ejecuta un host Docker, donde se despliegan las imágenes Docker, incluyendo la aplicación o servicio y sus dependencias. Para desarrollar en Linux o Mac se utiliza un host Docker basado en Linux y sólo se pueden crear imágenes para contenedores Linux. (En la Mac se puede editar código y ejecutar la interfaz de comandos de Docker (Docker CLI) desde macOS, pero, al menos hasta este momento, no se pueden ejecutar contenedores directamente en macOS). Desde Windows sí se pueden crear imágenes de contenedores tanto para Linux como para Windows.

Para manejar contenedores en entornos de desarrollo y manejar herramientas adicionales para el desarrollo, Docker provee el Docker Community Edition (CE) tanto para Windows como para macOS. Este producto instala la máquina virtual (el host Docker) necesaria para manejar los contenedores. Docker también tiene disponible la versión Docker Enterprise Edition (EE), que está diseñada para los entornos de desarrollo empresarial y se usa para desarrollar, desplegar y ejecutar grandes aplicaciones críticas para el negocio, en entornos de producción.

Hay dos tipos de motor de ejecución (runtime) para Contenedores de Windows:

Las imágenes para estos contenedores se crean y funcionan de la misma forma. La diferencia está en cómo se crea el contenedor a partir de la imagen, cuando se ejecuta un Contenedor Hyper-V hace falta un parámetro adicional. Para más detalle, consulte Contenedores de Hyper-V.

Comparando contenedores Docker con máquinas virtuales

Como los contenedores requieren muchos menos recursos (por ejemplo, no necesitan un sistema operativo completo) son fáciles de desplegar y arrancan rápido. Esto permite tener una mayor densidad, lo que significa que se pueden ejecutar más servicios en el mismo equipo y, por lo tanto, reduce los costes.

Como efecto secundario, al compartir el mismo núcleo del sistema operativo, se tiene menos aislamiento que en las máquinas virtuales.

El propósito de una imagen es hacer que el entorno (es decir, las dependencias) de la aplicación sea el mismo para todos los despliegues. Esto significa que puede depurar una imagen en su máquina y luego desplegarla en otra, asegurando que se mantiene el mismo entorno.

Una imagen es una forma de empaquetar una aplicación o servicio para desplegarlo de forma confiable y reproducible. Se podría decir que Docker no es sólo una tecnología sino también una filosofía y un proceso.

Cuando se usa Docker no escuchará a los desarrolladores decir “funciona en mi máquina, ¿por qué no en producción?”. Simplemente dirán “Funciona en Docker”, porque una aplicación empaquetada en Docker se puede ejecutar en cualquier entorno soportado por Docker y se ejecutará de la forma prevista en todos los entornos de despliegue (Desarrollo, control de calidad, pre-producción (staging) y producción).

La Figura 2-3 muestra una comparación entre máquinas virtuales y contenedores Docker.

Máquinas Virtuales

Image

Las máquinas virtuales (VM) incluyen la aplicación, las librerías y otros ficheros necesarios, así como un sistema operativo completo. La virtualización requiere más recursos que el manejo de contenedores.

Contenedores Docker

Image

Los contenedores incluyen la aplicación y todas sus dependencias, pero comparten el kernel del sistema operativo. Se ejecutan como procesos aislados en el entorno de un usuario del sistema operativo. (Excepto en Contenedores Hyper-V, donde cada contenedor se ejecuta en una VM)

Figura 2-3. Comparación entre las máquinas virtuales tradicionales y los contenedores Docker

Terminología Docker

En esta sección se presentan los términos y definiciones que debe manejar antes de entrar en profundidades con Docker. Para más definiciones, consulte el glosario provisto por Docker (https://docs.docker.com/glossary/).

Nota: En la traducción se mantienen muchos términos en inglés, porque son de uso habitual y el traducirlos podría más bien crear una barrera a la comunicación y comprensión.

Imagen de Contenedor (Container Image/Docker Image): O simplemente imagen, cuando no haya ambigüedad en el contexto. Un paquete con todas las dependencias e información necesaria para crear un contenedor. La imagen contiene todas las dependencias (como frameworks, por ejemplo) así como toda la configuración de despliegue y ejecución que será utilizada por el contenedor en tiempo de ejecución. Usualmente una imagen se deriva de otras imágenes base, que forman capas apiladas para conformar el sistema de ficheros del contenedor. Una imagen es inmutable, es decir, no se puede modificar después de crearla.

Contenedor (Container): Una instancia de una imagen (Docker Image). Un contenedor representa la ejecución de una sola aplicación, proceso o servicio. Están formados por el contenido de la imagen Docker, el entorno de ejecución y un conjunto estándar de instrucciones. Cuando se escala un servicio, se crean varios contenedores a partir de la misma imagen, pasando parámetros diferentes a cada instancia. También, un programa batch puede crear múltiples contenedores a partir de la misma imagen, pasando parámetros diferentes a cada instancia.

Etiqueta (Tag): Un elemento que se puede aplicar a las imágenes para identificar versiones o entornos de destino.

Dockerfile: Un fichero de texto que contiene instrucciones sobre cómo construir la imagen Docker.

Construir (Build): La acción de preparar una imagen Docker según la información y contexto definido en su Dockerfile, más los ficheros adicionales de la carpeta donde se prepara la imagen. Para preparar imágenes Docker se utiliza el comando: docker build.

Repositorio (Repo): Una colección de imágenes Docker, identificadas con una etiqueta para diferenciar la versión. Algunos repositorios contienen múltiples variantes de una imagen específica, por ejemplo, imágenes con SDK (más pesadas) o imágenes sólo con entorno de ejecución (más livianas), etc. Todas esas variantes se identifican con etiquetas. Puede haber variantes por plataforma (imágenes Linux y Windows) en un mismo repositorio.

Registro (Registry): Un servicio que provee el acceso a los repositorios. El registro por defecto para la mayoría de las imágenes públicas en Docker Hub (mantenido por la organización Docker). Un registro usualmente contiene repositorios de varios equipos de trabajo. Las empresas frecuentemente tienen registros privados para gestionar las imágenes que han creado. Otro ejemplo de registro es el Azure Container Registry.

Docker Hub: Un registro público para gestionar imágenes y trabajar con ellas. Docker Hub provee almacenamiento de las imágenes, registros públicos y privados, así como web hooks, triggers e integración con GitHub y Bitbucket.

Azure Container Registry: Un recurso público para trabajar con imágenes Docker y sus componentes en Azure. Este provee un registro cercano a los despliegues en Azure y permite controlar el acceso a través de los grupos y permisos de Azure Active Directory.

Docker Trusted Registry (DTR): Un servicio de registro ofrecido por la organización Docker, que se puede instalar en los servidores de la organización. Es conveniente para imágenes privadas que deban ser manejadas dentro de la empresa. El Docker Trusted Registry es parte del producto Docker Datacenter. Para más información consulte Docker Trusted Registry (DTR).

Docker Community Edition (CE): Es una herramienta de desarrollo para Windows y macOS, para preparar, ejecutar y probar contenedores localmente. Docker CE para Windows provee los entornos de desarrollo para contenedores de Linux y de Windows. El Docker host de Linux está basado en una máquina virtual Hyper-V. El host para contenedores Windows está basado directamente en Windows. Docker CE para Mac está basado en el Apple Hypervisor Framework y el xhyve hypervisor que provee una máquina virtual con el host Docker para Linux sobre Mac OS X. Docker CE para Windows y para Mac reemplaza al Docker Toolbox, que estaba basado en el VirtualBox de Oracle.

Docker Enterprise Edition (EE): Es una versión, a escala empresarial, de las herramientas Docker para desarrollo y producción en Linux y Windows.

Compose: Una herramienta de línea de comandos y un fichero en formato YAML con metadata, para definir y ejecutar aplicaciones de múltiples contenedores. Se define una aplicación basada en múltiples imágenes con uno o más ficheros .yml, que pueden reemplazar parámetros dependiendo del entorno. Después de crear las definiciones, se puede desplegar la aplicación multi-contenedores con un solo comando (docker-compose up) que crea un contenedor en el host Docker por cada imagen.

Cluster: Una colección de hosts Docker presentada como si fuera un host Docker virtual único, para que una aplicación pueda escalar a múltiples instancias de servicios, distribuidos en múltiples hosts dentro del cluster. Se puede crear un cluster de Docker con Docker Swarm, Mesosphere DC/OS, Kubernetes y Azure Service Fabric. (Cuando se usa el Docker Swarm para gestionar un cluster, habitualmente se hace referencia a la colección como “swarm” en vez de “cluster”.)

Orquestador (Orchestrator): Una herramienta que simplifica la gestión de clusters y hosts Docker. Los orquestadores permiten gestionar sus imágenes, contenedores y hosts a través de interfaces gráficas o de línea de comandos (CLI). Se pueden gestionar las redes de contenedores, las configuraciones, balanceo de carga, descubrimiento de servicios, alta disponibilidad, configuración de los host Docker y más. Un orquestador es responsable de ejecutar, distribuir, escalar y reparar las cargas de trabajo en una colección de nodos. Usualmente los orquestadores son los mismos productos que proveen la infraestructura para el cluster, como Mesosphere DC/OS, Kubernetes, Docker Swarm y Azure Service Fabric.

Contenedores Docker, imágenes y registros

Al usar Docker, el desarrollador crea una aplicación o servicio y lo empaqueta junto con sus dependencias en una imagen de contenedor. Una imagen es una representación estática de la aplicación o servicio junto con su configuración y sus dependencias.

Para ejecutar una aplicación o servicio, la imagen de la aplicación se instancia para crear un contenedor que se ejecutará en el host Docker. Los contenedores se prueban primero en un entorno de desarrollo o en un computador personal.

Los desarrolladores deberían guardar las imágenes en un registro, que funciona como una librería y se necesita para poder desplegar a través de los orquestadores de producción. Docker mantiene un registro público a través del Docker Hub; otros proveedores también ofrecen registros para diferentes colecciones de imágenes. Por otro lado, las empresas también pueden tener registros internos (on-premises), para mantener sus propias imágenes Docker.

la figura 2-4 muestra cómo se relacionan las imágenes y registros de Docker con los otros componentes del sistema. También se muestran las ofertas de registros de algunos proveedores.

Image

Figura 2-4. Taxonomía de los términos y conceptos de Docker

Guardar las imágenes en un registro permite mantener todos los elementos de la aplicación, incluyendo sus dependencias hasta nivel del framework. Así, esas imágenes se pueden versionar y desplegar en múltiples entornos y, por lo tanto, ofrecer una unidad consistente de despliegue.

los registros privados de imágenes, tanto en servidores internos como en la nube se recomiendan cuando: