Blog

Logrando el verdadero aislamiento multiinquilino en Docker

El modelo de kernel compartido de Docker introduce riesgos para entornos multiinquilino. Esta guía proporciona pasos concretos para fortalecer el aislamiento utilizando espacios de nombres de usuario, seccomp, AppArmor, herramientas de sandboxing y mejores prácticas de orquestación.

Resumen

Los contenedores Docker comparten el kernel del host, lo que puede ser un problema de seguridad para entornos multiinquilino donde los inquilinos pueden no confiar entre sí. Este artículo explica las brechas de aislamiento en las configuraciones predeterminadas de Docker y proporciona pasos concretos para fortalecer el aislamiento utilizando espacios de nombres de Linux, cgroups, espacios de nombres de usuario, seccomp, AppArmor y virtualización de hardware. Aprenderá cómo configurar demonios Docker por inquilino, usar herramientas de sandboxing como gVisor o Firecracker para un aislamiento más fuerte y orquestar con Kubernetes para multiinquilino. También cubriremos cómo seleccionar el proveedor de infraestructura adecuado que ofrezca virtualización basada en KVM para una capa adicional de separación. Al final, tendrá un plan para ejecutar cargas de trabajo multiinquilino seguras con Docker.

Al alojar múltiples inquilinos en un solo host Docker, el aislamiento predeterminado de contenedores —basado en espacios de nombres de Linux y cgroups— a menudo no es suficiente. Un escape de contenedor en un inquilino podría comprometer todo el host y todos los demás contenedores. Este problema es especialmente agudo en alojamiento compartido, plataformas SaaS o cualquier escenario donde se ejecute código no confiable junto con el suyo propio. La buena noticia: puede apilar múltiples técnicas de aislamiento para construir un entorno multiinquilino endurecido. Esta guía recorre seis pasos prácticos, desde frutas maduras como los espacios de nombres de usuario hasta medidas avanzadas como tiempos de ejecución en sandbox y opciones de infraestructura.

Comprendiendo el aislamiento predeterminado de Docker

Docker utiliza espacios de nombres de Linux para aislar procesos, red, sistema de archivos y otros recursos. Cgroups limita CPU, memoria y E/S. Pero estos comparten un solo kernel: una vulnerabilidad en el kernel puede afectar a todos los contenedores. Para un verdadero multiinquilino, especialmente con inquilinos no confiables, necesita defensa en profundidad. Como se discute en Diseñando una arquitectura Docker multiinquilino: eligiendo el nivel de aislamiento adecuado, los niveles de aislamiento van desde débil (solo espacios de nombres) hasta fuerte (virtualizado por hardware). Construyamos desde el más débil.

Paso 1: Habilitar espacios de nombres de usuario

Por defecto, root dentro de un contenedor se mapea a root en el host. Un escape de contenedor da acceso completo al host. Los espacios de nombres de usuario reasignan root del contenedor a un usuario no root fuera. Actívelo globalmente con dockerd --userns-remap=default o por contenedor con --userns=host. Este simple paso elimina muchos ataques de escalada de privilegios. Pruebe sus aplicaciones: algunas que requieren privilegios a nivel de host (por ejemplo, montar sistemas de archivos) podrían fallar. Para sitios Drupal o WordPress, suele ser seguro.

Paso 2: Aplicar perfiles Seccomp y AppArmor

Seccomp limita las llamadas al sistema que un contenedor puede hacer. Docker incluye un perfil seccomp predeterminado que bloquea syscalls peligrosas como mount y reboot. Para multiinquilino, ajústelo más: bloquee syscalls poco comunes que utilizan las herramientas de escape. De manera similar, AppArmor puede confinar procesos de contenedores. Cree un perfil AppArmor personalizado que deniegue acceso de escritura a interfaces del kernel y restrinja rutas de archivos. Ambos se configuran mediante banderas --security-opt. Combínelos para una defensa en capas.

Paso 3: Usar demonios Docker por inquilino

