Lesson 23 / 31

Kubernetes Workload Hardening

Configure pod security contexts, Pod Security Admission and network policies to limit what a compromised container can do.

By · 15 years in web development

Limiting the blast radius

Assume a container will eventually be compromised; hardening decides how far the attacker gets. In the pod's securityContext, set runAsNonRoot: true, allowPrivilegeEscalation: false, readOnlyRootFilesystem: true, drop all Linux capabilities and use the RuntimeDefault seccomp profile to block rarely needed system calls. Never mount the host filesystem or Docker socket and avoid privileged: true. Kubernetes enforces these patterns with Pod Security Admission using the Pod Security Standards: privileged (no restrictions), baseline (blocks known privilege escalations) and restricted (current hardening best practice), applied per namespace with labels. NetworkPolicies restrict which pods can talk to which, though they need a network plugin that enforces them; start with default-deny and allow only required flows. Finally, give each workload its own ServiceAccount with minimal RBAC, and disable token automounting when the pod does not call the Kubernetes API.

A restricted-compliant Deployment

These settings satisfy the restricted Pod Security Standard. The namespace label makes the API server reject pods that do not.

apiVersion: v1
kind: Namespace
metadata:
  name: shop
  labels:
    pod-security.kubernetes.io/enforce: restricted
---
apiVersion: apps/v1
kind: Deployment
metadata: { name: api, namespace: shop }
spec:
  replicas: 2
  selector: { matchLabels: { app: api } }
  template:
    metadata: { labels: { app: api } }
    spec:
      automountServiceAccountToken: false
      securityContext:
        runAsNonRoot: true
        seccompProfile: { type: RuntimeDefault }
      containers:
        - name: api
          image: registry.example.com/shop/api@sha256:<digest>
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities: { drop: ["ALL"] }

A hostel room, not the warden's office

If a guest misbehaves in one hostel room, locked doors, no master key and corridor rules keep the damage to that room. Security contexts and network policies are those locks and rules for each pod.

Secrets are only base64

Kubernetes Secret values are base64-encoded, not encrypted. Enable encryption at rest for etcd, restrict get secrets in RBAC, or sync from an external secret manager.

Quick check: Which Pod Security Standard level represents current pod hardening best practice?

  • privileged
  • baseline
  • restricted
  • default
Answer

restricted — restricted is the most locked-down level; baseline blocks known escalations; privileged is unrestricted.