ð kubernetes-security
Use when implementing Kubernetes security best practices including RBAC, pod security policies, and network policies.
Overview
Security best practices for Kubernetes deployments.
Pod Security
Run as Non-Root
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
Read-Only Root Filesystem
spec:
containers:
- name: app
securityContext:
readOnlyRootFilesystem: true
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}
Drop Capabilities
spec:
containers:
- name: app
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
Prevent Privilege Escalation
spec:
containers:
- name: app
securityContext:
allowPrivilegeEscalation: false
privileged: false
Network Security
Network Policies
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-allow
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
RBAC
ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
namespace: default
Role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
subjects:
- kind: ServiceAccount
name: app-sa
namespace: default
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Secrets Management
Encrypt at Rest
Enable encryption for secrets at rest in etcd.
External Secrets
Use external secret management:
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: app-secrets
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: app-secrets
data:
- secretKey: password
remoteRef:
key: secret/data/app
property: password
Avoid Hardcoding
# Bad
env:
- name: DB_PASSWORD
value: "hardcoded-password"
# Good
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
Resource Limits
Prevent Resource Exhaustion
spec:
containers:
- name: app
resources:
limits:
memory: "256Mi"
cpu: "500m"
requests:
memory: "128Mi"
cpu: "250m"
LimitRange
apiVersion: v1
kind: LimitRange
metadata:
name: mem-limit-range
spec:
limits:
- max:
memory: 512Mi
min:
memory: 64Mi
type: Container
ResourceQuota
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
spec:
hard:
requests.cpu: "10"
requests.memory: 20Gi
limits.cpu: "20"
limits.memory: 40Gi
Image Security
Use Specific Tags
# Bad
image: nginx:latest
# Good
image: nginx:1.21.6
Image Pull Policies
spec:
containers:
- name: app
image: myapp:1.0.0
imagePullPolicy: IfNotPresent
Private Registries
spec:
imagePullSecrets:
- name: registry-credentials
containers:
- name: app
image: private.registry.com/myapp:1.0.0
Pod Security Standards
Restricted Profile
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
Security Scanning
# Scan manifests with kubesec
kubesec scan pod.yaml
# Scan images with trivy
trivy image nginx:1.21
# Policy validation with OPA
opa eval -d policy.rego -i manifest.yaml