Your first policy: Kubernetes NetworkPolicy

Your first policy: Kubernetes NetworkPolicy

Every pod in a fresh cluster can talk to every other pod - a flat network where one compromised workload can reach all the others. This track walks up the four policy types that fix that, from the one your cluster already supports to Calico's cluster-wide controls. We start at the bottom rung: the upstream Kubernetes NetworkPolicy (networking.k8s.io/v1).

What you'll learn

What is a Kubernetes NetworkPolicy?

A NetworkPolicy (networking.k8s.io/v1) is the policy type built into every Kubernetes cluster - the portable baseline the rest of this track builds on. It is namespaced and allow-list only: you can't write a deny, you can only name what's permitted, and the act of selecting a pod flips it to default-deny. Its entire field surface is small:

Field Purpose
spec.podSelector which pods in this namespace the policy governs (matchLabels/matchExpressions); empty selects every pod in the namespace
spec.policyTypes Ingress, Egress, or both - the directions this policy default-denies
spec.ingress[].from / spec.egress[].to the allowed peers: podSelector, namespaceSelector, or ipBlock (a CIDR)
spec.ingress[].ports / egress[].ports allowed protocol + port (plus endPort for a range)

Two properties define it: it is namespace-scoped (a bare podSelector only sees local pods - crossing namespaces needs a namespaceSelector), and it has no action, no order, no tiers - every rule is an implicit allow. Those exact gaps are what the cluster-scoped and Calico kinds later in this track fill.

The policy

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-allow-frontend
  namespace: prod
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - protocol: TCP
          port: 8080

What to observe

Allowed

Denied

Untouched (still open)

The trap is thinking you "denied" the database. You didn't. A KNP only constrains the pods its podSelector matches. Until something selects prod/database, it accepts everyone. Default-deny is per-selected-pod, not per-namespace.

Recap

A Kubernetes NetworkPolicy is namespaced, selects pods by label, and the act of selecting flips those pods to default-deny - you then add back the flows you trust. Next: reaching across namespaces, and the limits that make you want a bigger tool.