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”.
  • from entries: 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):

ResourceAdds
NetworkPolicy (Calico)explicit Deny and Log actions, order
GlobalNetworkPolicycluster-wide rules, e.g. platform guard rails
StagedNetworkPolicydry run: shows what would be denied
Whiskerweb 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.

References