containerd: el runtime que sustenta a Kubernetes

Contenedores de transporte alineados representando contenedores software

containerd es probablemente el runtime de contenedores más usado del planeta y al mismo tiempo el menos conocido. Cuando Kubernetes 1.20 anunció el deprecation del Docker shim, miles de clusters migraron silenciosamente a containerd como runtime — y la mayoría de operadores no lo notaron porque, bien hecho, debe ser invisible. Cubrimos qué es exactamente, cómo encaja con Docker y Kubernetes, y los comandos básicos para operarlo directamente.

Qué es containerd, qué no es

containerd es un runtime de contenedores de alto nivel — gestiona el ciclo de vida completo de los contenedores en un sistema:

  • Pull de imágenes desde registros.
  • Almacenamiento de imágenes en disco.
  • Creación de contenedores a partir de imágenes.
  • Ejecución, pausa, parada de contenedores.
  • Gestión de network namespaces.
  • Snapshots del filesystem.

Lo que no hace:

  • Construir imágenes (no tiene Dockerfile).
  • Composición multi-contenedor (no tiene compose).
  • UI o experiencia de desarrollador (es un demonio, no una herramienta interactiva).
  • Orquestación (eso lo hace Kubernetes encima).

Originalmente containerd era parte interna de Docker. En 2017 fue donado a la CNCF y se convirtió en proyecto independiente. En 2019 se graduó como proyecto CNCF.

La arquitectura en capas

Para entender containerd ayuda ver la pila completa de un contenedor en Linux:

Kubernetes (orquestación)
   │
   ▼ vía CRI (Container Runtime Interface)
containerd (runtime alto nivel)
   │
   ▼ vía OCI runtime spec
runc (runtime bajo nivel — o crun, gVisor, kata)
   │
   ▼ namespaces, cgroups, capabilities
Linux kernel
  • Kubernetes orquesta — decide qué pods van dónde.
  • containerd ejecuta — habla CRI con Kubernetes y OCI con runc.
  • runc es la implementación de referencia que crea el contenedor real usando primitivas del kernel.

Esta separación permite intercambiar piezas: puedes cambiar runc por gVisor para más aislamiento, o containerd por CRI-O sin tocar Kubernetes.

containerd vs Docker: relación real

Mucha confusión hay sobre esto. La verdad sencilla:

  • Docker Engine internamente usa containerd como runtime desde hace años.
  • Cuando ejecutas docker run, Docker llama a containerd internamente.
  • En Kubernetes 1.24+, eliminado el “Docker shim” — Kubernetes habla directamente con containerd, sin Docker Engine en medio.
  • Los clusters Kubernetes que dicen “usan Docker” en realidad casi todos usaban containerd debajo. La migración fue cambiar la capa de adaptación.

Para servidores standalone, Docker Engine sigue siendo válido — es Docker + containerd + herramientas adicionales. Para Kubernetes, containerd directo elimina una capa innecesaria.

containerd vs CRI-O

CRI-O es la alternativa principal — un runtime ligero diseñado específicamente para Kubernetes. Diferencias prácticas:

  • containerd es de propósito más general, usado fuera de Kubernetes (Docker, dev environments).
  • CRI-O está hecho exclusivamente para Kubernetes, sin features extras.
  • Ambos cumplen CRI y OCI. Performance es comparable.
  • containerd tiene más adopción global; CRI-O es estándar en distribuciones tipo OpenShift de Red Hat.

Elegir entre ambos es más cuestión de ecosistema y soporte que de capacidades técnicas en 2023.

Trabajar con containerd directamente

Cuando algo va mal en un nodo Kubernetes, conviene saber moverte fuera de kubectl. Dos herramientas para hablar con containerd directamente:

ctr — la CLI básica

Viene con containerd. Útil pero no muy amigable:

# Listar imágenes
sudo ctr -n k8s.io images list

# Listar contenedores en el namespace de Kubernetes
sudo ctr -n k8s.io containers list

# Ver tasks (procesos contenedor activos)
sudo ctr -n k8s.io tasks list

# Sacar logs de un contenedor (usar journalctl o crictl en su lugar)

El -n k8s.io es el namespace que usa Kubernetes; sin él no ves los pods.

crictl — la herramienta oficial para Kubernetes

Más útil en clusters Kubernetes:

# Listar pods
sudo crictl pods

# Listar contenedores
sudo crictl ps

# Logs de un contenedor
sudo crictl logs <container-id>

# Ejecutar comando dentro
sudo crictl exec -it <container-id> sh

# Inspeccionar imagen
sudo crictl inspecti <image>

Configuración en /etc/crictl.yaml:

runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock

nerdctl — sintaxis Docker para containerd

Si echas de menos docker run y compañía, nerdctl es API-compatible con Docker pero habla con containerd directamente:

sudo nerdctl run -d -p 80:80 nginx
sudo nerdctl ps
sudo nerdctl exec -it <id> sh

Para developers que vienen de Docker, es la transición más cómoda.

Casos donde tocar containerd directamente

En operación día a día con Kubernetes, normalmente no tocas containerd. Donde sí ayuda:

  • Debug de pods que no arrancan. Logs de containerd en journalctl -u containerd muchas veces tienen detalle que kubelet no propaga.
  • Limpieza de imágenes huérfanas. crictl rmi --prune libera espacio cuando GC de Kubernetes va lento.
  • Problemas de pull de imagen. crictl pull directamente revela problemas de credenciales o red sin pasar por la abstracción de Kubernetes.
  • Verificar runtime activo. kubectl get nodes -o wide muestra el runtime; auditarlo es 30 segundos.

Configuración relevante

El config principal vive en /etc/containerd/config.toml. Cambios típicos:

  • Mirror de registry (acelera y reduce uso de Docker Hub).
  • Configurar runtime distinto (gVisor para más aislamiento en multi-tenancy).
  • Plugin de logs y rotación.
  • systemd cgroup driver (debe coincidir con kubelet — error común al instalar).

Cambios requieren systemctl restart containerd y, en clusters productivos, hacerlo nodo por nodo con cordon/drain.

Conclusión

containerd es la pieza fundamental sobre la que corren la mayoría de Kubernetes modernos. Conocer su arquitectura ayuda a debugging, decisiones de runtime alternativo y entendimiento de qué hace tu cluster. Para operación diaria, sigue siendo una capa que normalmente no tocas — pero saber moverte cuando hace falta convierte un problema de horas en uno de minutos.

Síguenos en jacar.es para más sobre Kubernetes, runtimes de contenedores y operación de clusters.

Entradas relacionadas