Why the Cluster Network Is Open by Default
Every pod in a fresh Kubernetes cluster can reach every other pod. This is not a bug or a misconfiguration - it is the model the project chose deliberately.
Summary
- Definition: Kubernetes defines a flat, fully routable network where any pod can talk to any other pod, across namespaces and nodes, without NAT.
- Insight: "Open by default" is a design decision that trades security for simplicity, and it pushes segmentation up to you.
- Key Concepts: the flat network model, the CNI plugin that implements it, and NetworkPolicy objects that constrain it.
- When to Use: understand this before you ship anything to a shared or multi-tenant cluster.
- Limitations/Trade-offs: open connectivity means one compromised pod can scan and reach the entire cluster until you add policy.
- Related Topics: the Kubernetes network model, the default-deny stance, and CNI selection.
Foundations
The Kubernetes network model has one guiding rule: pods communicate without NAT, and every pod sees the same IP for itself that others use to reach it.
There are no firewalls between pods by default. The control plane assigns each pod an IP, and routing "just works" cluster-wide.
This is convenient. A frontend can call a backend by its Service without anyone configuring routes, VLANs, or security groups first.
The convenience comes from a decision the maintainers made early: keep the core simple and let plugins handle the hard parts.
Kubernetes itself does not implement networking. It delegates that to a CNI (Container Network Interface) plugin such as Calico, Cilium, or the AWS VPC CNI.
The CNI's job is to satisfy the flat-network contract. Enforcing restrictions is optional and, historically, off by default.
Mechanics & Interactions
When a pod is scheduled, the kubelet calls the configured CNI plugin to set up the pod's network namespace, assign an IP, and wire up routes.
The plugin makes that IP reachable from every node. On most clusters this is done with an overlay (VXLAN or Geneve) or with native routing (BGP or cloud route tables).
Nothing in this path inspects or filters traffic. A packet from pod A to pod B is delivered as long as the route exists, which it always does.
NetworkPolicy is the API object that changes this. It is a namespaced resource that selects pods by label and declares which ingress and egress is allowed.
Here is the subtlety that surprises people: the NetworkPolicy API is inert on its own.
NetworkPolicy objects are only enforced if the installed CNI implements policy. The API server accepts the object regardless, so a policy can exist and do nothing.
Calico and Cilium enforce policy. The default AWS VPC CNI does not on its own - it relies on a separate controller or on Cilium/Calico for enforcement.
Once a pod is selected by at least one policy for a direction, the model flips for that pod. Traffic in that direction is denied unless a rule explicitly allows it.
Pods not selected by any policy stay fully open. Selection is the switch that turns a pod from allow-all to allow-list.
Advanced Considerations & Applications
The open default is why lateral movement is the dominant concern in Kubernetes security. A single exploited container can probe every Service and pod IP in the cluster.
Multi-tenant clusters make this acute. Without policy, one team's workload can reach another team's database pods directly, bypassing any Service-level auth you assumed protected them.
The remedy is a per-namespace default-deny policy plus targeted allow rules. This turns the flat network into a segmented one without changing the CNI's routing behavior.
Enforcement scope matters at scale. Native NetworkPolicy is pod-to-pod and DNS-aware only through explicit egress rules, so DNS and control-plane egress must be allowed on purpose.
Some CNIs extend the model. Cilium and Calico add cluster-wide policies, CIDR-based egress, L7 (HTTP/gRPC/Kafka) rules, and FQDN-based egress that the core API cannot express.
For regulated environments, treat "no policy" as a finding. Default-allow is acceptable in a throwaway dev cluster and rarely acceptable in production.
Common Misconceptions
"A NetworkPolicy blocks traffic as soon as I create it." Only if your CNI enforces policy. On a non-enforcing CNI the object is accepted and ignored.
"Namespaces isolate the network." They do not. Namespaces are an organizational and RBAC boundary, not a network boundary. Cross-namespace pod traffic flows freely by default.
"Services provide access control." A Service is load balancing and discovery. Any pod can also hit the backend pod IPs directly, bypassing the Service entirely.
"Deleting all policies is safe." Deleting the last policy selecting a pod returns it to allow-all, which can silently re-open paths you meant to keep closed.
"The AWS VPC CNI enforces NetworkPolicy out of the box." Enforcement requires enabling the network policy agent or running Calico/Cilium alongside it.
FAQs
Why did Kubernetes choose open-by-default? To keep the core small and portable, and to let CNI plugins compete on features rather than baking one firewall model into the API.
Does open-by-default mean insecure-by-default? For network segmentation, effectively yes. You must add policy to get isolation.
Can I make new clusters deny-by-default automatically? Yes, by applying a default-deny policy to each namespace, often via a controller, GitOps, or an admission policy that ships it with every namespace.
Do I need policy in a single-tenant cluster? It is still recommended, since it contains blast radius if any one workload is compromised.
Which CNIs enforce policy? Calico and Cilium do natively. AWS VPC CNI needs its policy agent enabled or a policy engine layered on top.
Is host and node traffic covered? Standard NetworkPolicy governs pod traffic. Node-level and host-endpoint controls need CNI-specific features like Calico host endpoints.
Related
- The Kubernetes Network Model
- Network Policies Basics
- Default-Deny Stance
- CNI Comparison
- Network Policies Best Practices
Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).