Kubernetes Security Best Practices
Kubernetes revolutionized the orchestration and management of containers at scale, becoming the de facto standard for deploying cloud-native applications, but its distributed architecture and inherent complexity introduce a significantly expanded attack surface compared to traditional deployment models. A typical Kubernetes cluster involves dozens of interconnected components - API server, etcd, scheduler, controller manager, kubelet, kube-proxy - each with its own potential vulnerabilities and specific hardening requirements. The dynamic nature of K8s, where pods are constantly created and destroyed, workloads migrate between nodes, and network policies must be applied in real time, makes security a multidimensional challenge that requires a defense-in-depth approach. Insecure default configurations, such as overly permissive RBAC permissions, the absence of network policies that allow unrestricted communication between pods, containers running as root with privileged capabilities, and secrets stored in plain text in unencrypted etcd, represent attack vectors commonly exploited in poorly configured K8s environments. This article explores fundamental practices for hardening Kubernetes clusters, covering role-based access control (RBAC), pod security standards, network policies for micro-segmentation, secure secrets management, admission controllers for policy enforcement, runtime security monitoring with tools such as Falco, and compliance with industry benchmarks such as the CIS Kubernetes Benchmark, providing a complete roadmap for building and operating secure Kubernetes clusters in production environments.
K8s Security Architecture
A Kubernetes cluster has multiple critical components:
- Control Plane: API Server, etcd, scheduler, controller manager
- Nodes: kubelet, kube-proxy, container runtime
- Add-ons: DNS, dashboard, ingress controllers
RBAC (Role-Based Access Control)
RBAC is the foundation of K8s security, controlling who can access what via the API server.
RBAC Configuration
# Role to read pods in a specific namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
---
# RoleBinding associates the role with a user
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: production
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
RBAC Principles
- Least privilege: Grant only the permissions needed
- Avoid ClusterAdmin: Create role-specific roles by function
- Service accounts: Each pod should have a dedicated SA
- Namespace isolation: RoleBindings instead of ClusterRoleBindings
Pod Security
Pod Security Standards
Kubernetes 1.25+ uses Pod Security Admission instead of the deprecated PSPs:
- Privileged: Unrestricted, for trusted workloads
- Baseline: Minimally restrictive, prevents known escalations
- Restricted: Heavily restricted, follows hardening best practices
Security Context
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: myapp:latest
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
Network Policies
By default, pods can communicate freely. Network Policies implement segmentation:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-allow-from-frontend
namespace: production
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
Secrets Management
- Never hardcode secrets: Use Kubernetes Secrets or external vaults
- etcd encryption: Enable encryption-at-rest for etcd
- External Secrets Operator: Integrate with Vault, AWS Secrets Manager
- Rotate secrets: Implement automatic rotation
- RBAC for secrets: Restrict who can read secrets
Image Security
- Private registries: Do not use public registries in production
- Image scanning: Trivy, Clair, Anchore for vulnerability scanning
- Image signing: Cosign to verify integrity
- Admission controllers: Validate images before deployment
- Distroless images: Minimize attack surface
Admission Controllers
- OPA/Gatekeeper: Policy-as-code for compliance
- Kyverno: Kubernetes-native policy management
- ImagePolicyWebhook: Validate image signatures
- ResourceQuota: Limit resources per namespace
- LimitRanger: Enforce CPU/memory limits
API Server Hardening
- Enable audit logging
- Use TLS for all communications
- Disable anonymous auth
- Implement API rate limiting
- Restrict access to the API server (network ACLs)
Runtime Security
- Falco: Runtime threat detection for K8s
- Sysdig Secure: Runtime protection and compliance
- Aqua Security: Full lifecycle container security
Compliance and Auditing
- CIS Kubernetes Benchmark: Hardening framework
- kube-bench: Automated CIS compliance checks
- kube-hunter: Penetration testing tool for K8s
- Audit logs: Centralize in a SIEM for analysis
Service Mesh Security
Service meshes (Istio, Linkerd) add a security layer:
- Automatic mTLS between pods
- Fine-grained authorization policies
- Traffic encryption in transit
- Observability and auditability
Final Recommendations
K8s security is a shared responsibility. Implement layered defense: RBAC, network policies, pod security, secrets management and runtime protection. Use automated compliance tools (kube-bench) and monitor continuously. Train teams in K8s security - complexity requires dedicated expertise.
