Por dentro del motor: entendiendo la arquitectura de Docker

La primera vez que ejecuté docker run funcionó. Pero cuando algo falló, no tenía idea de dónde buscar. No entendía quién hacía qué, cómo se comunicaban las piezas ni por qué a veces el daemon parecía tener vida propia. Este artículo es lo que me hubiera gustado leer antes de ese momento.

Docker no es un solo programa: es un sistema de piezas

Uno de los errores conceptuales más comunes cuando arrancás con Docker es pensarlo como «el comando que corre contenedores». En realidad, Docker es una arquitectura cliente-servidor compuesta por varios componentes que trabajan juntos. Entenderlos hace que todo lo demás tenga sentido.

El flujo completo en un diagrama

┌─────────────────────────────────────────────────────────────┐
│                        TU TERMINAL                          │
│                                                             │
│   $ docker run nginx        ← Docker Client (CLI)          │
└──────────────────┬──────────────────────────────────────────┘
                   │  REST API (Unix socket o TCP)
                   ▼
┌─────────────────────────────────────────────────────────────┐
│                    DOCKER DAEMON (dockerd)                   │
│                                                             │
│   • Escucha comandos del cliente                            │
│   • Administra imágenes, contenedores, redes, volúmenes     │
│   • Delega la ejecución a containerd                        │
└──────────┬─────────────────────────┬────────────────────────┘
           │                         │
           ▼                         ▼
┌──────────────────┐      ┌──────────────────────────────────┐
│   containerd     │      │         Docker Registry           │
│                  │      │   (Docker Hub / privado)          │
│  • Gestiona      │      │                                   │
│    ciclo de vida │      │  • Almacena imágenes              │
│    del contenedor│      │  • docker pull baja de acá        │
│  • Usa runc para │      │  • docker push sube acá           │
│    crear procesos│      └──────────────────────────────────┘
└──────────────────┘

Docker Engine: el corazón del sistema

El Docker Engine es el conjunto completo: client + daemon + la API REST que los conecta. Cuando instalás Docker en un servidor, lo que instalás es el Engine. En mis nodos SUSE Linux, el daemon corre como servicio systemd y arranca automáticamente con el sistema.

# Ver estado del daemon
sudo systemctl status docker

# Ver logs del daemon en tiempo real
sudo journalctl -u docker -f

# Información completa del sistema Docker
docker info

Docker Client: lo que escribís en la terminal

El cliente es simplemente la CLI: el binario docker que usás en la terminal. Su único trabajo es traducir tus comandos a llamadas a la API REST del daemon. Lo que importa saber: el cliente y el daemon pueden estar en máquinas diferentes. Puedo controlar el daemon de un servidor remoto desde mi notebook sin ningún problema.

# Conectar el cliente a un daemon remoto
export DOCKER_HOST=tcp://192.168.1.100:2376
docker ps  # Lista contenedores del servidor remoto

# O con contextos (la forma moderna)
docker context create servidor-prod --docker "host=ssh://mbernal@192.168.1.100"
docker context use servidor-prod
docker ps  # Ahora habla con el servidor remoto

Docker Daemon (dockerd): quien realmente hace el trabajo

El daemon es el proceso que corre en background y gestiona todo: imágenes, contenedores, redes y volúmenes. Cuando ejecutás docker run nginx, es el daemon quien:

  1. Recibe el comando del cliente
  2. Verifica si la imagen nginx existe localmente
  3. Si no existe, la descarga del registry
  4. Crea el contenedor usando containerd y runc
  5. Configura la red y el sistema de archivos
  6. Arranca el proceso principal del contenedor

Imágenes Docker: plantillas inmutables

Una imagen es una plantilla de solo lectura que define el sistema de archivos y la configuración inicial de un contenedor. Está compuesta por capas (layers), donde cada instrucción del Dockerfile agrega una capa nueva. Esta arquitectura por capas es brillante: si dos imágenes comparten las mismas capas base, se almacenan una sola vez en disco.

