Comprehensive guide6 min read

AppArmor and SELinux: Securing Kubernetes Workloads

SFEIR Institute•

Key Takeaways

  • âś“AppArmor and SELinux add a Mandatory Access Control layer to containers
  • âś“Profiles confine compromised processes by limiting file and network access
  • âś“Combine AppArmor/SELinux with Pod Security Standards for defense in depth

AppArmor Kubernetes and SELinux constitute the two pillars of container security at the system level. These Mandatory Access Control (MAC) technologies restrict process actions beyond classic Unix permissions. A compromised container finds itself confined to a strict perimeter, limiting the impact of an exploit.

TL;DR: Deploy AppArmor profiles for each sensitive workload. Use SELinux on RHEL/CentOS distributions. Combine these mechanisms with Pod Security Standards for defense in depth.

Professionals who want to master these skills follow the LFS460 Kubernetes Security Fundamentals training.

What is AppArmor and why use it with Kubernetes?

AppArmor is a Linux security module that controls program capabilities via text profiles. Each profile defines accessible files, authorized capabilities, and permitted network operations.

Kubernetes natively supports AppArmor since version 1.4. This integration allows applying profiles to each container individually.

According to the CNCF Annual Survey 2025, 82% of organizations run Kubernetes in production. Each container without a security profile represents a potential attack vector.

AppArmor ModeBehaviorUsage
enforceBlocks and logsProduction
complainLogs without blockingDevelopment
disabledNo restrictionsNot recommended
Key takeaway: AppArmor confines containerized processes. A restrictive profile prevents access to sensitive system files even if the container is compromised.

How to configure AppArmor Kubernetes for your pods?

Applying an AppArmor kubernetes profile is done via annotations on the pod or container.

Verify AppArmor availability

# Check AppArmor module on nodes
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.nodeInfo.containerRuntimeVersion}{"\n"}{end}'

# On a node, check loaded profiles
cat /sys/module/apparmor/parameters/enabled
aa-status

Create a custom AppArmor profile

# /etc/apparmor.d/k8s-restricted
#include <tunables/global>

