Start with running as non-root and the container runtime's default seccomp profile. Add AppArmor or SELinux, whichever your node operating system supports, for mandatory access control on files, network and capabilities. For stronger isolation than a shared kernel gives, the Kubernetes docs point to sandboxes such as gVisor.
First, run without root
The Kubernetes page on Linux kernel security constraints begins with the securityContext: set the user and group, and prevent containers from running as root. Pod settings override image defaults, which matters for images you do not own. Running as non-root, or in user namespaces if root is needed, reduces how often you must lean on the kernel controls.
seccomp: filter system calls
seccomp restricts which system calls a process can make. The docs recommend using the runtime's default profile. Runtimes such as containerd, CRI-O and Docker usually ship one, and Kubernetes can apply profiles loaded on the node.
securityContext:
seccompProfile:
type: RuntimeDefault
Risks the docs list: configurations can break during updates, allowed syscalls can still be exploited, and per-application profiles are hard to manage at scale. Also set allowPrivilegeEscalation to false, which stops unprivileged users from switching to a more permissive seccomp profile.
The Restricted Pod Security Standard requires RuntimeDefault or Localhost, and Baseline only forbids Unconfined.
AppArmor: profile based confinement
AppArmor confines programs with profiles governing capabilities, network access and file permissions. Profiles run in enforcing mode, which blocks disallowed access, or complain mode, which only reports. It needs a node OS with AppArmor enabled in the kernel, and the docs give Ubuntu as an example that enables it by default. The runtime may provide a default profile, or you can supply a custom one.
SELinux: label based confinement
SELinux restricts what a labeled subject can access, based on policies the host kernel enforces. In Kubernetes you set SELinux labels in the securityContext. Baseline limits the allowed SELinux type to a short list and requires user and role to be unset.
Decision guide
- Any cluster: Non-root plus RuntimeDefault seccomp
- Nodes run Ubuntu or similar with AppArmor: Add AppArmor, default profile first
- Nodes run an SELinux distribution: Add SELinux, keep labels default unless needed
- Tenants do not trust each other: Consider a sandbox such as gVisor, and weigh the extra node resources and compatibility limits the docs mention
Do not pick between them on preference. Your node OS usually decides.
For the pod fields, see the securityContext checklist.
Checking what is applied
Inspect a running pod and its node. Confirm the seccomp profile type in the pod spec, then check on the node whether AppArmor or SELinux is enabled in the kernel. If neither is active, adding a profile reference to the pod spec will not give you the protection you expect, so verify the node side first.
Quick check
Can I skip seccomp if I use AppArmor?
They control different things, system calls versus access to resources. Use the default seccomp profile regardless.
Does my managed cluster already apply these?
It depends on the provider and node image. Verify by inspecting a running pod's effective settings.
Sources
- Linux kernel security constraints for Pods and containers, Kubernetes documentation
- Pod Security Standards
Last reviewed: 19 October 2026.