Skip to content

Network policies

By default, every pod in a cluster can reach every other pod, in any namespace. The flat network is a deliberate simplification — and a poor security posture the moment you run more than one team's workloads.

NetworkPolicy narrows it.

Selecting turns on default-deny

A NetworkPolicy does not add rules to a permissive baseline. The moment any policy selects a pod, that pod switches to default-deny for the directions the policy mentions, and only the listed rules are permitted.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: payments-ingress
spec:
  podSelector:
    matchLabels:
      app: payments
  policyTypes: [Ingress]
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: checkout
      ports:
        - port: 8080

Payments now accepts traffic from checkout on 8080 and nothing else. Egress is untouched, because policyTypes does not list it.

Namespace selectors need labels

namespaceSelector matches on namespace labels, not names. Namespaces have no useful labels by default beyond kubernetes.io/metadata.name, which the control plane sets automatically:

ingress:
  - from:
      - namespaceSelector:
          matchLabels:
            kubernetes.io/metadata.name: monitoring

Combining namespaceSelector and podSelector in a single from entry is an AND. Listing them as two entries is an OR. One character of YAML indentation separates "Prometheus pods in the monitoring namespace" from "anything in monitoring, plus Prometheus pods anywhere".

The CNI has to implement it

Like Ingress, the object is only a declaration. Calico, Cilium and Antrea enforce policies. Flannel, on its own, does not.

A sensible starting point

Deny everything inbound in a namespace, then open specific paths:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
spec:
  podSelector: {}
  policyTypes: [Ingress]

An empty podSelector selects every pod in the namespace. With no ingress rules, nothing is allowed in. Layer permissive policies on top per service — policies are additive, so any rule that allows traffic wins over the baseline denial.