Kubernetes Security Best Practices (2026)
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.
Cluster and API server
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.
Workloads
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.
Networking
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.
Supply chain
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.
Secrets
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.
Runtime
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.
Start here
If the list feels long, do these four this week, in order:
- Audit RBAC and remove standing
cluster-adminand wildcard grants. - Label your namespaces with Pod Security
enforce: restricted. - Apply a default-deny NetworkPolicy per namespace.
- Wire image scanning into CI and fail on criticals.
Then layer in secrets management, admission control, and runtime detection.
The call we'd make
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.
Istio vs Linkerd: Service Mesh Comparison (2026)
A practitioner-grade breakdown of Istio and Linkerd across architecture, mTLS, traffic control, performance, and total cost of ownership.
Terraform count vs for_each (and the Errors)
A practical look at when to reach for count, when for_each saves you, and the specific errors each meta-argument tends to throw.
More from DevOps
Explore more articles in this category
GitHub Actions Workflow Lockfiles: Pin Every Action, Including the Ones You Can't See
GitHub now records the exact commit of every direct and transitive action in .github/workflows/actions.lock. Here is how to adopt it, what it fixes that SHA pinning never did, and where it still leaks.
GitHub Actions macOS 14 Retirement: Fix Your Builds Before Nov 2
GitHub retires the macOS 14 runner image on November 2, and brownouts are already failing jobs. Here is how to find every macos-14 reference and move without breaking Xcode.
PHP2Shell (CVE-2026-109618, CVE-2026-109619): Patch Before the Bots Do
Two unauthenticated RCEs in PHP core, leaked a day before the patch, with exploit attempts already logged. Here is how to tell if you are exposed and what to do tonight.
You might have missed
Evergreen posts worth revisiting.