Lesson 0011 · 35 minutes · System Hardening
Apply runtime confinement to a multi-container Pod
Linux capabilities and seccomp reduce a container’s power. AppArmor adds a path- and operation-oriented confinement layer. The difficult part is ensuring every container receives the intended profile without relying on deprecated annotations.
securityContext fields over legacy annotations. A container-level setting overrides the Pod-level setting, so inspect both levels when validating a multi-container workload.Timed task: 25 minutes
Apply lab/lesson-11-fixture.yaml. Create lab/lesson-11-answer.yaml from scratch containing the Pod described below.
Create Pod event-forwarder in namespace runtime-hardening with two containers, both using busybox:1.37 and command sh -c 'sleep 3600':
- Container names:
forwarderandmetrics. - Both containers must receive the runtime’s default AppArmor profile. Use the current structured API field—not an AppArmor annotation.
- Both containers must prevent privilege escalation and drop all capabilities.
- Run the Pod as a non-root UID
1000, with RuntimeDefault seccomp. - Do not mount a ServiceAccount token.
- Use a read-only root filesystem for both containers, while allowing each to write under
/tmp. - Do not enable host networking, host PID, host IPC, privileged mode, or hostPath volumes.
You decide whether a Pod-level or container-level field is the most concise correct way to satisfy the AppArmor requirement. Your manifest must not contain a conflicting override.
Verification
kubectl --context kind-cks-lab apply -f .\lab\lesson-11-fixture.yaml
kubectl --context kind-cks-lab apply -f .\lab\lesson-11-answer.yaml
kubectl --context kind-cks-lab -n runtime-hardening wait --for=condition=Ready pod/event-forwarder --timeout=60s
kubectl --context kind-cks-lab -n runtime-hardening exec event-forwarder -c forwarder -- id
kubectl --context kind-cks-lab -n runtime-hardening exec event-forwarder -c metrics -- sh -c 'touch /tmp/proof'
kubectl --context kind-cks-lab -n runtime-hardening get pod event-forwarder -o jsonpath='{.spec.securityContext.appArmorProfile.type}{"\n"}{.spec.securityContext.seccompProfile.type}{"\n"}{.spec.automountServiceAccountToken}{"\n"}'Both containers must be Ready, run as a non-zero UID, and write successfully to /tmp. If you set AppArmor at container level, inspect the equivalent container field instead of expecting the final command’s first value.
Retrieval check
Question
A Pod-level AppArmor profile is RuntimeDefault, but one container sets its own profile to Unconfined. Which profile applies to that container?
Documentation target
Use the official AppArmor tutorial and inspect the API schema with kubectl explain pod.spec.securityContext.appArmorProfile.
What to send me
Paste your Pod YAML and the proof outputs. I’ll inspect effective profile scope as well as the usual workload-hardening controls.