Kubernetes Security Best Practices


Kubernetes security is complex because the attack surface spans multiple layers: containers, clusters, networks, and cloud infrastructure. This guide covers the most impactful security practices for production Kubernetes deployments.





Pod Security Standards





Kubernetes deprecated PodSecurityPolicies in favor of Pod Security Admission (PSA), which enforces three security levels:




* **Privileged**: No restrictions (for system-level pods).

* **Baseline**: Prevents known privilege escalations.

* **Restricted**: Strong pod hardening.




Apply PSA via namespace labels:






apiVersion: v1


kind: Namespace


metadata:


name: production


labels:


pod-security.kubernetes.io/enforce: restricted


pod-security.kubernetes.io/enforce-version: latest


pod-security.kubernetes.io/audit: restricted







The `restricted` level enforces that containers cannot run as root, cannot use host networking, and cannot mount arbitrary host paths.





Running Containers as Non-Root





Never run containers as root in production:






apiVersion: v1


kind: Pod


metadata:


name: secure-app


spec:


securityContext:


runAsNonRoot: true


runAsUser: 1000


runAsGroup: 3000


fsGroup: 2000


seccompProfile:


type: RuntimeDefault


containers:


- name: app


image: myapp:1.0.0


securityContext:


allowPrivilegeEscalation: false


capabilities:


drop: ["ALL"]


readOnlyRootFilesystem: true







Use `seccompProfile: RuntimeDefault` to apply the container runtime's default seccomp profile. Drop all capabilities and only add back what is absolutely necessary.





Network Policies





By default, all pods can communicate with each other. Network policies restrict this:






apiVersion: networking.k8s.io/v1


kind: NetworkPolicy


metadata:


name: api-network-policy


namespace: production


spec:


podSelector:


matchLabels:


app: api


policyTypes:


- Ingress


- Egress


ingress:


- from:


- podSelector:


matchLabels:


app: frontend


ports:


- port: 3000


egress:


- to:


- podSelector:


matchLabels:


app: database


ports:


- port: 5432







Start with a deny-all policy and add allow rules incrementally. Use namespace isolation for multi-tenant clusters.





Role-Based Access Control (RBAC)





Apply the principle of least privilege to all service accounts:






apiVersion: v1


kind: ServiceAccount


metadata:


name: app-sa


namespace: production


---


apiVersion: rbac.authorization.k8s.io/v1


kind: Role


metadata:


namespace: production


name: app-role


rules:


- apiGroups: [""]


resources: ["pods"]


verbs: ["get", "list", "watch"]


- apiGroups: [""]


resources: ["configmaps"]


verbs: ["get"]


---


apiVersion: rbac.authorization.k8s.io/v1


kind: RoleBinding


metadata:


namespace: production


name: app-role-binding


subjects:


- kind: ServiceAccount


name: app-sa


namespace: production


roleRef:


kind: Role


name: app-role


apiGroup: rbac.authorization.k8s.io







Service accounts should only have permissions required for their specific function. Use `Role` for namespace-scoped access and `ClusterRole` only for cluster-wide resources.





Secrets Management





Kubernetes Secrets are base64-encoded, not encrypted by default. Enable encryption at rest:






# Create encryption config


cat > encryption-config.yaml <

apiVersion: apiserver.config.k8s.io/v1


kind: EncryptionConfiguration


resources:


- resources:


- secrets


providers:


- kms:


name: myKMS


endpoint: unix:///var/run/kmsplugin/socket.sock


- aescbc:


keys:


- name: key1


secret: $(openssl rand -base64 32)


EOF







For production, use external secrets management:






apiVersion: external-secrets.io/v1beta1


kind: ExternalSecret


metadata:


name: db-credentials


spec:


secretStoreRef:


name: aws-secret-store


kind: SecretStore


target:


name: db-credentials


data:


- secretKey: password


remoteRef:


key: production/db/password







External Secrets Operator syncs secrets from AWS Secrets Manager, GCP Secret Manager, or HashiCorp Vault into Kubernetes Secrets.





Image Security





Only run images from trusted registries:






apiVersion: v1


kind: Pod


spec:


containers:


- name: app


image: registry.example.com/myapp:1.0.0


imagePullPolicy: Always







Use image scanning in CI/CD:






# Scan container images before deployment


trivy image registry.example.com/myapp:1.0.0







Configure admission controllers to reject images with critical vulnerabilities.





Resource Limits





Set resource limits on every container to prevent resource starvation:






resources:


requests:


memory: "256Mi"


cpu: "250m"


limits:


memory: "512Mi"


cpu: "500m"







CPU limits throttle excessive usage, while memory limits terminate containers that exceed their allocation.





Runtime Security





Use Falco for runtime threat detection:






helm install falco falcosecurity/falco \


--set falco.driver.kind=modern_bpf







Falco detects anomalous behavior: shell in a container, unexpected file system access, suspicious network connections. It can trigger alerts or kill offending pods.





Audit Logging





Enable Kubernetes audit logging:






# kube-apiserver configuration


apiServer:


audit:


enabled: true


logPath: /var/log/kubernetes/audit.log


policy:


rules:


- level: RequestResponse


resources:


- group: ""


resources: ["secrets"]


- level: Metadata


resources:


- group: ""


resources: ["pods", "deployments"]







Ship audit logs to a SIEM for analysis. Monitor for unauthorized API access attempts.





Summary





Kubernetes security requires defense in depth: Pod Security Admission for pod hardening, network policies for segmentation, RBAC for access control, external secrets for sensitive data, and runtime security for threat detection. Start with pod security -- run containers as non-root, drop capabilities, and enable seccomp. Add network policies for isolation. Finally, implement RBAC and secrets management. Most Kubernetes compromises exploit misconfigurations rather than software vulnerabilities -- hardening these configurations is the highest-impact security investment.