KCSA — Runtime Security & Sandboxing
Container Isolation Mechanisms
Standard containers rely on Linux kernel features for isolation. These features separate a container’s view of the system from other containers and the host — but they all share the same kernel.
Key Isolation Primitives
| Mechanism | What It Isolates | Description |
|---|---|---|
| PID namespace | Process IDs | Each container sees its own PID 1; cannot see host or other container processes |
| Network namespace | Network stack | Each container gets its own network interfaces, IP address, routing table |
| Mount namespace | Filesystem | Each container has its own root filesystem; cannot see host mounts (unless explicitly shared) |
| UTS namespace | Hostname | Each container can set its own hostname |
| IPC namespace | Inter-process communication | Isolates shared memory, semaphores, message queues |
| User namespace | User/group IDs | Maps container root (UID 0) to an unprivileged user on the host |
| cgroups | Resource usage | Limits CPU, memory, I/O, and PIDs available to the container |
Why Standard Containers Are Not Fully Isolated
Despite these isolation mechanisms, standard containers share the host kernel. This means:
- A kernel vulnerability can be exploited from inside a container to escape to the host
- Privileged containers (
privileged: true) bypass nearly all isolation - Host namespaces (
hostPID,hostNetwork,hostIPC) remove namespace boundaries - Sensitive mounts (Docker socket,
/proc, host paths) provide escape routes
Container escapes are not theoretical — they are well-documented and regularly discovered (e.g., CVE-2019-5736 in runc, CVE-2020-15257 in containerd).
This is why sandboxed runtimes exist — they add an extra isolation layer between the container and the host kernel.
Sandboxed Runtime Options
Kubernetes supports multiple container runtimes through the Container Runtime Interface (CRI). Different runtimes offer different levels of isolation.
| Runtime | Approach | Overhead | Isolation Level | Use Case |
|---|---|---|---|---|
| runc | Standard OCI runtime | None | Kernel-level (namespaces + cgroups) | Default runtime for most clusters |
| gVisor (runsc) | User-space kernel intercepts syscalls | Moderate (syscall overhead) | High — application never touches host kernel | Untrusted workloads, multi-tenant |
| Kata Containers | Lightweight VM per pod | Higher (VM overhead) | Highest — hardware-level isolation | Strong compliance, strict isolation |
| Firecracker | MicroVM with minimal device model | Moderate | High — lightweight VM | Serverless, AWS Lambda/Fargate |
gVisor (runsc)
gVisor provides a user-space kernel called Sentry that intercepts system calls from the container and handles them without passing them directly to the host kernel.
┌──────────────────────────┐
│ Container Process │
├──────────────────────────┤
│ gVisor Sentry │ ← User-space kernel
│ (intercepts syscalls) │
├──────────────────────────┤
│ Host Linux Kernel │ ← Sentry uses limited host syscalls
└──────────────────────────┘
Key points about gVisor:
- Dramatically reduces the kernel attack surface by implementing ~200 syscalls in user space
- Adds latency to syscall-heavy workloads (not ideal for high I/O applications)
- Does not require hardware virtualization (works on any Linux host)
- Used in production by Google (GKE Sandbox)
- Some applications may not work due to unsupported syscalls
Kata Containers
Kata Containers runs each pod inside a lightweight virtual machine. The VM provides hardware-level isolation using a hypervisor (QEMU/Cloud Hypervisor).
┌──────────────────────────┐
│ Container Process │
├──────────────────────────┤
│ Guest Kernel │ ← Dedicated kernel per pod
├──────────────────────────┤
│ Hypervisor (QEMU) │ ← Hardware isolation
├──────────────────────────┤
│ Host Linux Kernel │
└──────────────────────────┘
Key points about Kata Containers:
- Provides the strongest isolation — a kernel vulnerability in the guest does not affect the host
- Higher resource overhead (each pod gets its own kernel and VM)
- Requires hardware virtualization support (nested virtualization in cloud)
- Slower cold start compared to standard containers
- Best for workloads with strict compliance or regulatory requirements
gVisor vs Kata Containers Comparison
| Feature | gVisor | Kata Containers |
|---|---|---|
| Isolation approach | User-space kernel | Lightweight VM |
| Host kernel exposure | Minimal (Sentry handles syscalls) | None (dedicated guest kernel) |
| Performance overhead | Moderate (syscall interception) | Higher (VM overhead) |
| Cold start time | Fast | Slower (VM boot) |
| Hardware requirements | None | Virtualization extensions (VT-x) |
| Syscall compatibility | Partial (~200 syscalls) | Full (standard Linux kernel) |
| Memory overhead | Low | Higher (per-pod kernel + VM) |
| Best for | Multi-tenant, untrusted code | Strict compliance, strong isolation |
For the KCSA exam, know what gVisor and Kata Containers do and when to choose each. You do not need to install or configure them.
RuntimeClass in Kubernetes
RuntimeClass is a Kubernetes resource that allows you to select which container runtime a pod should use. This is how you schedule specific workloads onto sandboxed runtimes.
Defining a RuntimeClass
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: gvisor
handler: runsc # Must match the runtime handler configured on the node
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: kata
handler: kata-qemu
Using RuntimeClass in a Pod
apiVersion: v1
kind: Pod
metadata:
name: sandboxed-app
spec:
runtimeClassName: gvisor # Select the gVisor runtime
containers:
- name: app
image: nginx:1.25
RuntimeClass with Scheduling
RuntimeClass also supports scheduling — ensuring pods land on nodes that have the required runtime installed:
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: kata
handler: kata-qemu
scheduling:
nodeSelector:
runtime.kata: "true"
RuntimeClass is a cluster-scoped resource — it is available to all namespaces.
Seccomp Profiles
Seccomp (Secure Computing Mode) restricts which system calls a containerized process can make. By limiting syscalls, you reduce the kernel attack surface available to an attacker inside a container.
How Seccomp Works
- A seccomp profile defines a list of allowed or denied system calls
- The profile is loaded when the container starts
- If the process makes a blocked syscall, it is killed (or the call returns an error, depending on the profile action)
Profile Actions
| Action | Behavior |
|---|---|
SCMP_ACT_ALLOW |
Allow the syscall |
SCMP_ACT_ERRNO |
Return an error for the syscall |
SCMP_ACT_KILL_PROCESS |
Kill the process immediately |
SCMP_ACT_KILL_THREAD |
Kill the calling thread |
SCMP_ACT_LOG |
Log the syscall but allow it (useful for profiling) |
Applying Seccomp in Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: seccomp-pod
spec:
securityContext:
seccompProfile:
type: RuntimeDefault # Use the container runtime's default profile
containers:
- name: app
image: nginx:1.25
Seccomp Profile Types in Kubernetes
| Type | Description |
|---|---|
RuntimeDefault |
Container runtime’s built-in default profile (recommended baseline) |
Localhost |
Custom profile loaded from a file on the node |
Unconfined |
No seccomp filtering (not recommended for production) |
The Docker/containerd default seccomp profile blocks approximately 44 dangerous syscalls (including reboot, mount, kexec_load, etc.) while allowing the ~300+ syscalls that most applications need.
AppArmor Profiles
AppArmor is a Linux Security Module (LSM) that restricts what a program can do — including file access, network operations, and capabilities. AppArmor provides mandatory access control (MAC) on top of standard Linux permissions.
AppArmor Modes
| Mode | Description |
|---|---|
| Enforce | Violations are blocked and logged |
| Complain | Violations are logged but not blocked (useful for profiling) |
| Unconfined | No restrictions applied |
Using AppArmor in Kubernetes
As of Kubernetes 1.30+, AppArmor can be specified directly in the security context:
apiVersion: v1
kind: Pod
metadata:
name: apparmor-pod
spec:
containers:
- name: app
image: nginx:1.25
securityContext:
appArmorProfile:
type: RuntimeDefault
For older Kubernetes versions, AppArmor profiles are applied using annotations:
metadata:
annotations:
container.apparmor.security.beta.kubernetes.io/app: runtime/default
What AppArmor Can Restrict
- File read/write/execute permissions by path
- Network operations (raw sockets, binding to ports)
- Linux capabilities (even if granted by the container runtime)
- Mount operations
- Signal handling
AppArmor profiles must be loaded on each node where the profiled pods will run. This is a common operational requirement.
SELinux in Kubernetes
SELinux (Security-Enhanced Linux) provides mandatory access control using a label-based system. Every file, process, and port gets a security label, and policies define which labels can interact.
Applying SELinux in Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: selinux-pod
spec:
securityContext:
seLinuxOptions:
level: "s0:c123,c456" # Multi-Category Security label
type: "container_t" # SELinux type
containers:
- name: app
image: nginx:1.25
AppArmor vs SELinux
| Feature | AppArmor | SELinux |
|---|---|---|
| Approach | Path-based profiles | Label-based policies |
| Complexity | Simpler to write and understand | More complex, steeper learning curve |
| Default on | Ubuntu, SUSE, Debian | RHEL, CentOS, Fedora |
| Granularity | Per-program profiles | System-wide label policies |
| Kubernetes support | securityContext + annotations | securityContext.seLinuxOptions |
The KCSA exam will not ask you to write AppArmor or SELinux policies. Know what they do and when to use each.
Runtime Security Monitoring
Beyond prevention, runtime security involves detecting anomalous behavior as containers run. This is the realm of runtime security monitoring tools.
What Runtime Monitoring Detects
| Behavior | Example | Why It Matters |
|---|---|---|
| Unexpected process execution | Shell spawned in a web server container | Possible container compromise |
| File modifications | Write to /etc/passwd inside container |
Privilege escalation attempt |
| Network anomalies | Outbound connection to a crypto-mining pool | Cryptojacking |
| Syscall anomalies | ptrace called by a non-debugger process |
Process injection attempt |
| Privilege changes | Process gains CAP_SYS_ADMIN at runtime |
Capability escalation |
Tools for Runtime Monitoring
| Tool | Description |
|---|---|
| Falco | Open-source runtime security engine using eBPF/kernel module to detect anomalous syscalls and behaviors |
| Tetragon | Cilium-based eBPF security observability and enforcement tool |
| Sysdig Secure | Commercial platform including runtime detection, image scanning, and compliance |
| KubeArmor | Runtime security enforcement engine using LSMs (AppArmor, SELinux, BPF) |
Falco is the most commonly referenced runtime monitoring tool in Kubernetes certifications. It uses rules to detect suspicious behavior at the syscall level.
Key Takeaways for the Exam
| Concept | What to Remember |
|---|---|
| Shared kernel risk | Standard containers share the host kernel — kernel exploits can break isolation |
| gVisor | User-space kernel, intercepts syscalls, moderate overhead, good for untrusted workloads |
| Kata Containers | Lightweight VMs, hardware isolation, highest overhead, strongest isolation |
| RuntimeClass | Kubernetes resource to select which runtime a pod uses (runtimeClassName in pod spec) |
| Seccomp | Filters system calls — RuntimeDefault is the recommended baseline |
| AppArmor | Path-based MAC — restricts file access, network, capabilities per container |
| SELinux | Label-based MAC — used on RHEL-family distributions |
| Runtime monitoring | Falco, Tetragon — detect anomalous behavior at runtime using eBPF |
- Know the trade-offs between gVisor and Kata Containers — this is a common exam question
- RuntimeClass is how Kubernetes selects runtimes — it is a cluster-scoped resource
- Seccomp + AppArmor/SELinux are complementary — seccomp filters syscalls, AppArmor/SELinux restrict resources
- Runtime monitoring is detection, not prevention — it alerts you when something bad happens