Una caja que engaña
Un contenedor no es una máquina virtual: es un proceso al que el kernel le esconde el resto. Al terminar sabrás armar uno a mano.
Primero, la idea completa
Mira el video entero o salta a la parte que quieras repasar. Después, cada idea tiene su propia escena para tocarla.
Paquetes y gestores de paquetes
Así como hay cadenas de suministro de alimentos, hay cadenas de suministro de software. Entenderlas importa para la calidad y la seguridad de lo que instalas. Tienen tres actores:
- Mantenedores: personas, proyectos de código abierto y empresas que producen el software y lo publican.
- Repositorio: lista los paquetes con sus metadatos. Cada paquete declara sus dependencias, otros paquetes que necesita para funcionar, como bibliotecas o programas de servicio. Mantenerlas al día es difícil.
- Gestor de paquetes: en tu máquina, busca en el repositorio e instala, actualiza o elimina, con las dependencias incluidas. Guarda una caché local de paquetes.
Un paquete es un archivo, normalmente comprimido, con los programas y sus metadatos. Hay dos grandes familias:
| Familia | Formato | Herramientas |
|---|---|---|
| Red Hat (RHEL, Fedora, CentOS) | .rpm | yum, dnf; zypper en openSUSE |
| Debian (Debian, Ubuntu) | .deb | dpkg (bajo nivel); apt, apt-get, aptitude (alto nivel) |
Los lenguajes también traen los suyos: pip en Python, npm en Node.js, cargo en Rust, maven en Java, go mod en Go, rubygems en Ruby, y Conan o vcpkg en C/C++.
Pide un paquete y mira qué calcula el gestor: qué dependencias faltan y en qué orden se instalan.
Namespaces
En Linux, los procesos tienen una vista global de los recursos: todos ven los mismos procesos, el mismo nombre de máquina, la misma red. Los namespaces le dan a un grupo de procesos una vista propia. Se centran en la visibilidad: aíslan lo que un proceso ve, lo que no equivale a un límite rígido de seguridad.
Tres llamadas al sistema los manejan:
clone: crea un proceso hijo que comparte con el padre solo las partes que se le indiquen.unshare: hace que un proceso que ya existe deje de compartir alguna parte.setns: une un proceso a un namespace que ya existe.
ampliación Hay uno por recurso: pid (números de proceso), uts (nombre de máquina), net (red), mnt (montajes), ipc, user y cgroup. Los de cada proceso aparecen en /proc/ID/ns.
Abre una shell nueva dejando de compartir los namespaces que elijas. Compara lo que ve con lo que ve el anfitrión.
cgroups
Los cgroups (grupos de control) son el mecanismo del kernel para limitar, priorizar y aislar recursos como CPU, memoria y dispositivos entre procesos o grupos de procesos. Los namespaces deciden qué se ve; los cgroups, cuánto se usa.
Hay dos versiones. En la v1 se fueron agregando grupos y controladores según hacía falta. La v2 es una reescritura completa, más simple y con mejor control y aislamiento; ya es la de fábrica en Ubuntu desde 21.10, en Fedora desde 31 y en Arch.
ampliación En la v2 cada grupo es una carpeta en /sys/fs/cgroup: se crea con mkdir, el límite se escribe en memory.max y un proceso entra al grupo escribiendo su PID en cgroup.procs. Si el grupo pasa su límite de memoria, el kernel mata a un proceso del grupo y no a cualquiera de la máquina.
Un programa necesita 200 MB. Ponle un límite de memoria a su grupo y ejecútalo.
Contenedores
Un contenedor es una unidad de software que encierra el código con todas sus dependencias, para que corra igual en cualquier entorno: desde pruebas en tu máquina hasta microservicios en Kubernetes. Por dentro no hay nada nuevo: es un grupo de procesos de Linux con namespaces, cgroups y, opcionalmente, un sistema de archivos de copia en escritura.
Tampoco es una idea nueva: antes hubo Linux-VServer (2001), OpenVZ (2005), LXC (2008) y lmctfy (2013). Fue Docker quien los popularizó en 2014, con una interfaz fácil para namespaces y cgroups y una forma estándar de empaquetar y distribuir imágenes.
La Open Container Initiative (OCI) define tres especificaciones: la de ejecución (operaciones y ciclo de vida), la de formato de imagen (metadatos y capas) y la de distribución (cómo se envían las imágenes desde los repositorios).
No hace falta Docker para usar contenedores OCI: buildah construye imágenes y podman las ejecuta, sin demonio. containerd es un demonio que administra todo el ciclo de vida, desde descargar imágenes hasta vigilar la ejecución.
Antes de leer la respuesta
Tu turno: un contenedor a mano
Arma un contenedor a mano, pieza por pieza: instala un programa con sus dependencias, abre una shell que solo ve sus propios procesos, cámbiale el nombre a la máquina sin afectar al anfitrión y ponle un límite de memoria que el kernel haga cumplir.
Comprueba lo que entendiste
Cada respuesta incorrecta explica por qué parece correcta y en qué falla.