Funcionamiento de los contenedores de Docker

Completado

Anteriormente, el contenedor es la unidad que usará para distribuir las aplicaciones. También ha aprendido que un contenedor se encuentra en un formato normalizado que usan los equipos de desarrollo y operaciones.

En nuestro ejemplo, está desarrollando un portal de seguimiento de pedidos que usarán las tiendas de su empresa. Una vez compilada la imagen de Docker, el equipo de operaciones se encarga de la implementación, la aplicación de actualizaciones y la administración del portal de seguimiento de pedidos.

En la unidad anterior, examinó cómo se crea una imagen de Docker. Aquí verá el ciclo de vida de un contenedor de Docker y cómo se administran los contenedores. También analizará cómo se configura el almacenamiento de datos y las opciones de red de los contenedores.

Cómo administrar contenedores de Docker

Un contenedor de Docker tiene un ciclo de vida que puede usar para administrar y hacer un seguimiento del estado del contenedor.

Diagram that shows the lifecycle of a container and the transition between the lifecycle phases.

Para colocar un contenedor en el estado de ejecución, use el comando run. También puede reiniciar un contenedor que ya se está ejecutando. Al reiniciar un contenedor, este recibe una señal de terminación para permitir que los procesos en ejecución se cierren correctamente antes de que finalice el kernel del contenedor.

Un contenedor se considera en estado de ejecución hasta que se pausa, se detiene o se elimina. Pero los contenedores también pueden salir del estado de ejecución de forma independiente. Un contenedor puede salir automáticamente cuando se completa el proceso en ejecución o si el proceso entra en un estado de error.

Para pausar un contenedor en ejecución, use el comando pause. Este comando suspende todos los procesos del contenedor.

Para detener un contenedor en ejecución, use el comando stop. El comando "stop" permite que el proceso de trabajo se cierre correctamente al enviarle una señal de finalización. El kernel del contenedor finaliza una vez que se cierra el proceso.

Para enviar una señal de terminación si es necesario finalizar el contenedor, use el comando kill. El kernel del contenedor captura la señal de eliminación, pero el proceso en ejecución no. Este comando finaliza forzosamente el proceso de trabajo en el contenedor.

Por último, para quitar los contenedores que se encuentran en estado detenido, use el comando remove. Una vez que se quita un contenedor, se destruyen todos los datos almacenados en él.

Cómo ver los contenedores disponibles

Para mostrar los contenedores en ejecución, use el comando docker ps. Para ver todos los contenedores en todos los estados, pase el argumento -a.

Este es un ejemplo:

docker ps -a

Esta es la salida de ese comando anterior:

CONTAINER ID    IMAGE        COMMAND         CREATED       STATUS           PORTS        NAMES
d93d40cc1ce9    tmp-ubuntu:latest  "dotnet website.dll …"  6 seconds ago    Up 5 seconds        8080/tcp      happy_wilbur
33a6cf71f7c1    tmp-ubuntu:latest  "dotnet website.dll …"  2 hours ago     Exited (0) 9 seconds ago            adoring_borg

Vamos a revisar tres elementos de la salida anterior:

  • El nombre de la imagen que aparece en la columna IMAGE; en este ejemplo, tmp-ubuntu: latest. Observe cómo está permitido crear más de un contenedor a partir de la misma imagen. Se trata de una característica de administración eficaz que puede usar para habilitar el escalado en las soluciones.

  • El estado del contenedor que se muestra en la columna STATUS. En este ejemplo, hay un contenedor que se está ejecutando y otro que ha terminado. Normalmente, el estado del contenedor es el primer indicador de su estado de mantenimiento.

  • El nombre del contenedor que se muestra en la columna NAMES. Además del identificador de contenedor en la primera columna, los contenedores también reciben un nombre. En este ejemplo, no ha proporcionado explícitamente un nombre para cada contenedor y, como resultado, Docker ha dado al contenedor un nombre aleatorio. Para asignar un nombre explícito a un contenedor mediante la marca --name, use el comando run.

¿Por qué reciben un nombre los contenedores?

Esta característica permite ejecutar varias instancias de contenedor de la misma imagen. Los nombres de contenedor son únicos, lo que significa que, si se especifica un nombre, ese nombre no se puede volver a usar para crear un nuevo contenedor. La única manera de reutilizar un nombre específico es quitar el contenedor anterior.

Cómo ejecutar un contenedor

Use el comando docker run para iniciar un contenedor. Solo es necesario especificar la imagen que se va a ejecutar mediante su nombre o identificador para iniciar el contenedor a partir de la imagen. Un contenedor iniciado de esta manera proporciona una experiencia interactiva.

En este caso, para ejecutar el contenedor con nuestro sitio web en segundo plano, agregue la marca -d.

docker run -d tmp-ubuntu

En este caso, el comando solo devuelve el identificador del nuevo contenedor.

Una vez que se especifica la ejecución de una imagen, Docker busca la imagen, carga el contenedor desde la imagen y ejecuta el comando especificado como punto de entrada. En este momento, el contenedor se puede administrar.