Ejecutar un solo demonio Docker para todos los inquilinos es arriesgado: cualquier escape de contenedor podría acceder al socket del demonio. Aísle demonios por inquilino usando Docker-en-Docker (DinD) o puntos finales de demonio remotos. Por ejemplo, inicie un demonio Docker dentro de un contenedor con --privileged (pero eso debilita el aislamiento). Un mejor enfoque: ejecutar demonios separados en VMs separadas o usar la función experimental --group de Docker con espacios de nombres de usuario. Para orquestación, el aislamiento basado en espacios de nombres de Kubernetes es más práctico, como se cubre en Defendiendo contra escapes de contenedores: una guía práctica de aislamiento Docker para alojamiento multiinquilino.

Paso 4: Considerar tiempos de ejecución en sandbox

Cuando el propio kernel de Linux no es confiable, use un tiempo de ejecución en sandbox que agregue una capa de VM ligera. gVisor (runsc) intercepta syscalls e implementa su propio kernel, mientras que Firecracker usa micro-VMs con virtualización de hardware. Ambos se integran con Docker a través de tiempos de ejecución de containerd. Por ejemplo, agregue "runtimes": {"runsc": {}} a la configuración del demonio Docker y ejecute contenedores con --runtime=runsc. La sobrecarga de rendimiento es del 5–15% pero el aislamiento es mucho más fuerte. Ideal para configuraciones multiinquilino de alta seguridad.

Paso 5: Orquestar con Kubernetes y políticas de seguridad

Kubernetes proporciona multiinquilino nativo a través de espacios de nombres, Estándares de Seguridad de Pods y NetworkPolicies. Defina espacios de nombres por inquilino con cuotas de recursos y aplique contextos de seguridad de pods restringidos (eliminar todas las capacidades, sistema de archivos raíz de solo lectura). Los controladores de admisión como OPA/Gatekeeper pueden bloquear configuraciones incorrectas. Si gestiona muchos inquilinos, Kubernetes automatiza la aplicación del aislamiento. Para orquestación a escala de producción, consulte Más allá de Docker Compose: orquestando aplicaciones contenerizadas listas para producción.

Paso 6: Elegir el proveedor de alojamiento adecuado

El hipervisor de su proveedor de infraestructura importa. Docker en alojamiento compartido (OpenVZ) proporciona un aislamiento débil: un inquilino puede ver otros procesos. Prefiera proveedores que usen KVM o VMware, que ofrecen separación a nivel de hardware. Proveedores como DigitalOcean, Kamatera o AWS ofrecen VPS basados en KVM con recursos dedicados. Para bare-metal, asegúrese de que la virtualización a nivel BIOS esté habilitada para contenedores anidados. Un proveedor que aísle inquilinos en la capa de hipervisor complementa su aislamiento de contenedores. Como se detalla en Dominando el aislamiento Docker para alojamiento web seguro y eficiente, el sistema operativo host también debe endurecerse con una superficie de ataque mínima.

Advertencias y compensaciones

Cada capa adicional agrega complejidad y costo de rendimiento. Los espacios de nombres de usuario pueden romper volúmenes montados en el host. Los perfiles Seccomp requieren ajustes por aplicación. Los tiempos de ejecución en sandbox como gVisor no soportan todas las syscalls: su aplicación podría no funcionar. Los demonios Docker por inquilino aumentan la sobrecarga de memoria. Elija el nivel de aislamiento que coincida con su modelo de amenazas: para inquilinos confiables, los espacios de nombres predeterminados pueden ser suficientes; para SaaS público, invierta en sandboxes de tiempo de ejecución y políticas de Kubernetes. Pruebe a fondo antes de producción.

Conclusión

El verdadero aislamiento multiinquilino en Docker es alcanzable apilando múltiples características del kernel, sandboxes de tiempo de ejecución y controles de orquestación. Comience con espacios de nombres de usuario y seccomp, luego pase a demonios por inquilino o tiempos de ejecución en sandbox. Para gran escala, Kubernetes proporciona aislamiento basado en políticas. Siempre acompáñelo con un host separado a nivel de hipervisor de un proveedor de confianza. Ninguna técnica es infalible por sí sola, pero combinarlas crea una defensa robusta. Sus inquilinos se lo agradecerán, y también su auditoría de seguridad.

Sources (5)