The Containment Era is here. →Explore

Egress Control

Kubernetes Network Policy: The Complete Guide to Egress Control

A Kubernetes network policy is the primary tool teams use to control how pods communicate inside a cluster and how they reach the world outside it. Most security work starts with inbound access controls, but outbound restrictions are where containment actually happens: bounding what a workload can reach, on every path, so a compromise cannot travel. This guide covers how to write, apply, and enforce network policies with a focus on egress control.

12 min read~ 2,722 wordsNIST SP 800-207 Aligned
KubernetesEgress Control
Kubernetes Network Policy
TL;DR
  • Kubernetes network policies control incoming and outgoing traffic at the pod level using label selectors, namespace selectors, and IP blocks.
  • Outbound controls are just as critical as inbound rules. Without them, a compromised pod can contact any external endpoint.
  • A default deny policy is the right baseline for any namespace handling sensitive workloads, forcing explicit allowlisting of every connection.
  • Multiple network policies apply additively in Kubernetes. Adding a policy can only expand allowed traffic, never restrict it.
  • Native network policies operate at Layer 3 and Layer 4. Multicloud environments and AI workloads typically need enforcement beyond what the Kubernetes network policy spec provides.
What You'll Learn
  • How Kubernetes Network Policies work and how they control pod-to-pod and external network communication.
  • The difference between ingress and egress traffic and why securing both is essential for cluster security.
  • How to implement default deny policies to reduce attack surfaces and enforce least-privilege networking.
  • How to create and manage egress rules that allow only approved outbound connections while blocking unauthorized traffic.
  • Best practices for scaling network security, including namespace-based policies, policy auditing, and CNI plugin considerations.

What Is a Kubernetes Network Policy?

A Kubernetes network policy is a namespaced Kubernetes object that defines rules for how pods communicate with each other and with other network endpoints. It uses label selectors to identify which pods the policy applies to, then specifies what ingress traffic those pods can receive and what egress traffic they can send.

By default, Kubernetes applies no network policies to pods. Every pod in a cluster can reach every other pod without restriction. That permissive default makes early development fast but creates a wide attack surface in any production environment.

Network policies close that gap. They give platform and security teams a declarative way to specify which connections are permitted. Everything not covered by a network policy is blocked once a policy governs a pod.

How Kubernetes Network Policies Are Structured

A network policy is defined using apiVersion: networking.k8s.io/v1 and carries standard Kubernetes metadata including name and namespace. The spec section contains the logic.

Three fields do the main work. The podSelector identifies which pods the policy governs. An empty podSelector matches all pods in the namespace. The policyTypes field tells Kubernetes whether the policy applies to ingress, egress, or both. The ingress and egress blocks then list specific allow rules.

Each rule uses from (for ingress) or to (for egress) to define permitted sources or destinations. These fields accept pod selectors, namespace selectors, and IP blocks. A ports field specifies the TCP port or port range covered by the rule.

Policy-as-Code for Kubernetes Security Get your copy of the guide and discover how to implement scalable, automated security guardrails for Kubernetes using a Policy as Code approach.

Ingress Traffic, Egress Traffic, and Why Both Matter

Ingress traffic is any incoming traffic arriving at a pod from an external source. Egress traffic is any outbound traffic a pod sends to another destination. A complete Kubernetes network policy strategy addresses both directions. Read more.

Many teams configure ingress rules first because blocking unwanted incoming traffic is intuitive. Prevent unauthorized pods from reaching your database, and your internal API looks safer. That logic holds, but it leaves outbound traffic completely uncontrolled.

Uncontrolled outbound traffic is one of the most direct paths to data exfiltration. A compromised workload with no restrictions on what it can send can contact arbitrary external services, exfiltrate credentials over any TCP port, and beacon to attacker infrastructure without any alert firing. Egress ingress symmetry is essential in a real containment model.

Egress Rules: The Policy Layer That Closes the Outbound Gap

Without egress rules, every pod in your Kubernetes cluster is permitted to initiate outbound connections to any IP address, any cloud service, and any domain reachable from your VPC. That is acceptable for development. It becomes a liability the moment workloads carry credentials or sensitive data.

Outbound policy restricts what traffic a pod is allowed to generate. A backend service communicating with a specific database should have a policy permitting exactly that connection on the expected TCP port and nothing else. All other outgoing traffic from that pod should be denied by a default policy.

The Aviatrix Zero Trust network segmentation model extends this principle beyond what native network policies can reach, enforcing policy at the cloud network layer for every workload type. Inside the cluster, getting outbound policy right is the foundation that broader enforcement builds on.

Default Deny: The Baseline That Makes Network Policies Effective

A default deny policy is the foundational posture for any production namespace. Rather than blocking specific exceptions to a permissive default, you deny all traffic and allowlist only what each workload explicitly needs.