# Ver imágenes locales
docker images

# Ver las capas de una imagen
docker history nginx:latest

# Inspeccionar metadatos completos
docker inspect nginx:latest

Contenedores: instancias en ejecución de una imagen

Un contenedor es una imagen en ejecución. La diferencia clave: la imagen es inmutable (solo lectura), mientras que el contenedor agrega una capa de escritura encima donde los procesos pueden crear y modificar archivos. Cuando el contenedor se destruye, esa capa desaparece. Por eso los datos importantes van en volúmenes — pero eso lo vemos en otro artículo.

# Relación imagen → contenedor
docker images ls          # ver imágenes (plantillas)
docker ps -a              # ver contenedores (instancias)

# Crear contenedor sin arrancarlo
docker create --name mi-nginx nginx

# Arrancarlo
docker start mi-nginx

# O directamente: crear + arrancar
docker run -d --name mi-nginx -p 80:80 nginx

Docker Registry: el repositorio de imágenes

El registry es donde viven las imágenes. Docker Hub es el registry público por defecto, pero en producción muchas empresas usan registries privados. En mi entorno on-premise uso un registry privado para no depender de internet en los deploys.

# Levantar un registry privado local
docker run -d -p 5000:5000 --name registry-privado   -v /data/registry:/var/lib/registry   registry:2

# Tagear imagen para el registry privado
docker tag mi-api:latest localhost:5000/mi-api:latest

# Subir al registry privado
docker push localhost:5000/mi-api:latest

# Bajar desde el registry privado
docker pull localhost:5000/mi-api:latest

Docker Compose: orquestación local

Docker Compose es la herramienta para definir y ejecutar aplicaciones multi-contenedor. En lugar de ejecutar múltiples docker run, definís todos los servicios en un archivo YAML y los gestionás con un solo comando. Lo veremos en profundidad más adelante — te adelanto que cambia completamente la forma de trabajar.

El flujo completo: qué pasa cuando ejecutás docker pull nginx

# Esto es lo que pasa internamente:
$ docker pull nginx

# 1. Docker Client envía petición al daemon via /var/run/docker.sock
# 2. Daemon consulta: ¿tengo nginx:latest localmente?
# 3. Si no → contacta Docker Hub (registry.hub.docker.com)
# 4. Autentica (si la imagen es privada)
# 5. Descarga cada capa (layer) que no tenga en cache
# 6. Verifica integridad con el digest SHA256
# 7. Almacena las capas en /var/lib/docker/overlay2/

Using default tag: latest
latest: Pulling from library/nginx
a803e7c4b030: Pull complete   ← cada línea es una capa
8b625c47d697: Pull complete
4d3239651a63: Pull complete
Digest: sha256:bc5eac5eafc581aeda3008b4b1f07ebba230de2f27d47767129a6a905c84f470
Status: Downloaded newer image for nginx:latest

Por qué me importa entender esto

El día que tuve un contenedor que no arrancaba y no sabía por dónde empezar a debuggear, entender la arquitectura me salvó. Saber que el daemon escribe en /var/lib/docker/, que los logs del daemon están en journalctl, que el socket Unix es /var/run/docker.sock — esos detalles marcan la diferencia entre resolver el problema en 5 minutos o perder una hora.

# Cuando algo falla, estos son mis primeros comandos:
sudo journalctl -u docker --since "1 hour ago"
docker info
docker system df          # ver uso de disco
docker system events      # stream de eventos del daemon

Artículo anterior: Cómo Docker cambió la forma en que trabajo | Serie Docker Completo | Próximo: Mi guía para escribir Dockerfiles →


Artículo anterior: Cómo Docker cambió la forma en que trabajo (y por qué tardé en entenderlo) | Serie Docker Completo | Próximo: Mi guía para escribir Dockerfiles que no me den vergüenza →

0 comentarios

Dejar un comentario

¿Quieres unirte a la conversación?
Siéntete libre de contribuir!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.