Network Policies and Pod Security
By default, Kubernetes implements a flat, permissive network model: every Pod can communicate with every other Pod in the cluster, across all namespaces and nodes. This means if an attacker compromises a single vulnerable public-facing web container, they can probe internal databases, payment gateways, and etcd endpoints without resistance.
To protect workloads, you must implement defense-in-depth at both the network layer (NetworkPolicies) and the process isolation layer (Pod Security Standards & SecurityContext).
Network Policies: Default Allow-All vs Zero-Trust Microsegmentation
NetworkPolicies: Microsegmentation for Pods
A NetworkPolicy is a declarative firewall specification.
Important: NetworkPolicies require a CNI plugin that supports policy enforcement (such as Calico, Cilium, or AWS VPC CNI with network policy enabled). If your CNI doesn't support them, NetworkPolicy objects will be saved but silently ignored!
Default Deny All Pattern
The golden rule of zero-trust networking: isolate namespaces with a default-deny policy, then explicitly whitelist necessary pathways:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Granular Ingress Whitelisting
Allow only the Frontend pods to connect to Backend pods on port 8080:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: production
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
Pod Security Standards (PSS)
Kubernetes replaces the deprecated PodSecurityPolicy with built-in Pod Security Admission, organized into three distinct levels:
- Privileged: Unrestricted execution. Containers can run as root, access host devices, and disable namespaces.
- Baseline: Minimally restrictive. Prevents known privilege escalations (prohibits host network, host ports, host PID).
- Restricted: Hardened best practice. Enforces non-root execution, drops all Linux capabilities, and requires read-only root filesystems.
You enforce these standards at the namespace level with simple labels:
apiVersion: v1
kind: Namespace
metadata:
name: secured-apps
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: latest
The Container SecurityContext
Even without cluster-wide admission, every deployment should define a robust securityContext:
spec:
containers:
- name: api
image: myapp:1.0
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 10001
capabilities:
drop:
- ALL
By dropping all Linux capabilities and mounting root as read-only, you eliminate the vast majority of container breakout exploits.
Enjoyed this breakdown?
Get notified when new lessons go live.