Network Policies in Kubernetes
A patient, plain-English guide to the rules that decide which pods may talk to which, so a single compromised application can never wander freely through your whole cluster.
Imagine a large office building where every internal door is propped open. Staff can walk from the reception desk to the finance room, from the kitchen to the server room, and from the mail room to the manager’s office. It is wonderfully convenient. Then one day a visitor slips in through the front door, pretending to deliver a parcel. Because nothing is locked, that stranger can wander anywhere, open any cabinet, and read any paper on any desk.
A fresh Kubernetes cluster behaves exactly like that building. By default, every pod can talk to every other pod, in every part of the cluster, on every port. Nothing is locked. It makes learning easy, and it makes real life dangerous. If an attacker breaks into one small, forgotten application, the open network lets them reach your databases, your internal tools, and your payment services.
A Network Policy is how you close and lock those internal doors, while leaving open exactly the ones people need. In this guide you will learn what a Network Policy is, how Kubernetes enforces it, how to read and design rules in plain words, how to avoid the classic traps that break DNS or lock you out, and how to roll policies out safely. No earlier knowledge is needed. Every new word is explained the first time it appears, and there is no code to copy. Instead, you will get pictures, analogies, and worked examples.
1Why an Open Network Is a Risk
The kindest default for learning is the most dangerous default for production.
Kubernetes was designed so that applications could find and reach each other with no fuss. Every pod gets its own address, and every pod can reach every other pod’s address directly. There is no firewall between them unless you build one. This is called a flat network: one big open space, with no walls inside.
A flat network is a gift to developers. A web service can call a database without asking anyone. A new microservice can start talking to its neighbors immediately. But it is also a gift to attackers. Security people call the resulting danger lateral movement: once an intruder controls one pod, they can move sideways to other pods, probing them one after another until they find something valuable.
Think of a ship without watertight compartments. If one section is damaged and floods, the water spreads everywhere and the ship sinks. A ship with sealed compartments limits the flood to one section. Network Policies are the sealed compartments of a cluster: they limit how far any single problem can spread.
What can go wrong on a flat network
A weak app becomes a doorway
An old, rarely updated service with a known flaw is compromised. From there, the attacker reaches sensitive services that never needed to talk to it.
Databases open to everyone
Any pod in the cluster can attempt to connect to a database. Only a password stands in the way.
Test traffic reaches production
A misconfigured test application accidentally calls a production service, because nothing prevents it.
Stolen data leaves freely
A compromised pod can send data to any address on the internet, since outbound traffic is also unrestricted.
Reaching the machine’s identity service
Pods can often contact the cloud provider’s metadata address and try to obtain credentials belonging to the machine.
Auditors ask for segmentation
Many security standards require that sensitive systems are separated from the rest. An open network cannot show that.
Network Policies are not magic armor. They do not fix weak passwords or buggy code. They reduce the blast radius, meaning how much damage a single failure can cause. That reduction is one of the highest-value, lowest-cost security steps in Kubernetes.
2A Quick Kubernetes Networking Refresher
A few basic ideas about how pods talk to each other are enough to follow everything that comes next.
| Word | Plain meaning | Everyday picture |
|---|---|---|
| Pod | One running copy of an application, with its own network address | One apartment with its own street address |
| Node | A computer that runs pods | An apartment building |
| Namespace | A named section of the cluster for organizing things | A floor of the building, or one company’s section |
| Label | A small tag attached to an object | A colored sticker on a door |
| Selector | A way of choosing objects that carry certain labels | “Everyone with a blue sticker, please step forward” |
| Service | A steady address that spreads traffic across a group of pods | A company’s main phone number that forwards to whoever is free |
| Ingress | An entrance that lets outside traffic reach services inside | The front door and reception desk |
| CNI plugin | The add-on that gives pods their network connections | The company that installs the building’s wiring |
| Port | A numbered doorway on an address, used by one application | A specific room number inside an apartment |
| CIDR block | A range of network addresses written in a compact form | A whole street of house numbers described in one line |
The word to remember most is label. Network Policies do not name individual pods. Pods come and go, and their addresses change constantly. Instead, policies point at groups of pods by their labels, such as “every pod labeled as the payment service”. This is what makes policies stable even as pods are replaced.
A hotel does not write guest names on every rule. It says, “Guests with a gold card may use the lounge.” Guests change every day, but the card type stays the same. Labels are the card types of a cluster.
3What Is a Network Policy?
A Network Policy is a Kubernetes object that lists which traffic is allowed to reach, or leave, a chosen group of pods.
A Network Policy is a small piece of written intent, stored in the cluster. It contains three ideas. First, which pods the policy is about. Second, which direction of traffic it controls: coming in, going out, or both. Third, which traffic is allowed, described by who the other side is and which ports are permitted.
What it is, why it exists, where it is used
What it is: an allow-list for pod traffic, written per group of pods and per namespace.
Why it exists: so that application owners can describe, in the cluster itself, which conversations are legitimate, and have everything else refused.
Where it is used: in nearly every production cluster that hosts sensitive data, several teams, or regulated workloads. It is a standard part of Kubernetes security guidance and of most compliance checklists.
Think of the guest list at a private party. The security guard at the door does not ask why you want to come in. He simply checks whether your name is on the list. If it is not, you stay outside. A Network Policy is the guest list. Nothing on the list means nobody gets in.
Network Policies only allow. There is no way, in the standard object, to write “block this specific address”. You block things by allowing everything else and leaving the unwanted item off the list. This one fact explains most of the confusion beginners feel.
4The Default: Everything Is Open
To understand what a policy changes, first see what the network looks like without one.
When no Network Policy selects a pod, that pod is non-isolated. It accepts traffic from anywhere and can send traffic anywhere. The moment a policy selects that pod for a certain direction, the pod becomes isolated for that direction. From then on, only traffic that some policy explicitly allows may pass in that direction.
flowchart LR
subgraph Open["Before any policy: flat and open"]
A1["Web pod"] B1["API pod"]
B1 C1["Database pod"]
A1 C1
D1["Unrelated tool pod"] C1
D1 A1
end
subgraph Locked["After policies: only listed paths remain"]
A2["Web pod"] --> B2["API pod"]
B2 --> C2["Database pod"]
D2["Unrelated tool pod"] -.->|"Refused"| C2
A2 -.->|"Refused"| C2
end
| Situation | Incoming traffic | Outgoing traffic |
|---|---|---|
| No policy selects the pod | Allowed from anywhere | Allowed to anywhere |
| A policy selects the pod for incoming traffic only | Only what the policies allow | Still allowed to anywhere |
| A policy selects the pod for outgoing traffic only | Still allowed from anywhere | Only what the policies allow |
| Policies select the pod for both | Only what the policies allow | Only what the policies allow |
A room with no lock lets anyone in or out. The moment you fit a lock on the entrance, only key holders can enter, but people inside can still leave freely until you fit a lock on the exit too. Incoming and outgoing are two separate locks, and you choose which to fit.
5Architecture and Components: Who Actually Enforces It?
Kubernetes stores policies, but it does not enforce them. Something else does, and if that something is missing, your policies do nothing at all.
This is the single most surprising fact for newcomers. The Kubernetes API server accepts and stores a Network Policy, but the core of Kubernetes does not filter any traffic itself. Enforcement is the job of the network plugin, also called the CNI plugin, which is the software that connects pods to the network. Some plugins understand and enforce policies. Some do not. If your plugin does not, the policy is stored, accepted without complaint, and silently ignored.
flowchart LR
USER["Engineer or pipeline"] -->|"Creates policy"| API["API Server"]
API --> ETCD["Cluster data store"]
AGENT["CNI plugin agent on each node"] -->|"Watches policies, pods, namespaces"| API
AGENT --> CALC["Works out allowed connections"]
CALC --> DP["Data plane rules on the node"]
DP --> PODA["Pod A"]
DP --> PODB["Pod B"]
PODA -->|"Packet"| DP
DP -->|"Allow or drop"| PODB
The cast of characters
The NetworkPolicy
A namespaced record describing the selected pods, the directions, and the allowed peers and ports.
API server and data store
They validate and keep policies safe, but do not judge any traffic.
CNI plugin agent
A small program on every node. It watches for policies, pods, and namespaces, and turns them into concrete rules.
Packet filtering machinery
Depending on the plugin, this is a set of firewall rules in the node’s kernel, or a more modern kernel technology that decides on each connection.
Labels and namespaces
The agent keeps track of which pod addresses belong to which labels, and updates rules as pods come and go.
Pods
The protected workloads. Rules are applied at the pod’s network connection on its node.
A company’s rulebook says “only staff on the list may enter the lab”. But a rulebook does not stop anyone. The guards at each door do. The Network Policy is the rulebook. The network plugin’s agents are the guards. A building with a rulebook but no guards is unprotected, however thorough the rulebook.
Before you rely on policies, confirm that your cluster’s network plugin enforces them. Some simple plugins do not. Others enforce them only when an optional component is switched on. The safest habit is to test: create a deny rule in a practice namespace and prove that a connection really fails.
6Anatomy of a Policy
A Network Policy has only a few parts. Learn them once, and every policy you ever read will make sense.
| Part | What it says | Example in words |
|---|---|---|
| Namespace | Which namespace the policy lives in, and therefore which pods it can select | The “shop” namespace |
| Pod selector | Which pods in that namespace the policy protects | Pods labeled as the payment service |
| Policy types | Which directions the policy controls: ingress, egress, or both | Incoming only |
| Ingress rules | A list of allowed sources and ports for incoming traffic | From pods labeled as the shopping cart, on port 8443 |
| Egress rules | A list of allowed destinations and ports for outgoing traffic | To pods labeled as the database, on port 5432 |
The important words
- Ingress here means traffic coming into the selected pods. Do not confuse it with the Ingress object that exposes web sites. The same word is used for two different things.
- Egress means traffic leaving the selected pods.
- Peer means the other side of a conversation: the sender for incoming traffic, the receiver for outgoing traffic.
- Selected pods are the ones the policy protects. Peers are the ones it names as allowed.
Consider a building’s rule card for one apartment: “For apartment 4B (the selected pod): visitors coming in may be only from the family list (ingress peers), and only through the front door (port). Residents going out may go only to the school and the shop (egress peers).” Each policy is one such card.
A policy is always about one namespace. It can protect only pods in its own namespace, though it can allow peers from other namespaces. To protect pods in several namespaces, create a policy in each.
7Selecting Pods and Becoming Isolated
The pod selector decides which pods a policy protects, and one special case surprises almost everyone.
The pod selector matches pods by label. It can be specific, such as “pods labeled as the payment service and the production tier”. It can also be empty. An empty selector is a valid and very important case: it means every pod in this namespace. This is how you write a rule that protects a whole namespace at once.
flowchart TD
A["Packet arrives for a pod"] --> B{"Does any policy select this pod for incoming traffic?"}
B -->|No| C["Pod is non-isolated: allow"]
B -->|Yes| D{"Does any selecting policy list this sender and port?"}
D -->|Yes| E["Allow"]
D -->|No| F["Drop"]
The surprising special case
A policy that selects pods and declares that it controls incoming traffic, but lists no allowed sources at all, is not a mistake. It is the standard way to say “nobody may come in”. Because the pod is now selected, it is isolated. Because nothing is on the guest list, nothing gets through. This tiny, empty policy is the foundation of the “default deny” approach you will meet later.
A sign on a door reading “Staff only. Staff list: none” locks the door completely. The sign itself, even with an empty list, is what turns an open door into a closed one.
Label typing mistakes are common and silent. If the selector names a label that no pod carries, the policy protects nothing, and there is no warning. Always list the pods a policy selects, and confirm they are the ones you meant.
8Ingress and Egress: Two Directions, Two Decisions
Every conversation between two pods is checked twice: once as it leaves the sender, and once as it reaches the receiver.
When pod A calls pod B, two different sets of rules may apply. Pod A’s egress rules decide whether A may send to B. Pod B’s ingress rules decide whether B may receive from A. For the conversation to work, both must allow it, if both directions are restricted. If only B is restricted, only B’s ingress rules matter. If neither is restricted, the call goes through.
sequenceDiagram
participant A as Pod A in Web tier
participant EA as Egress rules of A
participant IB as Ingress rules of B
participant B as Pod B in API tier
A->>EA: Open connection to B on port 8443
EA-->>A: Allowed if A has no egress isolation, or B is listed
EA->>IB: Connection continues
IB-->>IB: Allowed if B has no ingress isolation, or A is listed
IB->>B: Connection reaches B
B-->>A: Reply travels back automatically
| Sender’s egress | Receiver’s ingress | Result |
|---|---|---|
| Not restricted | Not restricted | Connection works |
| Not restricted | Restricted, sender listed | Connection works |
| Not restricted | Restricted, sender not listed | Connection refused |
| Restricted, receiver listed | Not restricted | Connection works |
| Restricted, receiver not listed | Not restricted | Connection refused |
| Restricted, receiver listed | Restricted, sender listed | Connection works |
| Restricted, receiver listed | Restricted, sender not listed | Connection refused |
Replies come back automatically
Network Policies are stateful for the connections they allow. If pod A is allowed to open a connection to pod B, then B’s replies on that same connection flow back to A without any extra rule. You never need a separate rule for the answers. You only describe who may start a conversation.
If you are allowed to phone a friend, you do not need a second permission for your friend to speak. Once the call is connected, both sides can talk. Permission concerns who may dial, not who may talk.
9Naming the Other Side: Pods, Namespaces, and Address Ranges
A rule can describe a peer in three ways, and one subtle combination trips up even experienced engineers.
Pod selector
Allow pods carrying certain labels, within the same namespace as the policy. This is the everyday choice for talking within one application group.
Namespace selector
Allow all pods in namespaces carrying certain labels. Use it to permit a shared tool, such as monitoring, that lives in its own namespace.
Address range
Allow a range of network addresses, with optional exceptions carved out. Use it for things outside the cluster, such as a company office network or an external service.
A useful detail: every namespace automatically carries a label holding its own name in modern Kubernetes versions, so you can select a namespace by name without labeling it yourself.
The AND versus OR trap
A rule may list several peers. How they are listed changes the meaning completely. If a namespace selector and a pod selector appear together in the same entry, they combine with AND: the sender must be in a matching namespace and also carry a matching label. If they appear as two separate entries, they combine with OR: a sender matching either one is allowed.
flowchart TD
subgraph One["Single entry: AND"]
A1["Sender in namespace labeled monitoring"] --> A3{"And also carries label prometheus?"}
A3 -->|Yes| A4["Allowed"]
A3 -->|No| A5["Refused"]
end
subgraph Two["Two entries: OR"]
B1["Sender in namespace labeled monitoring"] --> B4["Allowed"]
B2["Any pod in this namespace labeled prometheus"] --> B4
B3["Anything else"] --> B5["Refused"]
end
“Visitors who are from the accounting firm and wear a blue badge” is a narrow rule, since both conditions are needed. “Visitors from the accounting firm, or anyone wearing a blue badge” is far wider, since either condition is enough. Only a small change in punctuation separates a tight rule from a leaky one.
The wider OR form is often written by accident, when the author meant AND. Every pod in the whole cluster carrying that label then gets in. Always re-read your entries and ask: is this one condition, or two?
10Ports and Protocols
Saying who may connect is half of a rule. The other half is saying which door they may knock on.
Each peer entry may be paired with a list of ports. A port is a numbered doorway on a pod, used by one application. A rule can name a single port, or a continuous range of ports. It also names the protocol, most commonly TCP, and sometimes UDP or, more rarely, SCTP. If a rule lists no ports at all, it allows every port for the named peers, which is usually far broader than intended.
| Rule shape | What it allows | Comment |
|---|---|---|
| Peer only, no ports | All ports and protocols from that peer | Convenient and often too wide |
| Peer plus one port | Only that port, only that protocol | The usual best choice |
| Peer plus a port range | A continuous set of ports | Useful for applications that use a block of ports |
| Ports only, no peer | Those ports from anywhere | Rarely wise, since it opens the door to the whole world |
| Named port | Whatever number the pod calls that name | Helpful when different pods use different numbers for the same role |
Giving a visitor “access to the building” is very different from giving them “access to the meeting room on the third floor”. Naming the exact room limits what a visitor can reach, even if their identity is trusted. Ports are the room numbers.
Remember that a policy port refers to the port the pod listens on, not the port a Service advertises in front of it. If a Service maps port eighty to a pod’s port eighty-thousand-eighty, the policy must name the pod’s number.
11How It Works Internally: From Policy to Packet Decision
Follow a policy from the moment you create it to the moment a single network packet is allowed or dropped.
You create the policy
The API server checks that the object is well formed, stores it, and announces the change to anyone watching.
Every node’s agent notices
The network plugin’s agent on each node is watching for policies, pods, and namespaces. It sees the new policy within moments.
It finds the selected pods
The agent evaluates the selector against the labels of pods on its node, and marks those pods as isolated in the relevant direction.
It resolves the peers
For each allowed peer, the agent works out the current pod addresses that match, using labels and namespaces. As pods come and go, this list is refreshed continually.
It programs the data plane
The agent turns the result into concrete filtering rules on the node. Some plugins use classic firewall tables, and others use a faster in-kernel technology.
A packet arrives
When a pod starts a new connection, the data plane checks the rules for the sender’s outgoing side and the receiver’s incoming side.
Allowed connections are remembered
Once a connection is permitted, it is tracked, so later packets in the same conversation, and the replies, flow without repeating the full check.
Dropped connections are silent
A refused connection usually just times out from the sender’s viewpoint. There is normally no polite message saying “denied”, which makes problems harder to spot.
Think of a security guard who receives a new guest list each morning. He first works out which residents are affected, then memorizes which names are permitted, and finally checks each visitor at the door. Once a visitor has been let in for a visit, the guard does not check their ID again at every step through the hallway.
Because dropped connections just hang and time out, a blocked call often looks like a slow or broken application rather than a security rule. Whenever a new timeout appears after a policy change, suspect the policy first.
12Many Policies Add Up: The Union Rule
A pod may be selected by several policies at once. Kubernetes combines them by adding their allowances together.
There is no ordering, priority, or conflict between Network Policies. If two policies select the same pod, the pod may receive whatever either allows. This is called a union of rules. Adding a policy can therefore only make the network more open for the pods it selects, never less, once isolation has begun. The only step that closes things is the first one: selecting a pod and thereby isolating it.
| Policy A allows | Policy B allows | Both select the same pod. Traffic allowed is |
|---|---|---|
| Web pods on port 8443 | Monitoring pods on port 9100 | Web on 8443, and monitoring on 9100 |
| Nothing (empty list) | Web pods on port 8443 | Web on 8443 |
| All peers on all ports | Web pods on port 8443 | Everything, since A is already fully open |
If two different managers each hand the guard a guest list for the same room, the guard admits anyone who appears on either list. He never crosses names off because they are missing from the other list. Extra lists only ever add guests.
Because rules only add, one generous policy written by someone in a hurry can quietly cancel the value of a dozen careful ones. Review all policies that select the same pods together, not one at a time.
13Default Deny: The Foundation of Every Good Setup
The recommended approach is to close everything first, then open only what is needed.
Since policies only add allowances, the strongest starting point is a policy in each namespace that selects every pod, controls incoming traffic, and lists no allowed sources. Every pod in the namespace becomes isolated for incoming traffic, and nothing may enter. You then add small, specific policies that open the exact paths your applications need. This pattern is called default deny.
| Pattern | What it does | When to use it |
|---|---|---|
| Default deny for incoming traffic | Nothing may enter any pod in the namespace unless another policy allows it | The first step in almost every namespace |
| Default deny for outgoing traffic | Nothing may leave any pod unless another policy allows it | A second step, once incoming rules are stable and DNS is handled |
| Default deny for both | Complete lock-down by default | High-security namespaces |
| Allow all incoming | An explicit, visible statement that a namespace is intentionally open | Rare; makes intent clear when a namespace must stay open |
| Allow within the namespace only | Pods in the namespace may talk to each other, but nobody else may enter | A gentle first step for a group of closely related services |
A good building manager first locks every door. Then, one by one, she issues keys for exactly the doors each person needs. Starting with everything open and trying to lock things one at a time always leaves doors forgotten.
Apply default deny to a new, empty namespace before deploying anything into it. It is much easier to add allowances as you build than to lock down a live system later.
14The DNS Trap When You Lock Down Outgoing Traffic
The most common way to break a cluster with Network Policies is forgetting that pods must ask for directions before they can call anyone.
Applications rarely call each other by numeric address. They use names, and the cluster’s DNS service translates a name into an address. DNS is just another application running in pods, usually in the system namespace, listening on port fifty-three. When you apply a default deny for outgoing traffic, your pods can no longer reach DNS, so every name lookup fails. To the application, this looks like the entire network vanished, even though the paths to other pods are fine.
Imagine a phone system where you may only call numbers on an approved list, but nobody remembered to include the directory service. You cannot look up anyone’s number, so you cannot call anyone, even people on the approved list. The directory must be allowed first.
How to avoid it
- When you restrict outgoing traffic, always add a rule that allows the DNS service. Name the system namespace and the DNS pods as the peer, and allow port fifty-three for both UDP and TCP.
- Allow both protocols. Most lookups use UDP, but large answers switch to TCP.
- Test name lookups from a pod immediately after applying any egress restriction.
- If your cluster uses a node-level DNS cache, check where lookups actually go, since the peer may be an address on the node rather than a pod.
sequenceDiagram
participant App as App pod
participant DNS as Cluster DNS pods
participant Db as Database pod
App->>DNS: Where is the database service
Note over App,DNS: Blocked if egress to DNS is not allowed
DNS-->>App: Address of database
App->>Db: Connect to database on its port
Note over App,Db: Needs a second egress rule for the database
Db-->>App: Reply flows back automatically
Symptoms of blocked DNS are confusing: errors saying a name cannot be resolved, or long delays at startup. Whenever you see those after an egress change, test DNS first.
15Services, Load Balancers, and Policies
Policies talk about pods, not about Services. This distinction causes plenty of head-scratching.
A Service is a stable address that forwards traffic to pods. When a pod calls a Service, the network translates the Service’s address into the address of one of the pods behind it, and this translation happens before policies are checked. The policy therefore sees traffic going to a pod, not to the Service. This means:
- You write rules that name the pods behind a Service, using labels, not the Service itself.
- The port in a rule is the pod’s port, not the Service’s advertised port.
- You cannot write a rule that says “allow traffic to this Service by name”.
Traffic coming from outside the cluster
Traffic from the outside world reaches pods through node ports, cloud load balancers, or ingress controllers. Depending on the plugin and the load balancer type, the pod may see the original visitor’s address, or only the address of the load balancer or node. That changes what your rule must allow. If the original address is preserved, an address-range rule for outside visitors works. If not, you must allow the load balancer or ingress controller pods instead, and enforce visitor restrictions at that layer.
| Path into the pod | What the policy typically sees | What to allow |
|---|---|---|
| Pod to pod, direct | The sender pod | Pod or namespace selector |
| Pod to Service to pod | The sender pod, after translation | Same as above, using pod port |
| Ingress controller to pod | The controller’s pod | The controller’s namespace and pod labels |
| Cloud load balancer straight to pod | Varies by cloud and settings | Check whether the visitor’s or the balancer’s address arrives |
| Node port from outside | Often the node’s address, or the visitor’s, depending on settings | Test carefully; behavior is plugin dependent |
A company’s main phone number forwards each call to a specific employee’s desk. A guard at the employee’s door sees only the call arriving at the desk, not the number the caller originally dialed. Rules must therefore be written about who reaches the desk.
When rules involving load balancers or node ports do not behave as expected, run a small experiment in a test cluster and observe which address the pod really sees. Documentation varies, so evidence beats assumption.
16Ingress Controllers, Health Checks, and Monitoring Traffic
Some traffic is easy to forget because it comes from the platform itself. Forget it, and healthy applications look broken.
The ingress controller
It receives web visitors and forwards them to applications. Application pods must allow the controller’s namespace and pods on the application’s port.
Probes from the node
Kubernetes checks application health by sending requests from the node’s agent. Most plugins allow traffic from a pod’s own node, but this varies, so verify it after applying default deny.
Scraping by monitoring tools
Monitoring systems fetch numbers from pods regularly. Allow the monitoring namespace to reach the metrics port of each application.
Service mesh components
Meshes add proxies and control-plane traffic. Their documentation lists the paths that policies must permit.
Calls from the control plane
Admission webhooks are called by the API server. Locking down the pods that serve them can break deployments cluster-wide.
Log shippers and agents
Agents that send logs off the cluster need outgoing permission to their destination.
When you lock a building’s doors, remember the postal worker, the fire inspector, and the cleaning crew. They are not residents, but the building cannot function without them. Platform traffic is the equivalent: invisible until you lock it out.
A very common surprise after applying default deny is that pods stop becoming ready, because their health checks are refused. If pods are running but never ready after a policy change, check that traffic from the node’s agent is permitted by your plugin.
17Namespaces as Boundaries in Shared Clusters
Namespaces organize a cluster, but by themselves they do not separate its network. Policies make them real boundaries.
Many people assume that putting two teams in two namespaces isolates them. It does not. Pods in different namespaces can still reach each other by default. A namespace is a label on a group of objects, not a wall. Network Policies turn that label into an actual network boundary.
flowchart LR
subgraph TA["Namespace team-a"]
A1["App A1"]
A2["App A2"]
end
subgraph TB["Namespace team-b"]
B1["App B1"]
B2["App B2"]
end
subgraph SH["Namespace shared-tools"]
M["Monitoring"]
I["Ingress controller"]
end
A1 A2
B1 B2
A1 -.->|"Blocked"| B1
M --> A1
M --> B1
I --> A1
I --> B1
A common multi-team blueprint
Give every team its own namespace
One namespace per team or per application group, with clear names and labels.
Apply default deny in each
Nothing may enter until it is explicitly allowed.
Allow traffic within the namespace
Services owned by one team usually need to talk to each other freely.
Allow shared platform components
Permit ingress controllers, monitoring, and DNS by naming their namespaces.
Open specific cross-team paths
When team A truly needs team B’s API, the owner of team B adds a narrow rule allowing it.
Companies renting floors in one tower get separate floors, but the floors are not automatically locked. Each company must add a lock and a visitor list to its own floor. Only then do the floors become truly private.
18Designing Policies for a Three-Tier Application
A worked example shows how the pieces fit: a web tier, an application tier, and a database.
Consider a simple shop. Visitors reach a web tier through an ingress controller. The web tier calls an API tier. The API tier reads and writes a database. Nothing else should talk to anything else. Here is the desired picture.
flowchart LR
V["Visitors on the internet"] --> IC["Ingress controller"]
IC -->|"Port 8080"| W["Web tier pods"]
W -->|"Port 8443"| A["API tier pods"]
A -->|"Port 5432"| D["Database pods"]
P["Monitoring"] -.->|"Metrics ports"| W
P -.-> A
P -.-> D
W -->|"DNS lookups"| DNS["Cluster DNS"]
A -->|"DNS lookups"| DNS
| Protected pods | Incoming allowed from | Outgoing allowed to |
|---|---|---|
| Web tier | Ingress controller on the web port; monitoring on the metrics port | API tier on its port; DNS |
| API tier | Web tier on the API port; monitoring on the metrics port | Database on its port; DNS; specific external services if needed |
| Database | API tier only on the database port; monitoring on the metrics port; backup tool if any | Nothing, except DNS or backup destinations if needed |
What this achieves
If an attacker takes over a web pod, they can reach only the API tier on one port. They cannot touch the database directly. If they take over an API pod, they can reach the database, which is the price of the application working, but they cannot reach other teams’ services or the internet. Each compromise stays boxed in. Notice also that the database has almost no outgoing permissions. A database rarely needs to start conversations, so denying them removes a common path for stolen data to leave.
Draw the allowed conversations on paper before writing any policy. Every arrow in the picture becomes one rule. Every missing arrow is a rule you deliberately did not write.
19Controlling Outgoing Traffic to the Outside World
Most teams protect what comes in. Fewer control what goes out, and that is where stolen data escapes.
Outgoing rules matter for three reasons. First, a compromised pod that cannot reach the internet cannot send stolen data out or download more attack tools. Second, outgoing rules stop pods from contacting the cloud provider’s special metadata address, a private address which, on many clouds, hands out information and sometimes credentials belonging to the machine. Third, they stop accidental calls to services that should not be used from a given workload.
Allow the cluster, block the internet
Permit traffic to the cluster’s own address ranges and DNS, and nothing else. Pods can talk to neighbors, not the world.
Allow the internet, except private ranges
Allow all public addresses but carve out private ranges and the metadata address using the exception feature of address rules.
Allow named partners only
Permit specific address ranges of trusted external services, such as a payment provider, and nothing else.
Standard rules use addresses, not names
You cannot write “allow this web site by its domain name” in the standard object. Provider addresses change, so plugins offer extensions for name-based rules.
A company that checks visitors at the front door but lets employees carry any box out through the loading dock has left a gap. Outbound checks are the loading dock inspection: they stop things leaving that should not.
Outgoing rules to external services depend on addresses that can change without notice. Rules written from a snapshot may break silently months later. Where possible, route external calls through a controlled gateway or proxy with a stable address, or use the name-based extensions of your plugin.
20Stateful and Clustered Systems Need Special Care
Databases, queues, and clustered stores talk to their own members constantly. Forgetting those conversations breaks the cluster from the inside.
A clustered database is not a single pod. It is a group of members that keep in touch with each other, share data, and vote on decisions. If your policy allows the application to reach the database but forgets that the members must reach each other, the members lose contact, elections fail, and the database stops accepting writes.
| Conversation | Who talks to whom | Rule needed |
|---|---|---|
| Client traffic | Application to database members | Incoming allowed from application pods on the database port |
| Peer traffic | Members to each other | Incoming and outgoing allowed among database pods, on the peer ports |
| Replication | Primary to replicas | Covered by peer rules, but check any extra replication ports |
| Backups | Database to storage or backup tool | Outgoing allowed to the backup destination |
| Monitoring | Monitoring to database exporters | Incoming allowed from monitoring on the metrics port |
| Operator or controller | Management software to members | Incoming allowed from the operator’s pods |
A team of surgeons must talk to each other during an operation. A rule that lets patients’ families speak to the surgeons, but forbids the surgeons from speaking to one another, would ruin the operation. Locking down clustered systems means allowing the internal chatter too.
Read the port documentation of any clustered system before writing policies. Most list every port they use for clients, peers, management, and monitoring, and each may need its own rule.
21Beyond the Standard Object: Richer Policies from Plugins
The standard Network Policy is deliberately simple. Many plugins and newer efforts add powers the standard object lacks.
What the standard object cannot do
- Write explicit deny rules or rule ordering.
- Apply one policy cluster-wide across all namespaces.
- Allow or block by domain name.
- Inspect or filter by web request paths or methods.
- Log or count allowed and dropped connections.
- Require encryption between pods.
What extensions commonly add
- Cluster-wide policies managed by platform teams.
- Explicit deny rules with priority ordering.
- Rules that use domain names for outside services.
- Application-level rules for web request paths and methods.
- Flow logs showing accepted and denied connections.
- Identity-based rules, sometimes tied to encrypted service identity.
Popular network plugins offer their own policy objects with these powers. The Kubernetes community is also developing standard cluster-scoped policy objects for administrators, so that platform teams can set guardrails that namespace owners cannot override. The exact state of these efforts changes as versions advance, so check the documentation of your cluster’s version and plugin.
A basic door lock is enough for a family home. A bank uses cameras, logbooks, time locks, and separate keys for staff and managers. The standard Network Policy is the door lock. Plugin extensions are the bank’s extra machinery.
Plugin-specific policies are more powerful but tie you to that plugin. Using only the standard object keeps your rules portable. Many teams use the standard object for application rules, and extensions only for platform-wide guardrails.
22Performance and Scalability
Network Policies cost some computing effort. In most clusters it is small, and in very large ones it deserves attention.
Two kinds of cost exist. The first is control cost: the effort of each node’s agent to calculate rules whenever policies, pods, or labels change. The second is data path cost: the effort of checking each connection against those rules. Modern plugins keep both low, but the design of your policies influences them.
Churn multiplies work
Frequent pod restarts or label changes force agents to recompute peer lists. Very dynamic clusters feel this most.
Many broad selectors
Rules that match huge numbers of pods create long address lists. Narrower selectors produce smaller, cheaper rule sets.
Technology matters
Some plugins use long chains of firewall rules whose cost grows with size. Others use in-kernel lookups whose cost stays nearly flat.
Short-lived connections
Applications that open thousands of new connections per second pay the check cost more often than those using long-lived connections.
Thousands of policies
Large platforms with very many policies should test propagation time: how long after creating a policy it is truly enforced everywhere.
New pods and the enforcement gap
A new pod may briefly run before rules for it are programmed. Some plugins close this gap; others may allow a short unprotected moment.
Prefer a moderate number of clear, narrow policies over both extremes: one giant policy that nobody understands, and thousands of tiny ones that overlap. Structure by application and by purpose.
23High Availability and Reliability
Policies can protect reliability by preventing accidents, and damage it by blocking legitimate traffic. Design for both.
| Failure scenario | What happens | How to prepare |
|---|---|---|
| Policy too tight after a change | Legitimate calls time out; application errors rise | Roll out gradually, watch error rates, keep a quick rollback path |
| Enforcement agent crashes on a node | Behavior depends on plugin: existing rules may keep working, or new pods may be left unprotected | Monitor agents, and know your plugin’s failure behavior |
| Agent is slow to update | New pods or new rules take effect late | Measure propagation time; avoid relying on instant enforcement |
| Labels are changed by mistake | Pods silently fall out of, or into, a policy’s scope | Control who can edit labels; alert on label changes for critical pods |
| DNS or platform traffic blocked | Wide, confusing outages | Maintain standard allow rules for platform traffic in every namespace |
| Policy accidentally deleted | Namespace becomes open again | Keep policies in version control, and restore automatically |
A door lock protects a house, but a lock that jams shut can trap the family inside. Good security design includes a way to open the door in an emergency. Policies need a quick, well-practiced rollback for exactly that reason.
Whether the network fails open or fails closed when the enforcement component has trouble depends on the plugin. Read your plugin’s documentation on this point, and test it in a rehearsal, not for the first time during an incident.
24Security Considerations and Limits
Network Policies are one strong layer of defense. Knowing what they do not cover is as important as knowing what they do.
Limits lateral movement
A compromised pod can reach only the few peers you allowed, greatly shrinking the attacker’s options.
Blocks data exfiltration paths
Outgoing rules make it harder to send stolen data out or fetch attack tools.
Protects sensitive systems
Databases and internal tools can be reached only from named applications.
No encryption
Allowed traffic is not encrypted by the policy. Use encryption in the application or through a mesh or plugin feature.
No application awareness
A policy allows a whole port. It cannot tell a harmless request from a malicious one on that port.
Trust in labels
Anyone who can add a label to a pod may be able to move it into an allowed group. Restrict who can change labels.
Host and node traffic
Pods that share the node’s network, and traffic from nodes themselves, are handled differently by plugins, and may fall outside policy control.
Who can write policies
Permission to create, change, or delete policies is itself powerful. Guard it with narrow roles and reviews.
A door lock tells you who may enter, but not what they will do inside. It does not replace cameras, alarms, or safes. Network Policies are the lock on each door, an essential first layer, working together with strong passwords, encryption, and monitoring.
Combine policies with least-privilege access roles, hardened containers, encrypted traffic, secret management, and up-to-date images. No single layer is enough, and each covers weaknesses in the others.
25Rolling Out Policies Safely
The technical work of writing a policy is small. The careful work is introducing it without breaking a live system.
A policy applied carelessly to a busy production namespace can cut off legitimate traffic in an instant. The safe path is gradual: learn what traffic actually exists, write rules to match it, test in a copy of production, and roll out one namespace at a time with a quick way back.
stateDiagram-v2
[*] --> Discover
Discover --> Draft : "Traffic map understood"
Draft --> TestCluster : "Policies written"
TestCluster --> Draft : "Legitimate traffic blocked"
TestCluster --> Incoming : "Tests pass"
Incoming --> Watch1 : "Default deny for incoming applied"
Watch1 --> Draft : "Errors appear"
Watch1 --> Outgoing : "Stable for an agreed period"
Outgoing --> Watch2 : "Egress rules and DNS allowed"
Watch2 --> Draft : "Errors appear"
Watch2 --> Maintained : "Stable"
Maintained --> [*]
Discover the real traffic
Learn which pods talk to which. Sources include application owners, architecture diagrams, and flow logs from your plugin or from monitoring tools.
Draw the allowed map
Sketch each allowed conversation with its port. This drawing becomes your specification and your documentation.
Test in a non-production copy
Apply the policies in a staging namespace with realistic traffic, and watch for timeouts and failed health checks.
Start with incoming rules
Incoming restrictions are lower risk than outgoing ones and give the biggest early benefit.
Roll out namespace by namespace
Begin with a low-risk namespace, then move to more critical ones as experience grows.
Add outgoing rules with DNS
Only after incoming rules are stable, restrict outgoing traffic, always allowing DNS first.
Keep a rollback ready
Know exactly which policy to remove, or which pre-written open policy to apply, if something breaks.
Maintain continuously
Every new service comes with its own policies, and every retired service has its policies removed.
Installing locks on every door of a busy office in one night would trap people inside or lock out the cleaners. A wise manager first studies who uses which doors, tests one floor, and expands only when the first floor works smoothly.
26Monitoring, Logging, and Metrics
Because blocked connections fail silently, visibility is not a luxury. It is the only way to see what your rules are really doing.
Accepted and dropped connections
Many plugins can record each decision. These logs show exactly which conversation was refused and by which policy.
Drop counters
Counters of dropped connections per namespace or policy reveal sudden changes after a rollout.
Application error rates
A rise in timeouts and connection errors soon after a policy change is a strong signal that the policy is at fault.
Enforcement agent health
Track whether the plugin’s agents are running on every node, and how long rule updates take.
Changes to policies
The cluster’s audit log records who created, changed, or deleted policies and when. Review it after incidents.
Namespaces without default deny
A periodic report of namespaces that have no default deny policy highlights gaps.
Alerts worth setting up
- A sudden jump in dropped connections in a namespace shortly after a policy change.
- A namespace that has no policies at all, or has lost its default deny policy.
- Repeated denied attempts from one pod toward many different destinations, which may suggest scanning by an intruder.
- Denied connections to the cloud metadata address, which may indicate a credential theft attempt.
- Enforcement agents not running, or updates taking too long, on any node.
A guard who turns visitors away but writes nothing in a logbook cannot help investigate a break-in. The logbook of turned-away visitors is often where the first sign of an attack shows up. Flow logs are that logbook.
Before enforcing a new policy strictly, some plugins let you run it in a “log only” mode that reports what would have been blocked. This is an excellent way to find forgotten traffic without any outage.
27Advantages, Disadvantages, and Trade-offs
Network Policies deliver a large security gain for a modest cost, and like every control, they have downsides worth knowing.
Advantages
- Smaller blast radius. A single compromise cannot spread freely.
- Declarative and portable. Rules are written once as cluster objects and follow the pods wherever they run.
- Label-driven. Rules keep working as pods are created and replaced, without tracking addresses.
- Owned by application teams. The people who know the traffic patterns write the rules.
- Supports compliance. Provides evidence of segmentation for audits.
- Stateful and simple. Only initiators need permission; replies come free.
Disadvantages
- Needs an enforcing plugin. Without one, policies are ignored silently.
- Allow-only. No explicit deny, no ordering, and no cluster-wide scope in the standard object.
- Silent failures. Blocked traffic appears as timeouts, making debugging harder.
- Limited visibility. The standard object has no logging or metrics.
- Address-based external rules. No domain names in the standard object.
- Ongoing upkeep. Every new dependency needs a new rule.
The main trade-offs
Security versus agility. Tight rules slow the first deployment of a new dependency, because someone must add a rule. That small friction is the price of the protection.
Precision versus maintenance. Very fine-grained rules give the strongest protection and take the most effort to keep current. Broader rules, such as “allow within the namespace”, are easier to maintain but leave more paths open. Most teams choose narrow rules for sensitive systems and broader rules for low-risk groups.
Portability versus power. The standard object works with any enforcing plugin. Plugin extensions offer more features but tie you to one plugin.
28Design Patterns That Work
A few reliable patterns cover most real-world needs.
Default deny first
Every namespace starts with a policy that isolates all pods for incoming traffic, and often outgoing traffic too.
Allow by tier
Web may reach API, API may reach database, nothing else. Each tier’s rule names only the tier before it.
Shared platform allow-list
A standard set of rules permits DNS, monitoring, and the ingress controller in every namespace, applied through templates.
Namespace as a trust zone
Allow freely within one team’s namespace, and require explicit rules for anything crossing namespaces.
Egress gateway
Only a small group of pods may reach the internet. Other pods send external calls through them, so one place can be monitored and controlled.
Block the metadata address
A standard outgoing rule denies pods access to the cloud provider’s private metadata address, unless a workload truly needs it.
Policies packaged with the application
The application’s deployment files include its policies, so no service goes live unprotected.
Policy tests in the pipeline
Automated tests confirm that allowed paths work and forbidden paths are refused, before every release.
29Anti-patterns to Avoid
These habits turn a helpful control into a false sense of security or a source of outages.
What people do
They write careful policies and assume they work, without ever testing.
Why it hurts
If the plugin does not enforce policies, they are silently ignored, and the network stays fully open while everyone feels safe.
What to do instead
Choose a plugin that enforces policies, and prove enforcement with a test that must fail.
What people do
When traffic is blocked, they add a policy allowing all incoming traffic from everywhere, just to make the problem disappear.
Why it hurts
Because rules add up, one wide-open policy cancels every careful rule for the same pods.
What to do instead
Find the exact missing conversation, using logs or a traffic map, and add a narrow rule for it.
What people do
They apply default deny for outgoing traffic without allowing DNS, monitoring, or health checks.
Why it hurts
Name lookups fail, pods never become ready, and metrics disappear. The result looks like a total network failure.
What to do instead
Include a standard allow rule set for platform traffic in every namespace template, and test after each change.
What people do
They write a namespace selector and a pod selector as two separate entries when they meant them as one combined condition.
Why it hurts
The rule becomes much wider than intended, allowing every pod in the cluster with the label, or every pod in the namespace.
What to do instead
Review each peer entry aloud: “the sender must be in this namespace and carry this label”. Add tests that prove an outsider is refused.
What people do
They copy the current addresses of an external provider into address-range rules and forget about them.
Why it hurts
The provider changes addresses, and the application suddenly cannot reach it. Nobody remembers the rule that caused it.
What to do instead
Route external calls through an egress gateway, or use name-based rules from your plugin, and keep documentation of every external dependency.
What people do
They create and edit policies directly on the live cluster during incidents, with no record.
Why it hurts
Nobody knows why a rule exists, or whether it is safe to remove. Policy sets grow messy and dangerous.
What to do instead
Keep every policy in version control, review changes, and apply them through automation.
30Best Practices and Common Mistakes
A short checklist prevents most of the pain.
Best practices
Confirm enforcement
Run a test that proves a forbidden connection fails in your own cluster.
Start with default deny
Isolate first, then open exactly what is needed.
Use clear, consistent labels
Agree on labels for application, tier, and environment. Policies depend on them completely.
Name the port
Each rule should specify the exact port and protocol, not just the peer.
Document every rule
Add a short note saying why each policy exists and who owns it.
Test both directions
For every allowed path, test that it works. For every forbidden path, test that it fails.
Control who edits policies and labels
Both determine what traffic is allowed; guard them with narrow permissions.
Review regularly
Remove rules for retired services, and re-check that rules still match reality.
Common mistakes
Assuming namespaces isolate by themselves
Namespaces are labels, not walls. Without policies, pods in different namespaces talk freely.
Confusing the two meanings of “ingress”
The Network Policy direction word and the web-exposing Ingress object are different things.
Naming the Service instead of the pods
Rules match pods, and use the pod’s port. A rule written about a Service name does nothing.
Locking down outgoing traffic first
This is the riskiest step. Begin with incoming rules, and add outgoing ones later.
Believing an empty policy is a mistake
An empty allow list is the intentional way to deny everything.
Testing only that things work
Security testing means proving that things which should fail really do fail.
31Real-World and Industry Examples
Network segmentation appears wherever sensitive data lives, and Kubernetes teams follow the same principles as traditional networks.
Payment and financial services
Payment systems isolate the components that touch card data from everything else. Standards for card data ask for clear network segmentation, so teams use default deny, narrow tier-to-tier rules, and tight outgoing control to show that only approved paths exist.
Healthcare platforms
Systems handling patient records limit which services can reach the databases holding them, and log every denied attempt. Segmentation helps satisfy privacy regulations and reduces the harm of any single breach.
Software-as-a-service platforms with many customers
Providers that run many customers’ workloads in one cluster place each customer, or each group, in its own namespace with default deny and strict cross-namespace rules, so one customer’s compromise cannot reach another’s.
Large online retailers
Retail platforms with hundreds of microservices use tier-based rules and shared allow-lists for platform traffic. Automation generates the standard rules for each new service, so the network stays tidy as the system grows.
Government and regulated workloads
Public-sector clusters often require default deny everywhere, egress control, and audited changes. Cluster-wide policies from the network plugin enforce guardrails that individual teams cannot switch off.
Shared internal platforms
Company platform teams provide namespace templates that already contain default deny, DNS, monitoring, and ingress allowances. Application teams add only the few rules unique to their service.
In every setting, the same three steps appear: isolate by default, open only what is needed, and watch what happens. The technology is Kubernetes, but the principle is older than computers: give each person only the keys they need.
32When It Does Not Work: A Troubleshooting Path
Match the symptom to the likely cause, then follow the steps in order.
| Symptom | Likely cause | What to check | Typical fix |
|---|---|---|---|
| Policy has no effect at all | Plugin does not enforce, or the selector matches nothing | Plugin documentation, pods selected by the policy | Use an enforcing plugin, and correct labels |
| Everything stops working after default deny | DNS, health checks, or platform traffic blocked | Name lookups from a pod, and pod readiness | Add allow rules for DNS and platform traffic |
| Two pods cannot talk although a rule exists | Rule is on one side only, port is wrong, or AND-OR confusion | Both the sender’s egress and the receiver’s ingress, and the pod’s port | Fix the missing side, use the pod port, correct entry structure |
| Calls by Service name fail, but pod addresses work | Rule names the wrong port, or DNS is blocked | Pod port versus Service port; DNS access | Use the pod’s port; allow DNS |
| Traffic from outside is refused | Ingress controller or balancer not allowed, or the visitor’s address is not preserved | What address the pod really sees | Allow the controller’s pods, or adjust the address rule |
| Pods stay running but never ready | Health checks from the node refused | Plugin behavior for node traffic | Allow the node’s checks as your plugin requires |
| Clustered database breaks after policy | Peer-to-peer ports blocked | Ports the system uses among members | Allow members to reach each other |
| Rule works for some pods but not others | Labels differ between pods | Labels of working and failing pods | Correct the labels, and standardize them |
flowchart TD
A["A connection fails after a policy change"] --> B{"Does name lookup work from the source pod?"}
B -->|No| C["Allow DNS egress"]
B -->|Yes| D{"Does the source have egress restrictions?"}
D -->|Yes| E{"Is the destination listed with the right port?"}
E -->|No| F["Add the missing egress rule"]
E -->|Yes| G{"Does the destination have ingress restrictions?"}
D -->|No| G
G -->|Yes| H{"Is the source listed with the right pod port?"}
H -->|No| I["Add or correct the ingress rule"]
H -->|Yes| J["Check labels, namespace labels, and AND versus OR"]
G -->|No| K["Look beyond policies: application, Service, or routing"]
Confirm the symptom is a timeout
Blocked connections usually hang rather than fail instantly. A quick “connection refused” message more often means the application is not listening.
List the policies that select each pod
For both sender and receiver, find every policy selecting them, and note the directions each controls.
Check the labels
Compare the labels on the pods and on the namespaces with what the rules expect. A single wrong character is enough.
Check the ports
Use the pod’s real listening port, not the Service’s advertised port.
Look at flow logs
If your plugin records decisions, find the denied entry. It usually names the policy or the missing rule.
Test from a temporary pod
Start a small test pod with the same labels as the real sender, and try the connection. This isolates network rules from application problems.
Change one rule, then retest
Make a single small fix, and confirm that it works and that forbidden paths still fail.
33A Hands-On Walkthrough in Plain Words
Let us secure a small shop application step by step, describing each action in words rather than code.
You have a namespace called “shop” containing a web tier, an API tier, and a database. Right now everything is open. Here is how a careful engineer proceeds.
Prove that enforcement works
In a practice namespace, create a policy that denies all incoming traffic to a test pod, then try to connect from another pod. The connection must fail. If it succeeds, your plugin does not enforce policies, and nothing that follows will protect you.
Label everything consistently
Give each pod an application label and a tier label, such as web, api, or database. Also confirm the namespace carries its name label.
Draw the allowed conversations
Ingress controller to web on its port. Web to API on its port. API to database on its port. Monitoring to each metrics port. Web and API to DNS.
Apply default deny for incoming traffic
Create the empty allow-list policy selecting every pod in the shop namespace. Everything is now closed for incoming traffic.
Open the web tier
Add a policy for the web pods that allows the ingress controller’s namespace and pods on the web port, and monitoring on the metrics port. Check that the shop still loads in a browser.
Open the API tier
Add a policy for the API pods that allows only the web pods on the API port, and monitoring on the metrics port.
Open the database tier
Add a policy for the database that allows only the API pods on the database port, and monitoring. Then test from the web pod that a direct database connection now fails.
Add outgoing rules carefully
Once everything is stable, apply default deny for outgoing traffic, immediately allowing DNS. Then add the tier-to-tier outgoing rules from your drawing.
Block the metadata address
Add an outgoing rule for pods that allows public addresses but excludes private ranges and the cloud metadata address.
Test the forbidden paths
Confirm that the web tier cannot reach the database, that the database cannot reach the internet, and that a pod in another namespace cannot reach anything in shop.
Store and monitor
Commit every policy to version control, set up flow logs and alerts, and write a short note describing each rule’s purpose.
What this walkthrough teaches
Notice the order: prove enforcement, understand the traffic, close everything, open narrow paths one at a time, test what should work and what should not, and only then tighten outgoing traffic. A policy set built this way is understandable, testable, and calm to maintain.
34Design Exercise: Reading Four Policies in Words
The best way to master policies is to read them fluently. Here are four described in words. Ask yourself what each allows.
| Policy description | What it does | Watch for |
|---|---|---|
| Selects every pod in a namespace. Controls incoming traffic. Lists no sources. | Default deny for incoming traffic across the whole namespace | Health checks and platform traffic may also be blocked |
| Selects database pods. Allows incoming from pods labeled as API, on the database port only. | Only the API tier can reach the database, and only on one port | Cluster members’ peer traffic still needs its own rule |
| Selects all pods. Controls outgoing traffic. Allows only the DNS pods in the system namespace on port fifty-three, both protocols. | Default deny for outgoing traffic, except name lookups | Every other outgoing path now needs its own rule |
| Selects web pods. Allows incoming from a namespace labeled ingress AND pods labeled as the controller, in one entry, on the web port. | Only the controller’s pods in the ingress namespace may reach the web tier | If written as two entries, it would allow far more than intended |
Questions to practice with
- What happens to a database pod if the second policy exists but no default deny does? (The database is isolated by the second policy, since it selects those pods, and only the API tier may enter.)
- If the first and second policies both exist, can the web tier reach the database? (No, since only API pods are on the list.)
- If the third policy exists but no rule allows the database, can the API tier connect to it? (No. The API pods need an outgoing rule to the database as well.)
- What would change if the fourth policy’s entries were split into two? (Any pod in the ingress namespace, and any pod with the controller label in the web namespace, could enter.)
Take one of your own services and describe its policies in plain sentences like these before writing any real object. If you can explain each rule in one sentence, you understand it well enough to write it.
35Why Network Policies Exist: A Short History
The idea of separating network zones is decades old. Kubernetes had to relearn it for a world where addresses change every minute.
In traditional data centers, security teams protected systems with firewalls placed between network zones. A web server lived in one zone, an application server in another, and a database in a third. Firewall rules named fixed machine addresses, and those addresses rarely changed. A rule written today would still be correct next year.
Containers broke that assumption. A pod may live for minutes, and each new pod gets a new address. Writing firewall rules by address would mean rewriting them constantly. Kubernetes needed a way to describe rules by meaning, such as “the payment service” or “the database tier”, and let the system translate those meanings into current addresses. Labels became that vocabulary, and the Network Policy object became the place to write the rules.
The first versions were intentionally small: allow rules for incoming traffic, by pod, namespace, and address range. Later versions added rules for outgoing traffic, port ranges, and better handling of namespaces. Meanwhile, network plugin makers added more advanced features of their own, and the wider community began designing cluster-wide administrative policies. The core idea has stayed steady: a simple, portable, label-based allow-list.
Old-style firewall rules were like a list of house numbers on a quiet street. Kubernetes is like a festival where the stalls move every hour. Instead of house numbers, you now say, “All stalls flying a green flag may talk to the kitchen.” Labels are the flags.
Fixed machines, fixed rules
Firewalls between zones, with rules tied to stable addresses.
Containers arrive
Addresses change constantly, and address-based rules become impossible to maintain.
Label-based rules
Kubernetes lets owners describe traffic by label, and plugins translate labels into addresses.
Direction and detail added
Outgoing rules, port ranges, and namespace selection make policies more expressive.
Extensions and cluster-wide policies
Plugins and the wider community add deny rules, domain names, logging, and administrator-level guardrails.
36Choosing and Verifying a Network Plugin
Since the plugin does the enforcing, choosing one is a security decision, not only a networking one.
Several well-known plugins enforce Network Policies, while some simple ones do not. The names change over time, and features differ between versions, so treat the questions below as a checklist to answer from current documentation rather than a fixed list of winners.
| Question | Why it matters |
|---|---|
| Does it enforce the standard Network Policy object? | Without enforcement, all policies are decoration |
| Does it enforce both incoming and outgoing rules? | Some support only one direction in older versions |
| How does it filter: firewall tables or in-kernel programs? | Affects speed at scale and the tools you use to debug |
| Does it offer flow logs and metrics? | Visibility is what turns a silent block into a fixable problem |
| Does it provide cluster-wide and deny policies? | Lets platform teams set guardrails that teams cannot remove |
| Does it support name-based egress rules? | Makes external service rules stable over time |
| How does it treat node and host traffic? | Determines whether health checks and node-level services keep working under default deny |
| What happens if its agent fails? | Defines whether the network fails open or closed |
| How is it supported and maintained? | A plugin that is no longer maintained is a long-term security risk |
| Is it offered by your cloud provider’s managed service? | Managed clusters may need an option switched on to enforce policies |
How to verify enforcement in five minutes
- Create a practice namespace with two simple pods, one acting as a server and one as a client.
- Confirm that the client can reach the server. This is your baseline.
- Apply a policy that selects the server and allows no incoming traffic.
- Try again. The connection should now hang and time out.
- Remove the policy, and confirm that the connection works again.
Before you trust a new door lock, you close the door and try the handle from outside. If it opens, you have learned something valuable in one second. This five-minute test is the same simple pull on the handle.
Some managed Kubernetes services need policy enforcement to be switched on when the cluster is created, or later through an add-on. If you skip that step, your policies quietly do nothing. Check your provider’s documentation for the current steps.
37Governing Policies Across Many Teams
When dozens of teams write policies, a little shared discipline keeps the whole picture safe and understandable.
In a large organization, every team wants to move fast, and every team knows its own application best. But the security of the cluster depends on all policies together. Governance is the light framework that lets teams write their own rules while the platform team guarantees a safe floor.
Mandatory baseline
Every namespace receives default deny and standard platform allowances automatically, through templates or admission rules.
One owner per policy
Each policy carries a label or note naming the team responsible, so questions have somewhere to go.
Changes are reviewed
Policy changes travel through the same review process as code, with a second pair of eyes on any rule that opens a new path.
Admission rules for dangerous shapes
Automatic checks reject policies that allow all traffic from everywhere, or that delete the baseline.
Regular reviews
Once a quarter, review policies for retired services, overly broad rules, and gaps in coverage.
Blameless learning
When a policy breaks something, the team treats it as a lesson about missing tests or documentation, not a reason to remove policies altogether.
A typical arrangement
The platform team supplies a namespace template containing default deny, DNS access, monitoring access, and ingress controller access. Application teams add only their own tier-to-tier rules. A nightly report lists namespaces that lack the baseline, and any policy allowing all sources is flagged for review. The result is a cluster where new services are protected from their first minute.
A shopping mall has a shared security system installed by the management, while each shop chooses its own locks and opening hours. The mall guarantees a basic level of safety for everyone, and each shop adds what it needs on top.
38Frequently Asked Questions
Quick answers to the questions that come up most often.
39Summary and Key Takeaways
What to remember about Network Policies
- The default is fully open. Without policies, every pod can reach every other pod and the outside world, so one compromise can spread everywhere.
- Policies are allow-lists. Selecting a pod isolates it in that direction. Only listed traffic is permitted, and several policies add together with no conflicts or ordering.
- Your network plugin enforces them. Kubernetes stores policies, but the plugin’s agents do the filtering. Always prove enforcement with a test that must fail.
- Read rules carefully. Both the sender’s outgoing rules and the receiver’s incoming rules must allow a connection. Rules use pod labels and pod ports, and one entry means AND while two entries mean OR.
- Begin with default deny, and roll out gradually. Start with incoming rules, allow DNS and platform traffic before restricting outgoing, and test in a copy of production first.
- Watch out for silent failures. Blocked connections usually appear as timeouts. Use flow logs, metrics, and a clear troubleshooting order to find the cause.
- Treat policies as part of your application. Keep them in version control, name owners, review changes, and combine them with encryption, least-privilege access, and hardened containers for real defense in depth.