Pod Security¶
Security configurations and best practices for Kubernetes pods.
Pod Security Standards¶
Three levels of security policies:
Privileged¶
Unrestricted policy (not recommended for production)
Baseline¶
Minimally restrictive policy preventing known privilege escalations
Restricted¶
Heavily restricted policy following current pod hardening best practices
Pod Security Context¶
Pod-Level Security Context¶
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
fsGroupChangePolicy: "OnRootMismatch"
seccompProfile:
type: RuntimeDefault
supplementalGroups: [4000]
containers:
- name: app
image: myapp:1.0
Container-Level Security Context¶
apiVersion: v1
kind: Pod
metadata:
name: container-security
spec:
containers:
- name: app
image: myapp:1.0
securityContext:
runAsNonRoot: true
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
Security Context Fields¶
runAsNonRoot¶
runAsUser / runAsGroup¶
fsGroup¶
allowPrivilegeEscalation¶
readOnlyRootFilesystem¶
privileged¶
Linux Capabilities¶
Drop All Capabilities¶
Add Specific Capabilities¶
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE # Bind to ports < 1024
- CHOWN # Change file ownership
Common Capabilities¶
NET_BIND_SERVICE: Bind to privileged portsCHOWN: Change file ownershipDAC_OVERRIDE: Bypass file permissionsSETUID/SETGID: Set user/group IDNET_ADMIN: Network administrationSYS_ADMIN: System administration
SELinux¶
securityContext:
seLinuxOptions:
level: "s0:c123,c456"
role: "sysadm_r"
type: "container_t"
user: "system_u"
AppArmor¶
apiVersion: v1
kind: Pod
metadata:
name: apparmor-pod
annotations:
container.apparmor.security.beta.kubernetes.io/app: localhost/k8s-apparmor-example
spec:
containers:
- name: app
image: nginx
Seccomp¶
RuntimeDefault Profile¶
Custom Profile¶
Pod Security Admission¶
Namespace Labels¶
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
Modes¶
enforce: Reject non-compliant pods audit: Log violations warn: Show warnings
Restricted Pod Example¶
apiVersion: v1
kind: Pod
metadata:
name: restricted-pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: myapp:1.0
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
capabilities:
drop:
- ALL
volumeMounts:
- name: tmp
mountPath: /tmp
- name: cache
mountPath: /app/cache
volumes:
- name: tmp
emptyDir: {}
- name: cache
emptyDir: {}
Service Accounts¶
Create Service Account¶
Use in Pod¶
apiVersion: v1
kind: Pod
metadata:
name: sa-pod
spec:
serviceAccountName: app-sa
automountServiceAccountToken: false
containers:
- name: app
image: myapp:1.0
Host Namespaces¶
Avoid Host Namespaces¶
Volume Security¶
Read-Only Volumes¶
EmptyDir with Size Limit¶
Best Practices¶
1. Run as Non-Root¶
2. Drop All Capabilities¶
3. Read-Only Root Filesystem¶
4. Disable Privilege Escalation¶
5. Use Seccomp¶
6. Minimal Service Account¶
Security Scanning¶
# Scan pod security
kubectl auth can-i --list --as=system:serviceaccount:default:app-sa
# Check pod security standards
kubectl label --dry-run=server --overwrite ns production \
pod-security.kubernetes.io/enforce=restricted
Troubleshooting¶
# Check security context
kubectl get pod secure-pod -o jsonpath='{.spec.securityContext}'
# Check container security context
kubectl get pod secure-pod -o jsonpath='{.spec.containers[0].securityContext}'
# View pod security violations
kubectl get events --field-selector reason=FailedCreate
# Test as service account
kubectl auth can-i create pods --as=system:serviceaccount:default:app-sa