A practical, layer-by-layer checklist for securing Kubernetes clusters, workloads, networking, secrets, and the software supply chain.
Kubernetes gives you a lot of power and, by default, not much protection. A fresh cluster will happily run a privileged container as root, let any pod talk to any other pod, and hand a service account a token it never needed. Securing it is less about one magic setting and more about closing gaps at every layer.
This is the checklist we actually use. It is organized by layer, but not everything carries equal weight. If you only have a week, the four items that move the needle most are: tighten RBAC, enforce Pod Security at restricted, apply a default-deny network policy, and scan your images before they ship. Everything else is important, but those four cut the blast radius of a compromise dramatically.
The control plane is the crown jewel. If someone owns the API server or etcd, they own the cluster.
RBAC least privilege: This is the highest-impact control you have. Nobody and nothing should hold cluster-admin unless a human is actively breaking glass. Audit your ClusterRoleBindings, scope roles to namespaces, and avoid wildcard verbs and resources. Pay special attention to service accounts: a pod that can create pods or read secrets cluster-wide is a lateral-movement engine.
Disable anonymous auth: Set --anonymous-auth=false on the API server so unauthenticated requests are rejected outright.
Audit logging: Turn on the audit log at a sane policy level and ship it somewhere you can query. When something goes wrong, this is often the only record of who did what.
Keep versions patched: Kubernetes drops support fast. Run a supported minor version, apply CVE patches promptly, and treat node OS and kubelet updates as part of the same cadence.
Restrict the kubelet: Disable the read-only port, require authentication and authorization for the kubelet API, and lock down node access so a single compromised node cannot enumerate the cluster.
Protect etcd: Enable encryption at rest for etcd so secrets are not sitting in plaintext on disk, restrict etcd network access to the control plane only, and use TLS for peer and client traffic.
Assume application code will get exploited. The goal is to make a container breakout useless.
The single best move here is enforcing Pod Security Admission at the restricted level per namespace:
apiVersion: v1
kind: Namespace
metadata:
name: payments
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: latest
That one label blocks privileged pods, host namespaces, and most dangerous defaults. Back it with an explicit security context on your pods:
securityContext:
runAsNonRoot: true
runAsUser: 10001
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
seccompProfile:
type: RuntimeDefault
Run as non-root and drop all Linux capabilities, adding back only what a workload genuinely needs. Read-only root filesystem stops an attacker from writing tools into the container. Refuse privileged, hostPath, and hostNetwork outside of tightly reviewed exceptions. Apply the RuntimeDefault seccomp profile, layer AppArmor where you can, and always set CPU and memory resource limits so one workload cannot starve a node.
By default every pod can reach every other pod. Fix that first with a default-deny policy per namespace, then open only the paths you need:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: payments
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
That denies all ingress and egress; you then add narrow allow rules on top. This is worth doing early because it turns a flat network into a segmented one, and it is covered in depth in Kubernetes network policies.
Beyond L3/L4 segmentation, adopt mTLS between services so traffic is encrypted and identity-verified even inside the cluster. A service mesh gives you that plus policy without changing application code. Finally, limit egress: most workloads have no business making arbitrary outbound calls, and constraining egress cuts off both data exfiltration and command-and-control.
You can lock down the cluster perfectly and still lose if you deploy a poisoned image.
Scan images for known vulnerabilities in CI and block builds that ship criticals, as described in container vulnerability scanning. Sign your images and verify signatures at admission time. Use an admission controller such as Kyverno or OPA Gatekeeper to enforce policy: no unsigned images, no latest tags, no pulls from untrusted registries. Restrict pulls to registries you control or explicitly trust. Generate an SBOM and provenance attestation for every build so you can answer "is this CVE in production" in minutes rather than days, which we cover in supply-chain security with SBOMs.
Encrypt secrets at rest (the etcd encryption above), and go one step further by keeping the source of truth outside the cluster. External secret operators and Vault let you sync secrets in at runtime with rotation and audit, instead of committing them. Never bake secrets into images and avoid passing them as plain environment variables where a crash dump or process listing can leak them. Mounted files with tight permissions beat env vars.
Prevention is not perfect, so watch what runs. Deploy runtime threat detection such as Falco to catch suspicious syscalls, shells spawned in containers, and unexpected network connections. Add drift detection so you know when a running container no longer matches the image it was deployed from, a strong signal of tampering.
If the list feels long, do these four this week, in order:
cluster-admin and wildcard grants.enforce: restricted.Then layer in secrets management, admission control, and runtime detection.
Treat the cluster as hostile from the inside. The controls that pay off first are the ones that shrink blast radius: least-privilege RBAC, restricted Pod Security, default-deny networking, and scanned, signed images. Get those solid before chasing the long tail. Kubernetes security is one slice of a broader program, so fit it into your application security best practices rather than treating it as a separate island.
Get the latest tutorials, guides, and insights on AI, DevOps, Cloud, and Infrastructure delivered directly to your inbox.
Explore more articles in this category
A service mesh solves real problems and creates new ones. This is the map: what it actually does, when it earns its cost, and how the options compare.
Your pipeline holds the keys to production and signs off on everything you ship, so harden both the pipeline itself and the artifacts it builds.
A practical walkthrough to install Istio, turn on automatic mTLS, and run a canary traffic split on Kubernetes.
Evergreen posts worth revisiting.