You create a default deny for all ingress traffic by writing a network policy with an empty podSelector and no ingress block under policyTypes: [Ingress]. You deny all outgoing traffic the same way with an empty egress block.

Running both together gives every pod in the namespace a clean starting state. No incoming traffic arrives, and no outbound traffic leaves, until a more specific policy grants permission. This dramatically reduces the Blast Radius of any compromised workload.

Default deny policies are especially valuable in multi-tenant clusters where different teams share the same Kubernetes cluster but must not be able to reach each other's services. A deny-everything baseline at the namespace level enforces network segmentation without requiring teams to enumerate every possible cross-namespace path.

Deny All Egress Traffic: Policy Structure and Examples

Here is a policy that implements deny all egress traffic across an entire namespace:

apiVersion: networking.k8s.io/v1

kind: NetworkPolicy

metadata:

  name: default-deny-egress

  namespace: production

spec:

  podSelector: {}

  policyTypes:

  - Egress

The empty podSelector selects all pods in the production namespace. With no egress block specified, no outbound connections are permitted. Any pod in this namespace will have its outgoing traffic blocked until a separate policy explicitly allows it.

You can extend this to deny all incoming traffic as well by adding Ingress to the policyTypes list, giving you a full deny-all baseline for the namespace.

Writing Egress Policy That Allows Specific Outbound Connections

Once a default deny baseline is in place, you layer specific allow policies on top. Here is an example that permits a backend pod to reach a database pod on TCP port 5432:

apiVersion: networking.k8s.io/v1

kind: NetworkPolicy

metadata:

  name: backend-to-db

  namespace: production

spec:

  podSelector:

    matchLabels:

      app: backend

  policyTypes:

  - Egress

  egress:

  - to:

    - podSelector:

        matchLabels:

          app: database

    ports:

    - protocol: TCP

      port: 5432

Pods labeled app: backend are now permitted egress traffic to pods labeled app: database on TCP port 5432. All other outgoing traffic from the backend remains blocked by the default deny policy.

The allowed egress rules stack additively. Multiple network policies targeting the same pods each contribute to the effective allow set. Kubernetes merges them all.

Ingress and Egress Rules Across Namespaces

Kubernetes network policies can govern traffic between namespaces using namespaceSelector. This is essential for Kubernetes network architectures where services in different namespaces need controlled, limited access to each other.

To allow ingress traffic from a specific namespace, add a namespaceSelector to the from block of your ingress rule. You can combine namespaceSelector and podSelector in the same rule to require that incoming traffic come from a specific pod label inside a specific namespace.

Managing ingress and egress rules across namespace boundaries depends on consistent labeling. Namespace selectors match on labels, so every namespace needs reliable, predictable labels that policies can target. Labeling drift is one of the most common reasons network policies stop behaving as expected.

Multiple Network Policies: How They Combine

A key property of Kubernetes network policies is that multiple policies selecting the same pod are additive. The effective allow set is the union of all ingress and outbound allow rules across every policy selecting that pod.

There are no deny rules in a Kubernetes network policy spec. Network policies specify only what is allowed. The denial comes from the absence of a matching allow, not from an explicit block. This means adding a new policy can only expand permitted connections, never restrict a previously allowed one.

For platform teams managing large Kubernetes network deployments, this creates a real operational risk: policy sprawl. As teams add policies over time, the combined allow set grows and becomes difficult to audit. Without a clear ownership model and regular review cycles, multiple network policies quietly erode your security posture.

Network Policy Support Requires the Right Network Plugin

Kubernetes does not enforce network policies on its own. Network policy support depends entirely on the CNI plugin installed in your cluster. If your CNI does not implement the spec, policies are accepted by the API server and silently ignored at runtime.

Popular CNI plugins with network policy support include Calico, Cilium, Weave Net, and Antrea. Each implements the spec differently, with varying performance characteristics and feature coverage.

Before relying on network policies in production, verify enforcement with a test. Deploy a pod, apply a deny all policy, and confirm that blocked connections are actually dropped. Do not assume enforcement because the API accepted your manifest.

Where Native Network Policies Hit Their Limits

What containment means here. Containment is the architectural enforcement of explicit communication policy at every workload, governing what it can reach and what can reach it, by workload identity and protocol, on every path available to it, independent of whether a compromise has been detected. A Kubernetes network policy delivers a slice of that inside the cluster, at Layer 3 and Layer 4. Full containment extends the same principle to every path a workload can take across clouds.

Kubernetes network policies are the right starting point for controlling pod communication and basic outbound access inside a cluster. They are not designed to be a complete solution for enterprise cloud environments.

Native network policies operate at Layer 3 and Layer 4, matching on IP addresses, ports, and protocol. They have no awareness of workload identity beyond pod labels, no application protocol enforcement, and no way to govern egress traffic to cloud services by domain name rather than IP address.