Cómo pausar un contenedor

Para pausar un contenedor, ejecute el comando docker pause. Este es un ejemplo:

docker pause happy_wilbur

Al pausar un contenedor, se suspenden todos los procesos. Este comando permite que el contenedor continúe los procesos más adelante. El comando docker unpause anula la suspensión de todos los procesos de los contenedores especificados.

Cómo reiniciar un contenedor

Para reiniciar un contenedor, ejecute el comando docker restart. Este es un ejemplo:

docker restart happy_wilbur

El contenedor recibe un comando "stop", seguido de un comando "start". Si el contenedor no responde al comando "stop", se envía una señal de terminación.

Cómo detener un contenedor

Para detener un contenedor en ejecución, ejecute el comando docker stop. Este es un ejemplo:

docker stop happy_wilbur

El comando "stop" envía una señal de finalización al contenedor y a los procesos que se ejecuta en él.

Cómo eliminar un contenedor

Para eliminar un contenedor, ejecute el comando docker rm. Este es un ejemplo:

docker rm happy_wilbur

Una vez que elimine el contenedor, todos los datos del contenedor se destruirán. Es muy importante tener en mente que los contenedores son temporales cuando pensamos en el almacenamiento de los datos.

Configuración del almacenamiento en los contenedores de Docker

Tal y como se describió anteriormente, siempre debe considerar los contenedores como temporales cuando la aplicación de un contenedor necesita almacenar datos.

Supongamos que el portal de seguimiento crea un archivo de registro en una subcarpeta de la raíz de la aplicación, es decir, directamente en el sistema de archivos del contenedor. Cuando la aplicación escribe datos en el archivo de registro, el sistema los escribe en la capa grabable del contenedor.

Aunque este enfoque funciona, lamentablemente, presenta varias desventajas.

  • El almacenamiento en el contenedor es temporal.

    El archivo de registro no se conservará entre instancias de contenedor. Por ejemplo, supongamos que detiene y elimina el contenedor. Cuando inicie una nueva instancia de contenedor, se eliminarán las bases de la nueva instancia de la imagen especificada y se perderán todos los datos anteriores. Recuerde que todos los datos de un contenedor se destruyen cuanto este se elimina.

  • El almacenamiento del contenedor está acoplado a la máquina host subyacente.

    Es difícil acceder al archivo de registro o moverlo desde el contenedor, ya que el contenedor está acoplado a la máquina host subyacente. Tendrá que conectarse a la instancia de contenedor para acceder al archivo.

  • Las unidades de almacenamiento del contenedor ofrecen un rendimiento menor.

    Los contenedores implementan un controlador de almacenamiento para permitir que las aplicaciones graben datos. Este controlador presenta una abstracción adicional para comunicarse con el kernel del sistema operativo del host y ofrece un rendimiento menor que escribir directamente en un sistema de archivos de host.

Los contenedores pueden usar dos opciones para conservar los datos. La primera consiste en hacer uso de volúmenes y la segunda es mediante montajes de enlace.

¿Qué es un volumen?

Un volumen se almacena en el sistema de archivos del host en una carpeta específica. Elija una carpeta donde sepa que los procesos que no son de Docker no van a modificar los datos.

Docker crea y administra el nuevo volumen mediante la ejecución del comando docker volume create. Este comando puede estar incluido en la definición de Dockerfile, lo que significa que se pueden crear volúmenes como parte del proceso de creación del contenedor. Docker creará el volumen, si este no existe, la primera vez que intente montarlo en un contenedor.

Los volúmenes se almacenan en directorios en el sistema de archivos del host. Docker montará y administrará los volúmenes en el contenedor. Una vez montados, estos volúmenes están aislados de la máquina host.

Varios contenedores pueden usar simultáneamente los mismos volúmenes. Además, los volúmenes no se eliminan automáticamente cuando los contenedores dejan de usarlos.

En este ejemplo, puede crear un directorio en el host del contenedor y montar este volumen en el contenedor cuando cree el contenedor del portal de seguimiento. Cuando el portal de seguimiento registra los datos, se puede acceder a esta información a través del sistema de archivos del host del contenedor. Tendrá acceso a este archivo de registro incluso si se elimina el contenedor.

Docker también permite que las empresas de terceros creen complementos que se usarán como volúmenes. Por ejemplo, Azure Storage proporciona un complemento para montar Azure Storage como volúmenes en contenedores de Docker.

¿Qué es un montaje de enlace?

Un montaje de enlace es conceptualmente lo mismo que un volumen; pero, en lugar de usar una carpeta específica, puede montar cualquier archivo o carpeta en el host. También espera que el host pueda cambiar el contenido de estos montajes. Igual que sucede con los volúmenes, un montaje de enlace se crea si lo monta y aún no existe en el host.

Los montajes de enlace tienen una funcionalidad limitada en comparación con los volúmenes y, aunque ofrecen más rendimiento, dependen de que el host tenga una estructura de carpetas específica.

Los volúmenes son la estrategia de almacenamiento de datos preferida a la hora de trabajar con contenedores.

