Los contenedores comparten el kernel del anfitrión. Esa propiedad explica buena parte de su ligereza y también marca su techo en entornos multi-tenant donde la confianza entre cargas es baja.

Google creó gVisor para resolver ese techo. Interpone un kernel escrito en Go entre el proceso del contenedor y el kernel real del anfitrión. Así reduce la superficie de llamadas al sistema expuesta y ofrece un aislamiento intermedio entre el contenedor tradicional y la máquina virtual ligera.

Puntos clave

  • gVisor implementa el runtime runsc, compatible con OCI, que sustituye a runc interponiendo un kernel en espacio de usuario llamado Sentry.

  • El modo systrap, publicado en 2023 y convertido en opción por defecto ese mismo año, es la recomendada hoy: buen rendimiento, portable, sin requisitos especiales de hardware.

  • Para cargas de CPU el coste suele quedarse en un dígito bajo. Para cargas intensivas en llamadas al sistema (Redis, bases de datos con escritura constante), el impacto medido en bancos de pruebas independientes va del 50 % a más del 100 %.

  • Integrar gVisor en un clúster Kubernetes existente requiere instalar runsc y declarar una RuntimeClass; el resto de pods siguen con runc.

  • Tiene sentido para cargas multi-tenant, funciones serverless y ejecución de código de terceros; no para bases de datos pesadas o cargas con alto IOPS.

Qué es gVisor y por qué se construyó

gVisor implementa un runtime compatible con OCI llamado runsc que sustituye a runc. La diferencia decisiva es que runsc no deja al proceso del contenedor hablar con el kernel del anfitrión directamente. En su lugar, un componente llamado Sentry intercepta esas llamadas y responde a la mayoría por sí mismo. Sentry es un kernel de Linux reimplementado en Go en espacio de usuario, y habla con el anfitrión solo cuando no queda otra opción, siempre a través de un perímetro acotado.

El resultado es que un exploit del kernel que en un contenedor normal escalaría al anfitrión tiene que atravesar primero la implementación de Sentry. Esa implementación es mucho más pequeña y está escrita en un lenguaje con seguridad de memoria. Google abrió el código en 2018[1] y lo usa en producción para ejecutar código de clientes en App Engine, Cloud Run y Cloud Functions.

Arquitectura: Sentry, Gofer y modos de plataforma

Cuando un contenedor arranca con runsc, el runtime crea dos procesos principales en el anfitrión:

  • Sentry: el kernel en espacio de usuario que ejecuta el código del contenedor.

  • Gofer: proceso separado que actúa como intermediario para el acceso al sistema de archivos.

Esta separación es deliberada: incluso si un atacante compromete Sentry, todavía tiene que atravesar Gofer para tocar el disco, y ninguno de los dos tiene capacidades privilegiadas más allá de lo estrictamente necesario.

La intercepción de llamadas al sistema usa dos modos principales:

  • ptrace: portable pero lento, rara vez usado en producción.

  • KVM: aprovecha las extensiones de virtualización del hardware y rinde mejor que ptrace, pero requiere /dev/kvm.

  • systrap (la plataforma por defecto desde su lanzamiento en 2023[2]): usa seccomp con filtros de notificación para interceptar llamadas sin depender de KVM ni de ptrace. Buen rendimiento, portable y sin requisitos especiales de hardware.

Un detalle importante: Sentry no implementa todas las llamadas al sistema de Linux. Cubre lo que necesita un programa típico, pero hay llamadas oscuras que fallarán si el contenedor intenta usarlas. Esto es deliberado: cada llamada implementada es superficie de ataque potencial.

Rendimiento: dónde gana y dónde pierde

Para cargas con uso intenso de CPU y poco contacto con el kernel, gVisor está cerca de un contenedor nativo. La propia guía de rendimiento del proyecto[3] explica que no hay coste añadido en la ejecución bruta de instrucciones, porque Sentry no emula la CPU. Un banco de pruebas independiente de KubeBlocks[4] con Sysbench midió un sobrecoste de apenas un 4 % frente a runc, prácticamente igual que Kata.

La historia cambia con cargas intensivas en llamadas al sistema:

  • El mismo banco de KubeBlocks midió entre un 56 % (plataforma KVM) y un 95 % (plataforma ptrace) de degradación en operaciones de Redis. En un banco de inserciones de SQLite midió un 125 % de sobrecoste, frente a un 17 % en Kata.

  • La red también tiene impacto: gVisor trae su propia pila TCP en Go (netstack). Su propia documentación[3] reconoce que los servicios web sencillos, con poco trabajo por petición, notan más el sobrecoste que las cargas que hacen bastante cómputo entre llamadas.

La lección operativa: gVisor es buena opción para APIs HTTP con trabajo real por petición, funciones serverless, trabajos por lotes y ejecución de código no confiable. Es mala opción para bases de datos con escritura constante o para servir archivos estáticos pequeños a alta tasa de peticiones. También para cualquier carga cuya métrica principal sea IOPS o llamadas al sistema por segundo.

Comparación con Kata Containers y microVMs

La comparación obvia es con Kata Containers[5], que también busca aislamiento reforzado pero arrancando una máquina virtual pequeña con Firecracker o QEMU. Los modelos de amenaza son distintos:

  • Kata apuesta por la barrera de hardware del hipervisor.

  • gVisor apuesta por la reducción de superficie en espacio de usuario.

