Completed upto lesson 28
This commit is contained in:
1
lessons/0006-read-only-root-filesystem.html
Normal file
1
lessons/0006-read-only-root-filesystem.html
Normal file
@@ -0,0 +1 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>CKS lesson 6: Read-only filesystems</title><link rel="stylesheet" href="../assets/course.css"></head><body><main><p class="eyebrow">Lesson 0006 · 25 minutes · Minimize Microservice Vulnerabilities</p><h1>Harden a web workload without breaking its writable paths</h1><p class="lede">A read-only root filesystem limits post-compromise persistence, but applications still need deliberate places for transient state. This drill builds that boundary.</p><div class="callout"><strong>Exam reflex:</strong> when you set <code>readOnlyRootFilesystem: true</code>, identify every path the process must write to and mount only those paths as temporary writable volumes.</div><h2>Timed task: 15 minutes</h2><p>In namespace <code>payments-prod</code>, harden the <code>payments</code> Pod while keeping it available on port <code>8080</code>. Begin with <code>kubectl --context kind-cks-lab apply -f .\lab\payments-hardening-starter.yaml</code> and write the completed manifest to <code>lab/payments-hardening-answer.yaml</code>.</p><p>Preserve the Pod name, namespace, image, label, and container port. Add the following controls:</p><ul><li>Run as non-root UID <code>101</code>.</li><li>Set <code>allowPrivilegeEscalation: false</code>.</li><li>Drop all Linux capabilities.</li><li>Use the <code>RuntimeDefault</code> seccomp profile.</li><li>Set <code>readOnlyRootFilesystem: true</code>.</li><li>Mount one writable <code>emptyDir</code> volume at <code>/tmp</code>.</li></ul><p>This uses the unprivileged NGINX image, which listens on <code>8080</code>. A non-root process that has dropped all capabilities cannot generally bind port 80; changing the port is the correct secure design rather than adding <code>NET_BIND_SERVICE</code>.</p><h2>Proof, not assumption</h2><pre><code>kubectl --context kind-cks-lab apply -f .\lab\payments-hardening-answer.yaml kubectl --context kind-cks-lab -n payments-prod wait --for=condition=Ready pod/payments --timeout=60s kubectl --context kind-cks-lab -n payments-prod exec payments -- id kubectl --context kind-cks-lab -n payments-prod exec payments -- sh -c 'touch /tmp/ok && test -f /tmp/ok' kubectl --context kind-cks-lab -n payments-prod exec payments -- sh -c 'touch /root/nope'</code></pre><p>The identity must have a non-zero UID, the <code>/tmp</code> check must succeed, and the final command must fail with a read-only filesystem error.</p><h2>Retrieval check</h2><div class="quiz"><h3>Question</h3><p>Why is an <code>emptyDir</code> volume usually preferable to leaving the image filesystem writable for runtime scratch data?</p><label><input type="radio" name="q" value="isolated">It limits writes to an explicit, ephemeral path while keeping the image filesystem immutable.</label><label><input type="radio" name="q" value="faster">It makes all application writes faster.</label><label><input type="radio" name="q" value="permanent">It preserves the data across Pod replacement.</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/tasks/configure-pod-container/security-context/">Configure a Security Context for a Pod or Container</a> guide to confirm security-context placement and volume-mount syntax.</p><h2>What to send me</h2><p>Paste your answer YAML and the three proof outputs. I’ll check the writable boundary and show you a fast inspection command.</p><footer>Previous: <a href="0005-pod-security-standards.html">Pod Security Standards</a> · CKS domain: Minimize Microservice Vulnerabilities</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==='isolated'){f.textContent='Correct. The writable area is explicit and ephemeral, while the rest of the image filesystem stays protected.';f.className='feedback good';}else{f.textContent='Not quite. emptyDir is useful because it narrows writable state to a defined, temporary location.';f.className='feedback bad';}}</script></body></html>
|
||||
Reference in New Issue
Block a user