profile k8s-restricted flags=(attach_disconnected,mediate_deleted) {
#include <abstractions/base>

# Deny access to sensitive mounts
deny /proc/** w,
deny /sys/** w,
deny /etc/passwd w,
deny /etc/shadow rw,

# Allow read access to /app
/app/** r,
/app/bin/* ix,

# Minimal capabilities
capability net_bind_service,
}

Load the profile on each node:

sudo apparmor_parser -r /etc/apparmor.d/k8s-restricted

To deepen Kubernetes cluster administration, check our complete guide.

Apply the profile to a pod

apiVersion: v1
kind: Pod
metadata:
name: secured-app
annotations:
container.apparmor.security.beta.kubernetes.io/app: localhost/k8s-restricted
spec:
containers:
- name: app
image: myapp:v1.0
securityContext:
allowPrivilegeEscalation: false
runAsNonRoot: true
Key takeaway: Deploy AppArmor profiles on all nodes before referencing them in pods. Use a DaemonSet to automate deployment.

How to use SELinux Kubernetes on RHEL distributions?

SELinux kubernetes offers an alternative to AppArmor on Red Hat, CentOS, and Fedora distributions. This MAC module uses security labels to control access.

Verify SELinux on nodes

# SELinux status
getenforce
sestatus

# Labels of containerized processes
ps -eZ | grep container

seLinuxOptions configuration in securityContext

apiVersion: v1
kind: Pod
metadata:
name: selinux-app
spec:
securityContext:
seLinuxOptions:
level: "s0:c123,c456"
containers:
- name: app
image: myapp:v1.0
securityContext:
seLinuxOptions:
type: "container_t"
level: "s0:c123,c456"

Common SELinux types for containers

TypeDescriptionRestrictions
container_tDefault typeLimited filesystem access
container_runtime_tRuntime (containerd)Elevated privileges
spc_tSuper Privileged ContainerNo restrictions

Warning: spc_t disables SELinux for the container. Reserve it for exceptional cases like node-level monitoring agents.

For a complete Kubernetes training, explore our paths including system security.

When to choose AppArmor Kubernetes versus SELinux?

The choice between AppArmor and SELinux depends on your Linux distribution and existing skills.

Technical comparison

CriterionAppArmorSELinux
DistributionsUbuntu, Debian, SUSERHEL, CentOS, Fedora
SyntaxSimple text profilesComplex policies
GranularityPath-basedLabel-based
Learning curveModerateHigh
Kubernetes supportNative (annotations)Native (seLinuxOptions)

Recommendations by use case

Use AppArmor if:

  • Your nodes run on Ubuntu/Debian
  • You're starting with MAC
  • You want readable profiles

Use SELinux if:

  • Your nodes run on RHEL/CentOS
  • You have existing SELinux expertise
  • You need strict multi-tenant isolation
Key takeaway: AppArmor and SELinux are mutually exclusive on the same node. Choose based on your distribution and maintain consistency across the cluster.

Check Kubernetes security for a global view of protection mechanisms.

How to integrate AppArmor Kubernetes with Pod Security Standards?

Pod Security Standards (PSS) define three security levels (Privileged, Baseline, Restricted). They complement AppArmor without replacing it.

Pod Security Admission configuration

apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted

Combine PSS and AppArmor

apiVersion: v1
kind: Pod
metadata:
name: hardened-app
annotations:
container.apparmor.security.beta.kubernetes.io/app: localhost/k8s-restricted
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: myapp:v1.0
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true

According to Spectro Cloud State of Kubernetes 2025, 82% of Kubernetes workloads are overprovisioned. A strict securityContext also reduces the attack surface.

How to audit and debug AppArmor profiles?

Complain mode allows developing profiles without blocking applications.

Enable complain mode

# Switch a profile to complain mode
aa-complain /etc/apparmor.d/k8s-restricted

# Analyze audit logs
journalctl -k | grep apparmor
dmesg | grep -i apparmor

Automatically generate a profile

# Install tools
apt install apparmor-utils

# Start learning
aa-genprof /app/bin/myapp

# Analyze and refine the generated profile
aa-logprof

Test a profile before deployment

# Validate syntax
apparmor_parser -p /etc/apparmor.d/k8s-restricted

# Load in enforce mode
apparmor_parser -r /etc/apparmor.d/k8s-restricted

# Check status
aa-status | grep k8s-restricted

To master Kubernetes troubleshooting, include MAC log analysis in your workflow.

Key takeaway: Develop your profiles in complain mode, analyze logs, then switch to enforce for production.

What are AppArmor Kubernetes best practices in production?

Standardize and automate profile deployment to ensure consistency across all nodes.

Deployment via DaemonSet

apiVersion: apps/v1
kind: DaemonSet
metadata:
name: apparmor-loader
namespace: kube-system
spec:
selector:
matchLabels:
app: apparmor-loader
template:
metadata:
labels:
app: apparmor-loader
spec:
containers:
- name: loader
image: apparmor-profiles:v1.0
command: ["sh", "-c", "cp /profiles/* /host/etc/apparmor.d/ && apparmor_parser -r /host/etc/apparmor.d/k8s-*"]
volumeMounts:
- name: apparmor-d
mountPath: /host/etc/apparmor.d
securityContext:
privileged: true
volumes:
- name: apparmor-d
hostPath:
path: /etc/apparmor.d

Admission controller validation

Use an admission webhook to reject pods without AppArmor profiles:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: apparmor-validator
webhooks:
- name: validate.apparmor.k8s.io
rules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE"]
resources: ["pods"]

According to the CNCF Project Journey Report, 71% of Fortune 100 companies run Kubernetes in production. Security profile standardization becomes critical at this scale.

Check Kubernetes production best practices to complete your strategy.

AppArmor and SELinux Security Checklist

Validate each point for secured workloads:

  • [ ] AppArmor/SELinux enabled on all nodes
  • [ ] Custom profiles for each critical application
  • [ ] Enforce mode in production (not complain)
  • [ ] DaemonSet for automatic profile deployment
  • [ ] Validation via admission controller
  • [ ] Pod Security Standards configured (Restricted)
  • [ ] MAC violation monitoring
  • [ ] Profile and exception documentation
Key takeaway: AppArmor and SELinux form the last line of defense. Even if all other protections fail, these profiles limit an attacker's actions.

Take Action: Train on Kubernetes Workloads Security

The LFS460 Kubernetes Security Fundamentals training covers AppArmor, SELinux, Pod Security Standards, and CKS certification preparation. In 4 days, master container system security.

Next steps:

Contact our advisors to develop your custom Kubernetes security path.