Kubernetes Network Policies Explained
Kubernetes NetworkPolicies control which pods can talk to which, at the network layer. Here's how they work and why pods are open by default.
A NetworkPolicy is a Kubernetes resource that controls which pods are allowed to send or receive traffic from which other pods, namespaces, or IP ranges. Without one, Kubernetes pods can reach any other pod in the cluster by default — flat, fully open networking. NetworkPolicies are how you introduce actual segmentation, restricting communication to only the paths your application intentionally needs.
Why pod networking starts out fully open
Kubernetes networking is designed so every pod gets its own IP address and can, by default, reach every other pod in the cluster without NAT. That flat model makes service discovery and scaling simple — pods don’t need to know about network topology to talk to each other — but it also means a compromised pod in one namespace can, by default, probe and connect to workloads in a completely unrelated namespace.
That’s a meaningfully different default than most people assume. Setting up RBAC controls who can create or modify resources through the Kubernetes API, but it says nothing about which pods can talk to which over the network at runtime — those are two separate layers of access control, and it’s easy to lock down one while leaving the other wide open.
What a NetworkPolicy actually restricts
A NetworkPolicy selects a set of pods (via label selectors, the same mechanism used throughout pods, deployments, and services) and then defines ingress and/or egress rules for traffic to and from that set. A minimal example that only allows a backend pod to receive traffic from pods labeled role: frontend:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-allow-frontend
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 8080
The critical detail: as soon as any NetworkPolicy selects a pod for a given direction (ingress or egress), that pod’s default for that direction flips from “allow all” to “deny all except what’s explicitly permitted.” A pod with no matching NetworkPolicy at all stays fully open. This all-or-nothing switch per pod is a common source of outages — adding one narrow policy to lock down ingress on a pod also silently blocks traffic you never intended to restrict, if you forgot to allow it explicitly.
Selecting by namespace, not just by pod
Policies commonly combine podSelector with namespaceSelector to express rules like “allow traffic from any pod in the monitoring namespace, regardless of its labels”:
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring
This pattern is how clusters typically isolate tenants or environments that share the same physical cluster — each namespace gets policies that permit only specific cross-namespace traffic (metrics scraping, a shared ingress controller, a shared database) while denying everything else by default. It complements — but doesn’t replace — the boundary a namespace provides on its own, since namespaces alone don’t restrict network traffic without policies layered on top.
Egress rules and default-deny
Ingress rules get most of the attention, but egress rules are just as important for limiting blast radius. A pod that can freely make outbound connections can exfiltrate data or reach an attacker-controlled endpoint even if inbound traffic is locked down tightly. A common baseline for a namespace is a default-deny policy applied to every pod, followed by narrower policies that explicitly allow only the traffic each workload actually needs:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
An empty podSelector: {} matches every pod in the namespace, and specifying no ingress or egress rules means nothing is allowed — the strictest possible starting point. From there, add allow rules incrementally as you discover what each workload legitimately needs to reach.
NetworkPolicy vs a service mesh
NetworkPolicies operate at layer 3/4 — IP addresses, ports, and protocols. They don’t understand HTTP paths, mutual TLS identity, or request-level routing. A service mesh operates at a higher layer and can enforce far more granular rules — this specific HTTP method to this specific path, encrypted end to end regardless of the underlying network. The two aren’t competitors: NetworkPolicies provide a coarse, cluster-native baseline (this pod can reach that pod, full stop), while a service mesh layers finer-grained, identity-aware control on top for teams that need it. Many clusters use NetworkPolicies alone and never need a mesh; some layer both.
It’s also worth noting NetworkPolicies require a compatible CNI plugin to actually enforce them — creating the resource with a CNI that doesn’t support NetworkPolicy enforcement will silently do nothing, which is worth verifying before relying on one as a security boundary. That’s a different concern from Kubernetes vs Docker more generally, but it’s a reminder that Kubernetes’ networking model is pluggable, and not every plugin implements every feature.
The takeaway
Kubernetes pods can reach each other freely by default, and NetworkPolicies are the primary way to change that — selecting pods by label and namespace, then explicitly allowing only the ingress and egress traffic each workload needs. The moment a pod is selected by any policy for a direction, everything not explicitly allowed in that direction is denied, which makes a namespace-wide default-deny policy plus targeted allow rules a much safer starting posture than adding restrictions piecemeal after the fact.
Tagged
Keep reading
Chisato · · 4 min read Kubernetes Init Containers Explained
Init containers run to completion before a pod's main containers start, making them the standard way to handle setup steps and startup ordering.
Chisato · · 4 min read Kubernetes Service Types: ClusterIP vs NodePort vs LoadBalancer
Kubernetes offers four Service types for exposing pods on the network. How ClusterIP, NodePort, LoadBalancer, and ExternalName each route traffic.
The Lycoris Team · · 4 min read What Is Container Image Scanning?
Container image scanning checks a container's layers for known vulnerabilities and secrets before it ships. How it works and where to run it.