In multicloud environments, this becomes an operational problem. Pods in a Kubernetes cluster on AWS may reach managed services, third-party APIs, and cross-cloud endpoints where IP-based rules are unmanageable because addresses are ephemeral and service endpoints change constantly.

Aviatrix Cloud Native Security Fabric addresses this gap by enforcing policy at the cloud network layer, outside the cluster, using workload identity and application protocol instead of IP addresses and ports. The Distributed Cloud Firewall governs outbound and east-west traffic across VMs, containers, serverless functions, and managed services from a single policy plane.

The Zero Trust networking for Kubernetes at cloud scale solution brief covers exactly where the boundary between native network policies and cloud-layer enforcement sits.

Practical Guidelines for Managing Network Policies at Scale

Start with default deny in every production namespace. Apply both a deny-all incoming and a deny all egress traffic policy first, then add allow rules incrementally as you understand each workload's actual communication needs.

Label every pod and namespace consistently from the start. Network policies are only as reliable as the selectors they use. Establish a labeling convention for apps, tiers, and environments before writing any policy. Pods without consistent labels are invisible to your selectors.

Test every policy before it enforces in production. Several CNI plugins support a monitor-first mode where you observe which traffic would be blocked before dropping any packets. Use this workflow whenever possible.

Audit your effective policy set regularly. With multiple network policies layering across namespaces over time, the combined allow set can drift far from the original intent. A quarterly review of what each workload can actually reach is a lightweight but high-value control.

Conclusion

Kubernetes network policies give security and platform teams a precise, declarative mechanism for controlling pod communication. A default deny baseline, careful outbound policy per workload, and consistent labeling across namespaces together eliminate most of the unnecessary attack surface inside a cluster.

The ceiling shows up at enterprise scale. When egress traffic has to reach cloud native services, multicloud endpoints, and AI workloads cycling through IP addresses faster than any static rule can track, native network policies reach their architectural limit. That is where enforcement at the cloud network layer becomes necessary.

For teams at that point, the Aviatrix Kubernetes security resources are a practical next step. Ready to see what the Cloud Native Security Fabric delivers for your Kubernetes network? Contact Aviatrix.

About Aviatrix

Aviatrix is pioneering the Cloud Native Security Fabric, the architecture the Containment Era requires. The Cloud Native Security Fabric governs every workload communication path across every cloud, every VPC, every Kubernetes cluster, and every serverless function from a single policy plane. One rule. Universal propagation. Enforced at the workload, not at a chokepoint. Trusted by more than 500 of the world's leading enterprises. Visit aviatrix.ai to learn more.

References

  1. https://kubernetes.io/docs/concepts/services-networking/network-policies/

  2. https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy/

  3. https://www.cncf.io/reports/cncf-annual-survey-2023/

  4. https://aviatrix.ai/resources/zero-trust-networking-for-kubernetes-at-cloud-scale/

  5. https://aviatrix.ai/products/zero-trust-for-workloads/distributed-cloud-firewall/

Frequently Asked Questions
Partially. A [default deny egress policy](https://aviatrix.ai/learn-center/the-containment-era/default-deny-egress/) stops a compromised pod from opening arbitrary outbound connections inside the cluster, which is a real reduction in Blast Radius. But native network policies operate at Layer 3 and Layer 4 on IP addresses and ports, so they cannot govern egress to cloud services, third-party APIs, or multicloud endpoints by workload identity or domain, and those addresses change constantly. Bounding the Blast Radius across every path a workload can take requires enforcement at the cloud network layer, using workload identity and application protocol rather than IPs and ports.
By default, Kubernetes imposes no restrictions. Any pod can reach any other pod in the cluster on any port. Applying a default deny policy immediately overrides this, blocking all traffic until explicit allow rules are added.
Yes. The policyTypes field specifies whether a policy applies to ingress traffic, egress traffic, or both. A policy listing only Egress has no effect on incoming connections to that pod.
Multiple network policies are additive. Kubernetes unions all allowed ingress and egress rules across every policy selecting a given pod. A new policy can only expand what is permitted, never restrict a previously allowed connection.
No. Network policy support depends on the CNI plugin installed in your cluster. Without a compatible plugin such as Calico or Cilium, policies are accepted by the API server but not enforced at runtime.
Take the Next Step

Ready to Move Beyond Native Network Policies?

Kubernetes network policies help control pod communication, but they stop at Layer 3 and Layer 4. Modern workloads connect to cloud services, third-party APIs, AI platforms, and multicloud environments

Share This On:

See It in ActionKubernetes Network

Watch how Aviatrix simplifies Kubernetes egress control across multi-cloud environments no YAML wrestling required.

Access Demo