Kubernetes Security Hardening: A Production-Grade Guide for 2026
Running Kubernetes in production means operating one of the most complex distributed systems ever built. The default configuration is optimized for getting started quickly, not for security. This guide covers the critical security controls every production cluster needs.
Understanding the Kubernetes Attack Surface
Before hardening, understand what you're protecting:
- API Server: The control plane's single point of entry—if compromised, everything is lost
- etcd: Stores all cluster state including secrets—must encrypt at rest
- Kubelet: Node-level agent that can be exploited for container escape
- Container runtime: The final layer before workloads execute
Real-world breaches almost always follow the same pattern: exposed service → container escape → lateral movement to API server → cluster takeover.
Pod Security Standards (PSS)
PSP was deprecated in 1.21 and removed in 1.25. The replacement is Pod Security Standards with the Pod Security Admission controller:
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: v1.28
pod-security.kubernetes.io/warn: restricted
The restricted profile enforces:
runAsNonRoot: true- Read-only root filesystem
- Dropped ALL capabilities
- No privilege escalation
- Seccomp profile required
Compliant pod spec:
spec:
securityContext:
runAsNonRoot: true
runAsUser: 10001
seccompProfile:
type: RuntimeDefault
containers:
- name: app
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: [ALL]
RBAC: Principle of Least Privilege
kubectl get clusterrolebindings -o json | \
jq '.items[] | select(.roleRef.name == "cluster-admin") |
{name: .metadata.name, subjects: .subjects}'
Create minimal service accounts:
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
namespace: production
automountServiceAccountToken: false
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: app-role
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["app-config"]
verbs: ["get"]
Network Policies: Zero-Trust Networking
# Default deny all traffic
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
kind: NetworkPolicy
spec:
podSelector:
matchLabels:
app: backend
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- port: 8080
External Secrets Operator
Never store sensitive data in Kubernetes Secrets directly. Use External Secrets Operator with AWS Secrets Manager or Vault:
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: database-credentials
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets
kind: SecretStore
target:
name: db-credentials
data:
- secretKey: DB_PASSWORD
remoteRef:
key: prod/database/credentials
property: password
Runtime Security with Falco
Falco detects anomalous behavior at runtime using eBPF probes:
- rule: Shell in Container
desc: A shell was spawned in a container
condition: >
container and spawned_process and shell_procs and
not proc.pname in (shell_binaries)
output: >
Shell spawned (user=%user.name container=%container.id
image=%container.image.repository shell=%proc.name)
priority: WARNING
OPA Gatekeeper for Policy Enforcement
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: requirelabels
spec:
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package requirelabels
violation[{"msg": msg}] {
provided := {label | input.review.object.metadata.labels[label]}
required := {label | label := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg := sprintf("Missing required labels: %v", [missing])
}
Security Checklist
- etcd encrypted at rest with AES-GCM
- API server anonymous auth disabled
- Network policies with default deny
- Pod Security Standards enforced (restricted profile)
- All secrets in External Secrets Operator
- Falco deployed for runtime detection
- OPA Gatekeeper for policy enforcement
- Audit logging to SIEM
- Regular RBAC audits
- Image scanning in CI/CD (Trivy, Snyk)
Kubernetes security requires continuous monitoring, regular audits, and staying current with CVEs affecting cluster components.