Hay otra opción disponible para los contenedores de Windows: puede montar una ruta de acceso SMB como volumen y ponerla a disposición a los contenedores. Esto permite que los contenedores de distintos hosts usen el mismo almacenamiento persistente.

Configuración de la red de los contenedores de Docker

La configuración de red predeterminada de Docker hace que sea posible aislar los contenedores en el host de Docker. Esta característica permite crear y configurar aplicaciones que pueden comunicarse de forma segura entre sí.

Docker proporciona configuraciones de red diferentes para Linux y Windows.

Para Linux, hay seis opciones de red preconfiguradas:

  • Red de puente
  • Red de host
  • Overlay
  • IPvLan
  • MACvLan
  • None

Para Windows, hay seis opciones de red preconfiguradas:

  • NAT (traducción de direcciones de red)
  • Transparente
  • Overlay
  • L2Bridge
  • L2Tunnel
  • None

Puede elegir cuál de estas configuraciones de red se aplicará a su contenedor en función de sus requisitos de red.

¿Qué es la red de puente?

La red de puente es la configuración predeterminada que se aplica a los contenedores cuando se inician sin especificar ninguna otra configuración de red. Se trata de una red privada interna usada por el contenedor y que aísla la red del contenedor de la red del host de Docker.

A cada contenedor en la red de puente se le asigna una dirección IP y una máscara de subred cuyo nombre de host es el nombre del contenedor de forma predeterminada. Los contenedores conectados a la red de puente predeterminada pueden acceder a otros contenedores conectados a ella mediante la dirección IP. La red de puente no permite la comunicación entre contenedores a través de nombres de host.

De forma predeterminada, Docker no publica ningún puerto de contenedor. Para habilitar la asignación de puertos entre los puertos de contenedor y los puertos de host de Docker, use la marca --publish de puerto de Docker.

La marca de publicación configura eficazmente una regla de firewall que asigna los puertos.

En este ejemplo, el portal de seguimiento es accesible para los clientes que exploran el puerto 80. Tendrá que asignar el puerto 80 desde el contenedor a un puerto disponible en el host. Tiene el puerto 8080 abierto en el host, lo que le permite establecer la marca de la manera que se indica a continuación:

--publish 8080:80

Cualquier cliente que navegue a la dirección IP del host de Docker y al puerto 8080 puede acceder al portal de seguimiento.

Aparte de las configuraciones específicas de Linux, la red NAT en los hosts de Windows funciona igual que una red de puente. Además, NAT es la red predeterminada en Windows y todos los contenedores se conectarán a ella, a menos que se especifique lo contrario.

¿Qué es la red de host?

La red de host le permite ejecutar el contenedor directamente en esta red. Esta configuración elimina eficazmente el aislamiento entre el host y el contenedor en un nivel de red.

En este ejemplo, supongamos que decide cambiar la configuración de red a la opción "red de host". El portal de seguimiento sigue siendo accesible mediante la dirección IP del host. Ahora ya puede usar el puerto 80, en lugar de un puerto asignado.

Tenga en cuenta que el contenedor solo puede usar los puertos que no usa el host.

En Windows, la red host no está disponible. En los hosts de Windows, no hay opción de compartir la misma dirección IP (pila de redes) entre el host y el contenedor. La red NAT funciona de manera muy similar a una red de puente y la opción de superposición proporciona una dirección IP al contenedor desde la misma red que el host, pero no la misma dirección IP.

Superposición y otras opciones de red

En escenarios más avanzados, tanto Linux como Windows proporcionan otras opciones de red. Por ejemplo, la opción de superposición crea un conmutador virtual desde la red de host para que los contenedores de esa red puedan obtener direcciones IP de los servidores DHCP, o bien operar con direcciones IP de ese segmento de red. Además, Docker permite que los proveedores de terceros creen complementos de red.

¿Qué es la configuración de red "ninguna"?

Para deshabilitar las redes para los contenedores, use la opción de red ninguna. Esto puede resultar útil si tiene una aplicación que no usa la red o si simplemente quiere validar que una aplicación se ejecute según lo previsto en un contenedor.

Consideraciones del sistema operativo

Tenga en cuenta que existen varias diferencias entre los sistemas operativos de escritorio para las opciones de configuración de red de Docker. Por ejemplo, la interfaz de red de Docker0 no está disponible en macOS cuando se usa la red de puente, y el uso de la configuración de red de host no es compatible con los escritorios de Windows y macOS.

Estas diferencias pueden afectar a la forma en que los desarrolladores configuran su flujo de trabajo para administrar el desarrollo de los contenedores. Además, los orquestadores de contenedores también pueden proporcionar otras configuraciones de red, además de la configuración de Docker.

Comprobación de conocimientos

1.

Un contenedor se inicia mediante la marca "--publish 8080:80". ¿Cuál de las siguientes opciones es más probable que sea la configuración de red del contenedor?

2.

¿Cuál es la mejor opción de almacenamiento que permite que el host y el contenedor compartan un archivo para administrar la resolución del servidor de nombres (por ejemplo, el archivo resolve.conf en Linux)?