Files
CKS-Lessons/lessons/0017-tenant-isolation-admission.html
2026-08-23 15:29:06 +06:00

2 lines
4.3 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 17: Tenant isolation admission</title><link rel="stylesheet" href="../assets/course.css"></head><body><main><p class="eyebrow">Lesson 0017 · 45 minutes · Minimize Microservice Vulnerabilities</p><h1>Block host-escape settings before scheduling</h1><p class="lede">Namespace isolation is weak if a tenant can request host namespaces, host networking, privileged containers, or hostPath volumes. This drill uses native CEL admission controls to make those settings unrepresentable in one tenant namespace.</p><div class="callout"><strong>Exam reflex:</strong> protect optional fields with CEL <code>has(...)</code> checks. A policy must handle an omitted securityContext as safely as an explicit <code>false</code>.</div><h2>Timed task: 35 minutes</h2><p>Apply <code>lab/lesson-17-fixture.yaml</code>. Create <code>lab/lesson-17-answer.yaml</code> from scratch containing a <code>ValidatingAdmissionPolicy</code> and <code>ValidatingAdmissionPolicyBinding</code>.</p><p>Only in namespace <code>tenant-a</code>, deny Pod creates and updates when any of the following is true:</p><ul><li><code>hostNetwork</code>, <code>hostPID</code>, or <code>hostIPC</code> is true.</li><li>Any volume is a <code>hostPath</code> volume.</li><li>Any regular container is privileged.</li></ul><p>The policy must allow a normal unprivileged Pod that omits all of these fields. Use <code>failurePolicy: Fail</code>, a useful denial message, and <code>Deny</code> in the binding. Scope the binding with the supplied namespace label; do not apply it cluster-wide or use a webhook.</p><h2>Verification</h2><pre><code>kubectl --context kind-cks-lab apply -f .\lab\lesson-17-fixture.yaml&#10;kubectl --context kind-cks-lab apply -f .\lab\lesson-17-answer.yaml&#10;kubectl --context kind-cks-lab -n tenant-a run normal --image=busybox:1.37 --restart=Never -- sh -c 'sleep 60'&#10;kubectl --context kind-cks-lab -n tenant-a run host-net --image=busybox:1.37 --restart=Never --overrides '{"apiVersion":"v1","spec":{"hostNetwork":true}}' -- sh -c 'sleep 60'&#10;kubectl --context kind-cks-lab -n default run host-net-outside --image=busybox:1.37 --restart=Never --overrides '{"apiVersion":"v1","spec":{"hostNetwork":true}}' -- sh -c 'sleep 60'</code></pre><p>Expected: <code>normal</code> is admitted, <code>host-net</code> is rejected, and <code>host-net-outside</code> is admitted. Clean up the two admitted test Pods afterward. Also inspect your CEL carefully: the commands prove host networking, while the policy must cover all four listed controls.</p><h2>Retrieval check</h2><div class="quiz"><h3>Question</h3><p>Why is a plain expression such as <code>c.securityContext.privileged == false</code> unsafe for this task?</p><label><input type="radio" name="q" value="optional">A container can omit <code>securityContext</code>; the expression must handle optional fields without an evaluation error.</label><label><input type="radio" name="q" value="scope">Privileged is a namespace-level field.</label><label><input type="radio" name="q" value="port">Privileged containers always require a host port.</label><button onclick="check()">Check answer</button><p id="feedback" class="feedback" aria-live="polite"></p></div><h2>Documentation target</h2><p>Use the Kubernetes <a href="https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/">Validating Admission Policy</a> reference and inspect CEL field availability with <code>kubectl explain pod.spec</code>.</p><h2>What to send me</h2><p>Paste the policy and binding, plus the three admission outcomes. I’ll inspect scope, optional-field handling, and every escape path.</p><footer>Previous: <a href="0016-tls-ingress.html">TLS Ingress</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==='optional'){f.textContent='Correct. CEL expressions must explicitly handle fields that are optional in the Kubernetes API.';f.className='feedback good';}else{f.textContent='Not quite. securityContext can be absent, so a robust policy must account for it.';f.className='feedback bad';}}</script></body></html>