TL;DR: A container is a process isolated by namespaces, cgroups, capabilities, seccomp and an LSM, on the shared host kernel: escaping needs a kernel bug or a misconfiguration. gVisor puts a user-space kernel between the workload and the host, so the host kernel exposure shrinks to a small set of system calls. A microVM (Firecracker, Kata) gives the workload its own guest kernel behind hardware virtualisation: escaping needs a hypervisor or virtual-device bug. A full VM is the same boundary with more devices and overhead. Choose by trust: containers for your own code, gVisor or microVMs for untrusted or model-generated code.
How to approach it
For each option, state what sits between the workload and the host kernel, what an attacker must break, and the cost. Then pick by trust level and mention the misconfigurations that defeat any of them.
A strong answer
- 1
1 · Container
Shared host kernel
- Namespaces, cgroups, capabilities, seccomp, LSM
Escape: kernel bug or misconfiguration
- 2
2 · gVisor
User-space kernel in between
- Host kernel exposure shrinks to a small syscall set
Escape: gVisor bug plus host bug
- 3
3 · MicroVM
Minimal VMM, own guest kernel
- Firecracker-style, fast start
Escape: hypervisor or VMM bug
- 4
4 · Virtual machine
Full hardware virtualisation
- Separate kernel per tenant
Escape: hypervisor bug
| Option | Boundary | Attacker must break | Cost |
|---|---|---|---|
| Container | Kernel features on a shared kernel | A host kernel bug, or a misconfiguration | Lowest overhead |
| gVisor | User-space kernel (Sentry) intercepting syscalls, small host syscall surface | gVisor's implementation, then a much smaller host surface | Syscall-heavy workloads slower; some compatibility gaps |
| MicroVM (Firecracker, Kata) | Separate guest kernel, hardware virtualisation, minimal virtual devices | The hypervisor or a virtual device | Extra memory and startup time (Firecracker is designed for fast starts) |
| Full VM | Separate kernel, more emulated devices | Hypervisor or device emulation | Highest overhead |
Misconfigurations that defeat containers regardless. Privileged mode; mounting the container runtime socket; host path mounts of sensitive directories; adding capabilities such as CAP_SYS_ADMIN; disabling seccomp or AppArmor; sharing host network or PID namespaces; running as root without user namespaces.
Choosing.
- Your own reviewed services: hardened containers (non-root, read-only root, default seccomp, no extra capabilities).
- Third-party but vetted software: hardened containers on segregated nodes.
- Untrusted, customer or model-generated code: gVisor or microVMs, per session, with no credentials and restricted egress.
- Strong multi-tenant isolation for customers: microVMs, and separate hosts for high-risk tenants.
Isolation is half the design. A perfect boundary around code that holds cloud credentials and open internet access still lets that code exfiltrate data. Pair the boundary with an empty environment.
GPUs. Passing GPUs into sandboxes weakens guarantees: drivers are large kernel components, and GPU memory isolation between processes has had flaws (LeftoverLocals, CVE-2023-4969). Prefer dedicated GPUs per tenant for untrusted workloads.
What interviewers probe next
- "Why is Kubernetes namespace isolation not a security boundary?" It is an API and naming scope; pods in different namespaces share nodes and kernels unless you separate them with node pools, sandboxed runtimes and network policy.
- "How does Firecracker keep its attack surface small?" A minimal virtual machine monitor with very few emulated devices, running in a restricted process.
- "When is a container enough for untrusted code?" Rarely; perhaps for low-risk, short-lived code with no network and no secrets, accepting kernel-exploit risk.
What if?
What if · interview follow-ups
Hold your answer as the constraints change
You must run customer-supplied Python code on shared infrastructure, and a teammate proposes plain Docker containers because they are fast to start.
Start here
What isolates a container?
Which kernel does the container use?
Namespaces, cgroups, capabilities, seccomp and a Linux security module, all on the shared host kernel. Escaping needs a kernel bug or a misconfiguration. For your own trusted code that boundary is often enough; for hostile code it is thin.
Carry it forwardContainers share the host kernel.
Weak answerTreating containers as virtual machines.
Constraint changes
What does gVisor change?
How much of the host kernel can the code reach?
It puts a user-space kernel between the workload and the host, so the host kernel exposure shrinks to a small set of system calls the sandbox makes. Some workloads run slower or hit compatibility limits.
Carry it forwardgVisor narrows host kernel exposure.
Weak answerAssuming gVisor is free of compatibility costs.
Constraint changes
What does a microVM add?
What must an attacker break to reach the host?
A microVM such as Firecracker or Kata gives the workload its own guest kernel behind hardware virtualisation, so escaping needs a hypervisor or virtual-device bug. Startup is still fast enough for per-session use.
Carry it forwardMicroVMs put a hypervisor boundary in front of the host.
Weak answerAssuming microVMs are too slow for interactive use.
Constraint changes
Which should run customer code?
Who wrote the code you will run?
Choose by trust: containers for your own code, gVisor or microVMs for untrusted code, full VMs or dedicated hosts for the highest risk. Customer-supplied code is untrusted, so a microVM or gVisor per session is the right default.
Carry it forwardMatch isolation strength to code trust.
Weak answerUsing plain containers for hostile code.
Constraint changes
What matters besides the isolation layer?
What could the code steal without escaping?
What is inside and around the sandbox: no credentials, no metadata access, default-deny network, resource limits, non-root execution and destruction after use. A strong boundary around a sandbox full of secrets still leaks them.
Carry it forwardKeep the sandbox empty of value.
Weak answerMounting secrets into a strong sandbox.
Now defend it
What would you recommend?
Run customer code in per-session microVMs or gVisor sandboxes, not shared-kernel containers; keep sandboxes free of credentials, block metadata and network by default, run as non-root with resource limits, destroy them after use, and reserve plain containers for your own trusted services.
How it's scored
Weak: "Containers are isolated, VMs are more isolated."
Hire: Explains the shared kernel, gVisor's user-space kernel and microVM guest kernels, and maps choices to trust.
Strong Hire: Adds misconfigurations, costs, Kubernetes namespace caveats, GPU limitations, and pairs isolation with environment controls.
Common mistakes
- Treating Kubernetes namespaces as isolation.
- Running untrusted code in privileged containers for convenience.
- Focusing on escape while leaving credentials inside the sandbox.