Learn how to use AppArmor (Application Armor) to enforce Mandatory Access Control (MAC) policies on Kubernetes pods. AppArmor is a Linux security module that provides fine-grained access control for applications.
Prerequisites
Understanding AppArmor
AppArmor is a Linux kernel security module that:
Mandatory Access Control: Enforces policies that applications cannot override
Path-based: Controls access to files, directories, and capabilities
Profile-based: Uses text-based profiles to define allowed operations
Kubernetes integration: Applied via pod annotations
Q1: What are the main AppArmor profile modes?
Answer
Enforce: Actively denies operations that violate the profile
Complain: Logs violations but allows operations to proceed
Unconfined: No restrictions applied (default for most applications)
Kill: Terminates the process if it violates the profile
Q2: How does AppArmor differ from seccomp?
Answer
AppArmor: Controls access to files, network, capabilities (path-based)
Seccomp: Controls which system calls can be made (syscall-based)
Complementary: Often used together for defense in depth
Scope: AppArmor is broader, seccomp is more granular
Check AppArmor Support
First, verify that AppArmor is available and enabled:
# Check if AppArmor is enabled on the nodesudo aa-status
# List available profilessudo aa-enabled
# Check AppArmor filesystemls -la /sys/kernel/security/apparmor/
# Verify kubelet supports AppArmorkubectl version --short
Using Runtime Default Profile
The simplest approach is using the runtime’s default AppArmor profile:
# Apply the podkubectl apply -f apparmor-pod.yaml
# Test basic operations (should work)kubectl exec -it apparmor-runtime-default -- sh
ls -la
cat /etc/passwd
ps aux
# Test restricted operations (some may be blocked)mount
chmod 777 /tmp
Custom AppArmor Profiles
For specific security requirements, create custom AppArmor profiles:
Step 1: Create Profile on Nodes
Create a custom AppArmor profile on all cluster nodes:
# Apply the podkubectl apply -f custom-apparmor-pod.yaml
# Test allowed operationskubectl exec -it apparmor-custom-profile -- sh
ls /tmp
echo "test" > /tmp/testfile
cat /tmp/testfile
# Test denied operations (should fail)cat /etc/shadow # Should be deniedmount # Should be deniedchmod 777 /etc/passwd # Should be denied
AppArmor Profile Development
Generate Profile from Application Behavior
Use AppArmor tools to create profiles based on actual application behavior:
# Install AppArmor utilities (on Ubuntu/Debian)sudo apt-get install apparmor-utils
# Create a profile in learning modesudo aa-genprof /usr/bin/nginx
# Run the application and exercise its functionality# In another terminal:kubectl exec -it test-pod -- nginx -t
kubectl exec -it test-pod -- nginx -s reload
# Finish learning and create profilesudo aa-logprof
Complain Mode for Testing
Use complain mode to test profiles without blocking operations:
# Set profile to complain modesudo aa-complain /etc/apparmor.d/k8s-restricted-profile
# Check profile statussudo aa-status | grep k8s-restricted-profile
# Should show: k8s-restricted-profile (complain)# Test with pod - operations will be logged but not blocked# Check logs:sudo tail -f /var/log/kern.log | grep ALLOWED
Multi-Container Pod Configuration
Apply different AppArmor profiles to different containers:
apiVersion: v1kind: Podmetadata:
name: multi-container-apparmorannotations:
# Different profiles for different containerscontainer.apparmor.security.beta.kubernetes.io/web-server: runtime/defaultcontainer.apparmor.security.beta.kubernetes.io/database: localhost/k8s-restricted-profilespec:
containers:
- name: web-serverimage: nginx:alpineports:
- containerPort: 80 - name: databaseimage: postgres:alpineenv:
- name: POSTGRES_PASSWORDvalue: "secretpassword"command: ["/bin/sh"]
args: ["-c", "while true; do sleep 30; done;"]