Kata tiende a mejor compatibilidad con cargas de E/S intensiva porque dentro de la VM corre un kernel Linux completo. En cambio, gVisor tiende a arrancar más rápido y consumir menos memoria fija por contenedor porque no hay hipervisor completo que cargar. En Cloud Run, donde el arranque en frío importa, la elección de gVisor tiene sentido.

Firecracker por sí solo es un ladrillo de construcción distinto: el modelo de amenaza es fuerte por la separación de hipervisor. Operar Firecracker puro implica mucha más integración con el orquestador que runsc, que se enchufa en containerd con pocas líneas de configuración.

Operación y despliegue

Integrar gVisor en un clúster existente es relativamente sencillo:

# Instalación típica en un nodo Debian
curl -fsSL https://gvisor.dev/archive.key | sudo gpg --dearmor 
  -o /usr/share/keyrings/gvisor-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) 
  signed-by=/usr/share/keyrings/gvisor-archive-keyring.gpg] 
  https://storage.googleapis.com/gvisor/releases release main" 
  | sudo tee /etc/apt/sources.list.d/gvisor.list
sudo apt update && sudo apt install -y runsc
sudo runsc install   # añade runsc a containerd
sudo systemctl restart containerd

Después se declara una RuntimeClass en Kubernetes y los Pods que la referencien arrancan con Sentry y Gofer; el resto sigue con runc. Esto permite aplicar gVisor solo a las cargas que lo necesitan sin imponer su coste a todo el clúster. Este patrón de runtime mixto encaja bien con el modelo de containerd con Wasm, donde el mismo nodo ejecuta runtimes distintos según la carga.

runsc exporta métricas en formato Prometheus con información de CPU y memoria, y los registros se integran con el stack habitual de logs. El diagnóstico cuando algo falla es más complicado que con runc porque los mensajes pueden venir de Sentry, pero la documentación ha mejorado mucho y hay una comunidad activa.

Cuándo compensa

gVisor tiene un sitio claro: cargas multi-tenant donde el aislamiento importa y el patrón de uso es intensivo en CPU y ligero en E/S.

  • Plataformas que ejecutan código de terceros.

  • Funciones serverless.

  • Entornos de pruebas donde usuarios distintos comparten nodos.

  • Clústeres educativos y laboratorios de análisis de malware.

En todos esos casos la reducción de superficie de ataque compensa de largo el pequeño coste de CPU que se pierde. Hay operadores que usan gVisor para una fracción del clúster, Kata para otra y runc para el resto. Eligen la barrera que mejor encaja con el nivel de confianza y el perfil de rendimiento de cada carga. Esta heterogeneidad es la respuesta madura a cómo aislar contenedores en entornos multi-tenant.

Donde no compensa es en cargas propias de una organización que confía en su propio código. Si todos los pods los despliega el mismo equipo con el mismo pipeline, el sandbox extra rara vez justifica el coste operativo. Para esas cargas, las herramientas de observabilidad 2026 y Kubernetes 1.35 ofrecen mejoras de seguridad sin el sobrecoste de sandbox adicional.

Este artículo también está disponible en inglés: gVisor: sandboxing for multi-tenant containers.

Fuentes:

  1. gVisor: guía de arquitectura y rendimiento[3]
  2. gVisor blog: Releasing Systrap, a high-performance platform[2]
  3. Google Cloud Blog: Open-sourcing gVisor, a sandboxed container runtime[1]
  4. KubeBlocks: how containerization affects database performance, benchmark of runC, Kata and gVisor[4]
  5. Kata Containers: sitio oficial del proyecto[5]

Preguntas frecuentes

¿Cuánto rendimiento pierdo al ejecutar un contenedor con gVisor?

Depende de la carga. Con uso intenso de CPU y pocas llamadas al sistema, un banco de pruebas independiente de KubeBlocks con Sysbench midió apenas un 4 % de sobrecoste frente a runc, porque Sentry no emula la CPU. Con cargas intensivas en llamadas al sistema la cosa cambia. Hay entre un 56 % (plataforma KVM) y un 95 % (ptrace) de degradación en Redis y un 125 % en inserciones de SQLite, frente a un 17 % en Kata.

¿Puedo usar gVisor solo en algunos pods de mi clúster Kubernetes?

Sí. Instalas runsc en los nodos, lo registras en containerd con sudo runsc install y reinicias containerd. Después declaras una RuntimeClass en Kubernetes: solo los pods que la referencien arrancan con Sentry y Gofer, y el resto sigue con runc. Hay operadores que combinan gVisor para una fracción del clúster, Kata para otra y runc para el resto según el nivel de confianza de cada carga.

¿Qué modo de plataforma de gVisor debo usar: ptrace, KVM o systrap?

systrap, el modo por defecto desde su lanzamiento en 2023. Usa seccomp con filtros de notificación para interceptar llamadas sin depender de KVM ni ptrace, con buen rendimiento, portable y sin requisitos especiales de hardware. La plataforma ptrace es portable pero lenta y rara vez se usa en producción. KVM rinde mejor que ptrace, pero requiere acceso a /dev/kvm.

Fuentes

  1. abrió el código en 2018
  2. lanzamiento en 2023
  3. guía de rendimiento del proyecto
  4. KubeBlocks
  5. Kata Containers