Las herramientas CLI de containerd: ctr, nerdctl y crictl
Tres herramientas de línea de comandos, tres trabajos distintos: cuál usar y cuándo.
Cuando Docker deja de ser lo que ejecuta los contenedores en un nodo, docker ps y docker logs dejan de funcionar allí. Tres herramientas llenan ese vacío, creadas por dos comunidades distintas con dos propósitos distintos. Usar la equivocada es la fuente más común de confusión al solucionar problemas directamente en un nodo.
Las tres herramientas de un vistazo
| Herramienta | Creada por | Se comunica con | Propósito | ¿Similar a Docker? |
|---|---|---|---|---|
ctr | Proyecto containerd | containerd directamente | Depurar containerd en sí | No, mínima y de bajo nivel |
nerdctl | Proyecto containerd | containerd directamente | Gestión general de contenedores | Sí, imita de cerca a docker |
crictl | Proyecto Kubernetes | Cualquier runtime compatible con CRI | Depurar el runtime desde la perspectiva de Kubernetes | Parcialmente, entiende Pods |
ctr: incluida, mínima, solo para depuración
ctr se distribuye con el propio containerd, lo que hace que esté siempre disponible dondequiera que esté containerd, pero es explícitamente una herramienta de depuración con un conjunto de funciones deliberadamente pequeño, no algo pensado para la gestión diaria de contenedores:
ctr images pull docker.io/library/redis:7
ctr run docker.io/library/redis:7 my-redis
ctr containers list
El propio proyecto containerd recomienda no usar ctr para nada más allá de depurar e inspeccionar el estado interno de containerd. Si te encuentras intentando automatizar despliegues con ella con scripts, es una señal para pasar a nerdctl.
nerdctl: el día a día, al estilo Docker
nerdctl es una CLI independiente, también del proyecto containerd, diseñada para parecerse y comportarse como la CLI de docker lo bastante como para que la mayoría de los comandos de docker funcionen sustituyendo el nombre del binario:
nerdctl run -d -p 8080:80 nginx:1.25
nerdctl ps
nerdctl logs my-container
nerdctl build -t myapp:latest .
Además de la paridad con los flujos de trabajo habituales de Docker, nerdctl expone capacidades nativas de containerd que Docker no tiene: imágenes cifradas, lazy pulling, distribución de imágenes P2P, firma y verificación de imágenes, e interacción directa con los namespaces de Kubernetes en el propio modelo de datos de containerd. Para el trabajo general con contenedores en una máquina con containerd instalado pero sin Docker, nerdctl es la herramienta a la que recurrir.
crictl: desde el punto de vista de Kubernetes
crictl la mantiene el propio proyecto Kubernetes, no el de containerd, y habla CRI, la misma interfaz que usa el kubelet, en lugar de la API nativa de containerd. Eso significa que funciona igual con containerd, CRI-O o cualquier otro runtime compatible con CRI, y entiende conceptos de Kubernetes que ctr y nerdctl no entienden, sobre todo los Pods, no solo los contenedores:
crictl images
crictl ps
crictl pods
crictl exec -it CONTAINER_ID sh
crictl logs CONTAINER_ID
Fíjate en crictl pods: ni ctr, ni nerdctl, ni Docker antes que ellos tenían un concepto nativo de Pod, un grupo de contenedores que comparten red y almacenamiento. Eso es específico de Kubernetes, y crictl es la herramienta creada para razonar sobre ello directamente.
crictl, como ctr, está pensada para inspección y depuración, no para crear cargas de trabajo. Si la usas para iniciar un contenedor que Kubernetes no conoce, el kubelet no tiene registro de él y lo eliminará en cuanto lo detecte, ya que para Kubernetes un contenedor inesperado en un nodo es una desviación que corregir, no una carga de trabajo que preservar.
A qué endpoint se conecta crictl
Como crictl funciona con distintos runtimes, necesita saber a cuál conectarse. Sin configuración, prueba una lista fija de sockets por defecto en orden (históricamente el de dockershim, luego el de containerd, luego el de CRI-O, luego otros). En un nodo moderno esta ambigüedad rara vez importa porque solo hay un runtime instalado, pero en un nodo con más de uno, o al solucionar un problema con la ruta de un socket, defínelo explícitamente:
crictl --runtime-endpoint unix:///run/containerd/containerd.sock ps
# o
export CONTAINER_RUNTIME_ENDPOINT=unix:///run/containerd/containerd.sock
Cómo elegir entre ellas
- Inspeccionar o solucionar problemas de lo que ve el propio Kubernetes, contrastar lo que reporta
kubectl describe podcon lo que realmente se está ejecutando en el nodo: usacrictl. - Trabajo general con contenedores en un nodo o en desarrollo local, ejecutar algo rápidamente, construir una imagen, revisar logs: usa
nerdctl. - Depurar el estado interno de containerd, algo específico de containerd y no de la vista CRI independiente del runtime: recurre a
ctr, y espera necesitar la documentación de containerd abierta a su lado.
Guías populares
-
De Docker a containerd: una breve historia de los runtimes de Kubernetes Por qué Kubernetes dejó de hablar directamente con Docker y qué es realmente containerd en relación con él. -
Internos del runtime: cgroups, runc y dónde encaja containerd Qué aísla y limita realmente a un contenedor, desde la función del kernel hasta el daemon con el que habla Kubernetes.