A Kubernetes network policy defines which network traffic is allowed between Pods, namespaces and the outside world. Without one, most clusters let every Pod reach every other Pod, whether that connection is actually needed or not. A network policy lets you restrict that on purpose, down to exactly the connections your application really uses.
I run Kubernetes clusters in production and introduced network segmentation there myself, step by step over time, along with every pitfall that comes with it. You can find all my Kubernetes articles collected on the Kubernetes page.
What a kubernetes network policy controls
A network policy is its own Kubernetes object that defines, for one or more Pods, which incoming (ingress) and outgoing (egress) traffic is allowed. It acts like a firewall at the Pod level, not at the node or whole-cluster level. A rule only ever applies to the Pods matched by its podSelector, every other Pod stays unaffected.
One thing matters here: network policies are additive. If several rules match the same Pod, the union of all allowed connections applies, no rule can restrict what another one allows. That is a real difference from RBAC, where a missing permission automatically means a denial. With network rules, you have to make sure yourself that only what you actually want to allow ends up allowed.
Without a network policy: why every Pod can talk to every other Pod
In a freshly set up cluster there is no restriction by default: every Pod can reach every other Pod by its IP address, across namespace boundaries. That is convenient when you are getting started, but a real risk in production. If a single Pod gets compromised, it can freely try to reach databases, internal APIs or other namespaces.
This is exactly where the network policy comes in, on top of RBAC and Pod Security Standards. RBAC controls who may create objects through the Kubernetes API, and Pod Security Standards control how a Pod itself may be configured, while a network policy controls who a running Pod is allowed to talk to over the network. I cover how these three layers work together in Kubernetes Pod Security Standards.
Default deny as your starting point
The most common recommendation for getting started is to first block all traffic in a namespace and then deliberately allow only what is needed. This default deny pattern is the safest starting point, because from there you only ever add exceptions instead of patching holes into an already open configuration.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: shop
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
An empty podSelector matches every Pod in the shop namespace. Since spec defines neither ingress nor egress rules, but both directions are switched on under policyTypes, this policy blocks all incoming and outgoing traffic for every Pod in the namespace. From here you add, application by application, exactly the connections it actually needs.
Namespace and Pod selectors: allowing traffic on purpose
After a default deny, you need rules that reopen exactly the connections your application requires. Two selectors are available, and you can combine them: podSelector picks Pods by their labels, namespaceSelector picks whole namespaces by their labels.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-api-from-frontend
namespace: shop
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
This rule allows incoming traffic on port 8080 to every Pod labeled app: api, but only from Pods labeled app: frontend in the same namespace. If you also want to allow that access from another namespace, combine podSelector and namespaceSelector inside the same from entry, then both conditions have to match at once. Separate entries in the from list, on the other hand, work like a logical or.
Egress rules and the DNS exception people forget
Outgoing traffic is easy to overlook when you start out, because an application without egress rules can no longer make new connections, yet it still seems to start up cleanly as long as it doesn't actually try to reach anything. As soon as you restrict egress with policyTypes: [Egress], you need at least one rule that allows DNS access, otherwise the Pod cannot even resolve service names.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-egress-dns
namespace: shop
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
This rule allows every Pod in the namespace outgoing connections to the cluster's DNS Pods on port 53, over both UDP and TCP. Without this exception, applications often fail with hard to diagnose timeouts, because name resolution for an internal service does not work in the first place. For traffic that leaves the cluster entirely, such as an external API, you add a further rule using ipBlock with the matching CIDR range.
Requirement: your CNI has to support network policies
A network policy is only a description, it gets enforced by your cluster's network plugin, the Container Network Interface (CNI). Not every CNI can do that. If you apply a network policy in a cluster whose CNI ignores it, the object is accepted without complaint but never enforced, a dangerous silent failure.
| CNI plugin |
Network policy support |
| Flannel (default configuration) |
enforces none by itself |
| Calico |
supported |
| Cilium |
supported, plus its own extended rules |
| Antrea |
supported, plus its own cluster-wide policies |
Before you roll out a default deny rule in production, check which CNI your cluster actually runs. k3s is a special case many people misread: it ships Flannel as the CNI but additionally starts an embedded kube-router network policy controller that enforces the rules (k3s documentation on networking services). That is exactly how my clusters run, on the k3s default setup, and I use network policies there mainly to keep client systems separated from each other. The full reference for fields and behavior is in the Kubernetes documentation on network policies.
Frequently asked questions
What is a kubernetes network policy deny all rule?
That is the common name for a policy with an empty podSelector and both entries in policyTypes, but without any defined ingress or egress rules. It blocks all traffic for every Pod in the namespace and is usually the first step before adding targeted exceptions.
How does kubernetes network policy egress work in practice?
Egress rules allow outgoing traffic from a Pod, selected by destination Pods, destination namespaces or IP ranges, each with the allowed ports. Without at least one egress rule for DNS on port 53, a Pod with restricted egress usually cannot even resolve internal service names.
What counts as kubernetes network policy best practices?
From my own experience: start with a default deny rule per namespace, then open access as narrowly as possible using labels rather than whole namespaces, never forget the DNS exception, and always try a new rule in a test cluster with the same CNI before it goes to production.
Is a network policy enough to secure a cluster on its own?
No. A network policy only controls network traffic between Pods. Who may create objects through the API is controlled by RBAC, how a Pod has to be configured is controlled by Pod Security Standards and additional admission policies. All three layers complement each other, none of them replaces the others.
Where to go next
A network policy is the network side of a defense that starts with cleanly cut namespaces, as I describe in Kubernetes Namespaces Done Right, and works with stable service addresses, as covered in Kubernetes Service Types Explained. Securing the individual Pod itself is covered in Kubernetes Pod Security Standards.
My suggestion for getting started: first check which CNI your cluster runs, then apply a default deny rule in a non-critical namespace and watch which connections actually fail before you touch production namespaces.
My Kubernetes Practical Guide published by Rheinwerk Computing devotes chapter 7 to governance and security in Kubernetes, with its own sections on RBAC and policies. I do not cover the network policy itself there, it belongs technically to your cluster's CNI choice more than to a classic policy engine. You can find all the information about the book on my Kubernetes page.