Security Best Practices

Harden workloads with security contexts, least privilege, and network policies.

A running cluster is a big attack surface. A few habits dramatically reduce risk.

Run containers safely

Use a securityContext to drop privileges:

  • runAsNonRoot: true — refuse to run as root.
  • readOnlyRootFilesystem: true — block writes to the image.
  • allowPrivilegeEscalation: false — prevent gaining more rights.
  • Drop all Linux capabilities, then add back only what is needed.

More layers

  • NetworkPolicies — restrict which Pods can talk to which, defaulting to deny.
  • RBAC least privilege — minimal Roles per ServiceAccount.
  • Image scanning and pinned image digests to avoid tampered images.
  • Keep Secrets out of Git and enable encryption at rest.

Example

Example · yaml
apiVersion: v1
kind: Pod
metadata:
  name: hardened
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
  containers:
    - name: app
      image: myapp:1.0
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop: ["ALL"]

When to use it

  • A security team enforces a baseline Pod Security Standard on the dev namespace, blocking privilege escalation and host namespace sharing.
  • A developer sets securityContext.runAsNonRoot=true on their pod so the container cannot run as root even if the image defaults to UID 0.
  • A platform team drops all Linux capabilities and adds back only NET_BIND_SERVICE for a web server that needs to bind port 80.

More examples

Enforce Pod Security Standards

Applies the restricted Pod Security Standard to the production namespace, blocking any pod that does not meet the policy.

Example · bash
kubectl label namespace production \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/warn=restricted

kubectl get namespace production --show-labels | grep pod-security

Secure securityContext

Configures a hardened security context: non-root user, no privilege escalation, read-only root filesystem, and all capabilities dropped except NET_BIND_SERVICE.

Example · yaml
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsGroup: 2000
  containers:
    - name: app
      image: myapp:1.0
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop: [ALL]
          add: [NET_BIND_SERVICE]

Verify pod security policy

Attempts to create a root-user pod in a restricted namespace and shows the forbidden error enforced by Pod Security Standards.

Example · bash
# Try to deploy a privileged pod in the restricted namespace
kubectl run priv-test --image=nginx \
  --overrides='{"spec":{"securityContext":{"runAsUser":0}}}' \
  -n production
# Error: pods priv-test is forbidden: violates PodSecurity

# View active policies per namespace
kubectl get ns production -o jsonpath='{.metadata.labels}'

Discussion

  • Be the first to comment on this lesson.