Skip to content

Networking

Think of a Network Policy as a Firewall for Pods. By default, Kubernetes has a "Flat Network" philosophy: every pod can talk to every other pod. A Network Policy is how you break that philosophy to keep your data safe.


1. Why do we need them? (The "Blast Radius")

In a cluster without policies:

  • If a hacker compromises your Frontend Nginx pod, they can immediately "reach out" and talk to your Database pod.

  • They can scan your whole network, find your internal APIs, and steal data.

With Network Policies, you create Islands. Even if someone breaks into the Frontend, they can only go where you explicitly allowed them to go (e.g., only to the Backend API on port 8080).


2. The 3 Golden Rules of NetPol

Before looking at YAML, you have to understand these three behaviors:

  1. Additive Only: There is no such thing as a "Deny" rule. You only write "Allow" rules.

  2. The "Isolation" Trigger: As soon as a pod is selected by a Network Policy, it becomes Isolated. It stops talking to everyone except what is in your "Allow" list.

  3. No Policy = Open Bar: If no policy selects a pod, it's wide open.


3. Real-World Examples

Example A: The "Default Deny" (The Deadbolt)

This is the first thing you should apply to a production namespace. It locks everything down so nothing can talk to anything. You start from zero and "allow" only what's necessary.

YAML

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
spec:
  podSelector: {} # {} means "Select ALL pods in this namespace"
  policyTypes:
  - Ingress
  - Egress
  # Since there are no 'ingress' or 'egress' rules defined below,
  # everything is blocked by default.

Example B: The "Database Shield"

Imagine a database that should only be touched by the "Backend" app.

YAML

spec:
  podSelector:
    matchLabels:
      app: mongodb       # The pod we are protecting
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: backend   # The only pod allowed in
    ports:
    - protocol: TCP
      port: 27017        # Only on this specific port

Example C: Cross-Namespace Access

Sometimes your "Monitoring" tool is in a different namespace. You have to use a namespaceSelector.

YAML

  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: monitoring # Allow from the monitoring namespace

4. How to read the YAML (The "Dash" Secret)

This is where everyone trips up. Look at these two snippets:

Snippet 1 (AND logic):

YAML

  from:
  - podSelector: { matchLabels: { role: client } }
    namespaceSelector: { matchLabels: { user: admin } }

Because there is only one dash, this means: "Allow if the pod has label role: client AND it is in a namespace labeled user: admin."

Snippet 2 (OR logic):

YAML

  from:
  - podSelector: { matchLabels: { role: client } }
  - namespaceSelector: { matchLabels: { user: admin } }

Because there are two dashes, this means: "Allow if the pod has label role: client OR if the traffic comes from any pod in the user: admin namespace."


5. Summary Cheat Sheet

Situation podSelector namespaceSelector
Same Namespace Use podSelector Leave out
Different Namespace Use podSelector Use namespaceSelector
The whole internet Leave out Use ipBlock
All pods in namespace {} Leave out

Export to Sheets

One final warning: Remember that Network Policies are enforced by the CNI (the network plugin). If you are using a basic setup like Flannel, these YAMLs will successfully "Apply" but they will do absolutely nothing. You need something like Calico, Cilium, or Azure/AWS CNI to actually block the traffic.

Does the "AND vs OR" logic make the exercise you just passed feel a bit more "wrong" now?