In many Kubernetes clusters, the default network policy is effectively simple:
Anything can talk to anything.
A public-facing frontend may be able to connect directly to a payment database. A monitoring pod may be able to reach the open internet. A compromised container may be able to connect to every service its neighbours can reach, which is often most of the cluster.
Very few teams make a deliberate architectural decision to allow all of this. It is simply the starting state in many environments, and because everything works, the risk stays mostly invisible.
Until there is an incident.
I have spent around twenty years working across development, DevOps, and platform engineering, and this is still one of the most underestimated parts of Kubernetes security. Not because it is especially complicated. Once you see the traffic map, the problem is usually obvious.
The difficulty is that most teams never see the map.
A cluster with unrestricted connectivity can run perfectly for years. Applications deploy, health checks pass, and dashboards stay green. Then one workload is compromised, and the incident report reveals how much of the environment it could reach.
The answer is network microsegmentation: start with no connectivity, then allow only the communication each workload genuinely needs.
This is not a new or product-specific idea. It is simply least privilege applied to the network. But as attacks become faster and cheaper to execute, it is moving from “good security hygiene” to a basic architectural requirement.
It is much easier to build this posture in from the beginning than to bolt it on after an audit or incident.
What a hardened cluster actually looks like
Strip away the tooling and vendor terminology, and a secure Kubernetes network comes down to a handful of properties.
If you can demonstrate these properties, your cluster is in a good position. If you cannot, there are gaps, regardless of what the security dashboard says.
Default-deny, not default-allow
The starting position should be that workloads cannot communicate unless you explicitly allow them to.
That is the network-level expression of zero trust, least privilege, and assume breach.
With default-allow, the team has to identify and block every path that should not exist. That quickly becomes a game of whack-a-mole.
With default-deny, the team defines the smaller set of connections the application actually requires.
In Kubernetes, the exact implementation depends on your CNI or network-policy engine, but the principle is the same: deny first, then add deliberate exceptions.
Allow only the connections the application needs
Once default-deny is in place, the next job is to draw the real application map.
The frontend talks to the API. The API talks to the database. The payment service talks to the payment provider.
That is microsegmentation. Nothing else should be assumed.
The benefit is practical rather than theoretical. If a pod is compromised, the attacker inherits only the network access that pod legitimately requires. They do not automatically gain a path to the rest of the cluster.
Contain lateral movement
Lateral movement is one of the most important properties to test and one of the easiest to overlook.
An assume-breach architecture accepts that, over a long enough period, a workload may be compromised. The real question is what happens next.
Can that workload reach an administrative service? Can it connect to the message bus? Can it scan other namespaces? Can it access databases that have nothing to do with its function?
If the answer is yes, a small foothold can become a cluster-wide incident.
Good segmentation turns a compromise into a contained compromise.
Control egress by destination identity
Outbound traffic matters because it is where data leaves the environment and where command-and-control traffic often enters the picture.
IP-based egress controls can be difficult to maintain. Service addresses change, cloud infrastructure is shared, and external providers may use large or dynamic address ranges.
For many use cases, hostname-aware egress gives you a more useful policy:
This workload may connect to the payment provider’s API, and nowhere else.
Standard Kubernetes NetworkPolicy does not provide hostname-based rules on its own, so this capability depends on the networking or security implementation you choose.
The important requirement is that the rule continues to work when the destination’s underlying IP addresses change.
Make the traffic visible
A policy you cannot observe is difficult to trust.
You should be able to answer basic questions without starting a packet capture or spending an afternoon joining logs:
What is this workload connecting to?
Which services can reach the database?
Is anything making unexpected outbound connections?
Which traffic would a new policy block?
Did the policy actually stop the connection?
Visibility should be part of the normal engineering workflow, not something reserved for incident response.
That is the checklist. Most of the remaining discussion is implementation detail.
These same properties make a useful evaluation guide.
Instead of comparing long feature matrices, test each candidate against a realistic application and ask a few direct questions:
Can it enforce default-deny without turning every policy change into an outage?
Can it contain lateral movement between pods, services, and namespaces?
Can it control egress by hostname and handle changing destination IPs?
Can it show you what is communicating without requiring custom queries for every investigation?
Does it provide the coverage you need across your actual node estate, including Windows Server nodes if you run them?
Do not settle for a slide showing that these capabilities exist.
Test them on a real cluster. Break the application. Apply the controls. Watch what gets blocked. Confirm that legitimate traffic still works.
Any gap you do not find during evaluation becomes a gap your team will have to manage later.
Stop reading and go break something
This is much easier to understand by watching it fail than by reading another explanation.
That is why we built nyx-demo, a free fifteen-module lab based on a deliberately vulnerable sample application called CloudMart.
It runs locally on kind, Kubernetes in Docker, so you do not need a cloud account. When you are finished, cleanup is a single kind delete cluster command.
The quickstart guide takes you from a clean machine to a running environment in a few commands.
The lab begins by accessing sample payment-card data from the public-facing frontend.
There is no network rule stopping it. There is no alert. The connection succeeds because the cluster has not been told that it should not.
That first step makes the default visible.
From there, the modules close the gap in stages:
Apply a default-deny posture.
Add least-privilege allow rules.
Contain lateral movement.
Restrict outbound traffic by hostname.
Observe a simulated attack being blocked.
By the end, you have hardened the cluster yourself. More importantly, you understand why each rule exists and what would happen without it.
For developers, the lab helps build a useful design instinct: stop asking whether a service can reach something and start asking whether it needs to.
For platform engineers, it demonstrates an architecture pattern that can make every cluster safer by default.
For security teams, it provides a concrete demonstration of lateral-movement containment and egress control that can be shared with engineering teams.
For technical leaders, it is an hour shifts security left more effectively than another policy document.
The part that still surprises me
I said this post was not specifically about Nyx, and the security model above applies regardless of which tool you use.
But there is one part of the lab that changed how the work felt for me.
For years, understanding network behaviour meant packet captures, log searches, and slowly building a mental map of the system by hand.
In the lab, Nyx lets you ask questions such as:
What is talking to what?
Or:
Is anything reaching the internet that should not be?
Getting a useful answer in seconds rather than spending an afternoon investigating was genuinely surprising.
The idea of a query interface was not the surprising part. The speed was.
When checking the effect of a policy becomes easy, you check more often. When investigation becomes part of the normal workflow, rather than a specialist task saved for incidents, the security model becomes easier to maintain.
That is difficult to communicate in a tutorial, so I will put it plainly here:
The security discipline is the important part, and that discipline is tool-agnostic. But observability that lets you check your work immediately changes the everyday experience of applying it.
Try the lab for the segmentation model.
Notice the difference that fast feedback makes.
The lab is free and runs on the Nyx free tier. Start at github.com/tracenyx/nyx-demo and follow the QUICKSTART-kind.md guide.
Nyx provides kernel-native network security and observability across Linux and Windows Kubernetes nodes. Learn more at tracenyx.ai.