Network policies and segmentation
Network policies and segmentation
By default every Pod can talk to every Pod in every namespace. A compromised frontend can reach the database directly.
graph LR
subgraph shop
F[frontend] -->|allowed| B[backend]
B -->|allowed| D[(db)]
F -.x.-> D
end
O[other namespace] -.x.-> B
NetworkPolicy
Selects Pods and lists what may reach them (ingress) and what they may reach (egress). Enforced by the CNI - here Calico.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: { name: db-from-backend, namespace: shop }
spec:
podSelector:
matchLabels: { app: db } # the Pods this policy protects
policyTypes: ["Ingress"]
ingress:
- from:
- podSelector:
matchLabels: { app: backend }
ports:
- { protocol: TCP, port: 5432 }
The rules of the game
- A Pod selected by no policy: everything allowed.
- A Pod selected by any policy for a direction: only what a policy allows.
- Policies are additive - there is no “deny” rule, only “allow”.
fromentries:podSelector,namespaceSelector, both combined (AND in one item, OR as separate items),ipBlock.- With egress policies, allow DNS (UDP/TCP 53 to kube-system) or nothing resolves.
# default deny in a namespace - start here
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: { name: default-deny, namespace: shop }
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
Calico extras
The standard API is namespaced and allow-only. Calico adds
(projectcalico.org/v3, visible to kubectl through the Calico API server):
| Resource | Adds |
|---|---|
NetworkPolicy (Calico) | explicit Deny and Log actions, order |
GlobalNetworkPolicy | cluster-wide rules, e.g. platform guard rails |
StagedNetworkPolicy | dry run: shows what would be denied |
| Whisker | web UI with live flow logs and policy verdicts |
kubectl port-forward -n calico-system service/whisker 8081:8081
Cilium adds L7 (HTTP path, DNS name) policies; Kubernetes itself is working on cluster-wide AdminNetworkPolicy.