Kubernetes Security Hardening¶
Overview¶
Run a Pod with a restrictive securityContext, enable Pod Security Admission labels on a namespace, and draft a default-deny NetworkPolicy pattern.
Defence in depth: RBAC + securityContext + Pod Security Admission (PSA) + NetworkPolicy + signed/scanned images + Secrets hygiene.
This is a core tutorial in Module 10 · Security of the REBASH Academy Kubernetes for Cloud & DevOps Engineers series — written for Cloud, DevOps, Platform, and SRE engineers.
Prerequisites¶
Learning Objectives¶
By the end of this tutorial, you will be able to:
- Set
runAsNonRoot, drop capabilities - Label ns for PSA (
restricted/baseline) - Explain NetworkPolicy default-deny
- List image policy controls
Architecture¶
This topic’s control points and relationships are shown below.
Theory¶
What it is¶
Hardening layers controls beyond basic RBAC. securityContext settings run containers as non-root, drop Linux capabilities, and disallow privilege escalation. Pod Security Admission (PSA) enforces baseline/restricted profiles per namespace. NetworkPolicies restrict Pod-to-Pod and egress traffic (enforced by the CNI). Image hygiene — digests, scanning, admission policies — reduces supply-chain risk. Secrets encryption and audit logging complete the picture.
Why it matters¶
A cluster with open RBAC but privileged Pods and unrestricted east-west traffic is one CVE away from lateral movement. CKS-oriented DevOps treats defence in depth as normal: identity, workload, network, and supply chain each fail closed where practical.
How it works (mental model)¶
- Workload: Pod/container
securityContext+ PSA labels (enforce=restrictedwhen apps allow). - Network: default-deny NetworkPolicy, then allow only needed ingress/egress.
- Identity: dedicated SAs, no unnecessary secret mounts, short-lived tokens where possible.
- Supply chain: pin digests, scan in CI, optional admission (Kyverno/OPA Gatekeeper) to block
:latestor unsigned images. - Controllers still reconcile — hardening constrains what may run, not the reconcile loop itself.
PSA replaces the older PodSecurityPolicy API; learn labels, not PSP.
Key concepts / comparisons¶
| Control | Layer |
|---|---|
| RBAC | API access |
| securityContext | Process privileges |
| PSA | Admission of Pod specs |
| NetworkPolicy | East-west / egress |
| Image policy | What may be pulled/run |
| PSA level | Strictness |
|---|---|
| privileged | No restriction |
| baseline | Minimally opinionated |
| restricted | Hardened defaults |
Common pitfalls¶
- Labelling
enforce=restrictedwithout fixing images that require root — mass Pending/reject. - Writing NetworkPolicies when the CNI does not enforce them — false sense of safety.
- Dropping
ALLcapabilities but adding back dangerous ones casually. - Leaving
hostNetwork/hostPIDenabled on ordinary apps. - Scanning images once and never again — rebuild pipelines must re-scan.
Hands-on Lab¶
Create a workspace for this tutorial.
Focus: Apply a Pod Security Context and non-root container settings
Step 1 – Deploy a hardened Pod¶
kubectl create namespace rebash-lab
cat > hardened.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: hardened
namespace: rebash-lab
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: busybox:1.36
command: ["sh", "-c", "id; sleep 3600"]
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
EOF
kubectl apply -f hardened.yaml
kubectl -n rebash-lab wait --for=condition=Ready pod/hardened --timeout=60s
Step 2 – Verify identity and security fields¶
kubectl -n rebash-lab exec hardened -- id
kubectl -n rebash-lab get pod hardened -o jsonpath='{.spec.securityContext}{"
"}'
kubectl -n rebash-lab get pod hardened -o jsonpath='{.spec.containers[0].securityContext}{"
"}'
Final step – Cleanup note¶
kubectl delete namespace rebash-lab --ignore-not-found
# Workspace kept for notes; remove with: rm -rf "$(pwd)" when finished
Validation¶
- Lab commands run under
~/rebash-k8s/module-10-hard/ - You can explain each Theory section in your own words
- You used modern tooling where it applies to this topic
- You can describe one production failure mode for this topic
Code Walkthrough¶
Production practice for Kubernetes Security Hardening always combines:
- Inspect before you change (status, plan, logs, dry-run)
- Prefer reversible, documented changes (Git, IaC, drop-ins, version pins)
- Capture evidence (command output, pipeline logs) for handovers
- Prefer current tools and APIs over legacy shortcuts
- Least privilege — escalate credentials only when required
Keep runbooks short enough to follow under pressure. Automate checks; keep humans for judgement.
Security Considerations¶
- Treat credentials and tokens for kubernetes as privileged — never commit them
- Prefer short-lived auth (OIDC, roles, SSO) over long-lived keys
- Validate blast radius before apply/deploy/delete operations
- Restrict who can approve production changes
- Collect audit logs; limit who can read sensitive traces
Common Mistakes¶
Labelling enforce=restricted without fixing images that require root — mass Pending/reje
Validate assumptions against the Theory section and official docs before changing production.
Writing NetworkPolicies when the CNI does not enforce them — false sense of safety.
Lab shortcuts (open security groups, admin roles, skip approvals) must not ship unchanged.
Changing production without a rollback path
Always know how to revert (previous artefact, prior release, state rollback, DNS failback).
Best Practices¶
- Encode Kubernetes Security Hardening changes as code and review them in pull requests
- Pin versions (images, modules, actions, provider plugins)
- Separate environments with clear promotion gates
- Alert on symptoms with runbooks attached
- Destroy lab resources; tag everything with owner and expiry where possible
Troubleshooting¶
| Symptom | Likely cause | Fix |
|---|---|---|
| Auth / permission denied | Wrong identity, policy, or scope | Check caller identity, roles, and least-privilege policies |
| Timeout / no route | Network, DNS, security group, or endpoint | Trace path, DNS, and allow-lists before retrying |
| Drift / unexpected plan | Manual change or wrong state/workspace | Reconcile desired vs actual; avoid click-ops on managed resources |
| Pipeline/job red | Flaky step, cache, or missing secret | Read failing step logs; bisect recent workflow/config changes |
| Cost spike | Idle load balancer, NAT, oversized compute | Inventory billable resources; stop/delete labs promptly |
Summary¶
Kubernetes Security Hardening is essential for Cloud and DevOps engineers working with kubernetes. Practise the lab until the inspection and change path is muscle memory, then continue the track.
Interview Questions¶
- What does a Pod securityContext control?
- Why drop Linux capabilities and disable privilege escalation?
- What is the purpose of readOnlyRootFilesystem?
- How do admission policies complement runtime securityContext settings?
- What is a practical hardening checklist for a typical web Deployment?
Sample answer — question 2
Dropping capabilities and setting allowPrivilegeEscalation false reduce the blast radius if a process is compromised, preventing easy root or capability grabs inside the container.
Sample answer — question 4
Admission policies enforce organisational baselines so individual manifests cannot opt into privileged mode. Runtime settings protect each Pod; admission makes the standard mandatory.