Files
CKS-Lessons/lessons/0011-apparmor-runtime-confinement.html
2026-08-23 15:29:06 +06:00

2 lines
4.8 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>CKS lesson 11: AppArmor confinement</title><link rel="stylesheet" href="../assets/course.css"></head><body><main><p class="eyebrow">Lesson 0011 · 35 minutes · System Hardening</p><h1>Apply runtime confinement to a multi-container Pod</h1><p class="lede">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.</p><div class="callout"><strong>Exam reflex:</strong> prefer structured <code>securityContext</code> fields over legacy annotations. A container-level setting overrides the Pod-level setting, so inspect both levels when validating a multi-container workload.</div><h2>Timed task: 25 minutes</h2><p>Apply <code>lab/lesson-11-fixture.yaml</code>. Create <code>lab/lesson-11-answer.yaml</code> from scratch containing the Pod described below.</p><p>Create Pod <code>event-forwarder</code> in namespace <code>runtime-hardening</code> with two containers, both using <code>busybox:1.37</code> and command <code>sh -c 'sleep 3600'</code>:</p><ul><li>Container names: <code>forwarder</code> and <code>metrics</code>.</li><li>Both containers must receive the runtime’s default AppArmor profile. Use the current structured API field—not an AppArmor annotation.</li><li>Both containers must prevent privilege escalation and drop all capabilities.</li><li>Run the Pod as a non-root UID <code>1000</code>, with RuntimeDefault seccomp.</li><li>Do not mount a ServiceAccount token.</li><li>Use a read-only root filesystem for both containers, while allowing each to write under <code>/tmp</code>.</li><li>Do not enable host networking, host PID, host IPC, privileged mode, or hostPath volumes.</li></ul><p>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.</p><h2>Verification</h2><pre><code>kubectl --context kind-cks-lab apply -f .\lab\lesson-11-fixture.yaml&#10;kubectl --context kind-cks-lab apply -f .\lab\lesson-11-answer.yaml&#10;kubectl --context kind-cks-lab -n runtime-hardening wait --for=condition=Ready pod/event-forwarder --timeout=60s&#10;kubectl --context kind-cks-lab -n runtime-hardening exec event-forwarder -c forwarder -- id&#10;kubectl --context kind-cks-lab -n runtime-hardening exec event-forwarder -c metrics -- sh -c 'touch /tmp/proof'&#10;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"}'</code></pre><p>Both containers must be Ready, run as a non-zero UID, and write successfully to <code>/tmp</code>. If you set AppArmor at container level, inspect the equivalent container field instead of expecting the final command’s first value.</p><h2>Retrieval check</h2><div class="quiz"><h3>Question</h3><p>A Pod-level AppArmor profile is <code>RuntimeDefault</code>, but one container sets its own profile to <code>Unconfined</code>. Which profile applies to that container?</p><label><input type="radio" name="q" value="container">The container-level <code>Unconfined</code> profile, because it overrides the Pod-level setting.</label><label><input type="radio" name="q" value="pod">The Pod-level RuntimeDefault profile.</label><label><input type="radio" name="q" value="merge">Both profiles merge into a stricter profile.</label><button onclick="check()">Check answer</button><p id="feedback" class="feedback" aria-live="polite"></p></div><h2>Documentation target</h2><p>Use the official <a href="https://kubernetes.io/docs/tutorials/security/apparmor/">AppArmor tutorial</a> and inspect the API schema with <code>kubectl explain pod.spec.securityContext.appArmorProfile</code>.</p><h2>What to send me</h2><p>Paste your Pod YAML and the proof outputs. I’ll inspect effective profile scope as well as the usual workload-hardening controls.</p><footer>Previous: <a href="0010-minimize-secret-exposure.html">Minimize Secret exposure</a> · CKS domain: System Hardening</footer></main><script>function check(){const c=document.querySelector('input[name=q]:checked'),f=document.getElementById('feedback');if(!c){f.textContent='Choose an answer.';f.className='feedback bad';return;}if(c.value==='container'){f.textContent='Correct. A container-level AppArmor profile overrides the Pod-level profile for that container.';f.className='feedback good';}else{f.textContent='Not quite. The explicit container-level profile takes precedence for that container.';f.className='feedback bad';}}</script></body></html>