Command Palette

Search for a command to run...

Hectal
PHASE 3Intermediate ~14 min· topic 3 of 4

Topic 3.3

NetworkPolicy: Locking Down Pod-to-Pod Traffic

In one line

By default, every pod in a cluster can reach every other pod — a NetworkPolicy is how you actually restrict that, enforcing a genuine allow-list of exactly which traffic should be permitted.

0/4 · 0%

Think of it like this

An office building with every door unlocked by default — anyone can walk into any room. A NetworkPolicy is the decision to actually install locks and issue keys only to the specific people who genuinely need access to a specific room, rather than leaving everything open by default.

Key ideas

  1. 01

    By DEFAULT, Kubernetes networking is fully open — ANY pod can send traffic to ANY other pod in the cluster, regardless of namespace (Topic 2.2's namespace separation is organizational, NOT a network boundary on its own, exactly as that topic's trade-off flagged). This is genuinely convenient for getting started, but a real security gap in any production cluster handling sensitive workloads.

  2. 02

    A NETWORKPOLICY defines rules restricting which traffic is allowed TO and/or FROM a set of pods (selected by labels, exactly like a Service) — once ANY NetworkPolicy selects a given pod, that pod's traffic becomes DEFAULT-DENY for whatever direction (ingress/egress) that policy covers, and only traffic explicitly matching an ALLOW rule is permitted through.

  3. 03

    A genuinely common, important pattern: a strict DEFAULT-DENY-ALL policy applied to an entire namespace, followed by SPECIFIC allow rules for exactly the traffic that should actually be permitted (a frontend pod can reach a backend pod on port 8080; nothing else can reach the backend at all) — this mirrors the exact same 'default deny, then explicitly allow' principle Linux's own course covered for firewalls (Phase 4.3).

  4. 04

    NetworkPolicy enforcement requires a CNI (Container Network Interface) plugin that actually SUPPORTS it — not every networking plugin does, and creating a NetworkPolicy on a cluster whose CNI doesn't enforce it will silently have NO EFFECT AT ALL, a genuinely important and easy-to-miss gotcha worth confirming before relying on NetworkPolicy for real security.

  5. 05

    kubectl get networkpolicy lists policies in a namespace, and kubectl describe networkpolicy <name> shows exactly which pods it selects and what traffic it allows — genuinely useful both for auditing what's actually locked down and for debugging why traffic that should be allowed is unexpectedly being blocked.

Code & diagrams

NetworkPolicyDefaultDenydiagram

Default deny, then one explicit allow rule — the same 'firewall' pattern from Linux's own course, applied inside the cluster.

Rendering diagram…
network-policy.yamlmarkdown

Deny everything to the backend by default, then allow only the frontend.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}       # selects EVERY pod in the namespace
  policyTypes: ["Ingress"]
  # no ingress rules specified = deny all incoming traffic by default
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend        # this policy applies to backend pods specifically
  policyTypes: ["Ingress"]
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend   # ONLY pods labeled app=frontend may reach backend
      ports:
        - protocol: TCP
          port: 8080
networkpolicy.shmarkdown

Confirm the lockdown actually works, from both an allowed and a blocked pod.

kubectl apply -f network-policy.yaml

# From a pod labeled app=frontend — this should succeed
kubectl run test-frontend --labels="app=frontend" --rm -it --image=busybox -- \
  wget -qO- --timeout=3 http://backend-svc:8080

# From a pod WITHOUT that label — this should time out / fail
kubectl run test-other --rm -it --image=busybox -- \
  wget -qO- --timeout=3 http://backend-svc:8080

# Inspect exactly what a policy allows
kubectl describe networkpolicy allow-frontend-to-backend -n production

Explain it without notes

01

Why is it a real security gap that Kubernetes' default networking allows every pod to reach every other pod, and why doesn't putting pods in separate namespaces fix this by itself?

02

You apply a NetworkPolicy on your cluster, but traffic doesn't seem to be restricted at all, even after waiting. What's the most likely explanation?

Practice

01

If your cluster's CNI supports NetworkPolicy, apply the default-deny-all and allow-frontend-to-backend example policies, then confirm from a correctly-labeled test pod that access succeeds, and from an unlabeled one that it's blocked.

02

Check what CNI plugin your cluster uses (kubectl get pods -n kube-system, looking for the networking component) and look up whether it documents NetworkPolicy support.

Trade-offs

  • ↔

    A strict default-deny NetworkPolicy posture is significantly more secure, but it requires genuinely knowing and explicitly declaring every legitimate communication path in advance — get one allow rule wrong or forget one, and a real, working dependency between two services silently breaks, which is exactly why introducing NetworkPolicy on an existing, already-running cluster benefits from careful, incremental rollout (auditing actual traffic patterns first) rather than switching to default-deny all at once.

Done when you can

  • I understand Kubernetes networking is fully open between pods by default, unless a NetworkPolicy says otherwise.

  • I know namespaces alone do not provide network isolation, and NetworkPolicy is what actually does.

  • I know NetworkPolicy enforcement depends on the cluster's CNI plugin supporting it.