Marcio Cunha

Data leaks in Kubernetes? How to isolate workloads

Learn how to secure your Kubernetes cluster against lateral pod invasions using native NetworkPolicies. Restrict Layer 3 and Layer 4 traffic with practical configuration examples.

Marcio Cunha•4 min
Also available in:PortuguêsEspañol
Summary
  • The default Kubernetes networking behavior allows any pod to communicate freely with any other pod in the cluster.
  • NetworkPolicies operate at the OSI network layers 3 and 4, controlling IP addresses, ports, and transport protocols.
  • Implementing default deny policies creates a secure perimeter where traffic must be explicitly authorized.
  • Severe issues like pods stuck in CrashLoopBackOff require rapid diagnostics to prevent long-lasting security gaps.
  • Proper namespace isolation prevents an application compromise from propagating to critical databases.

The invisible danger of open pod communication in Kubernetes

When we create a Kubernetes cluster, the default configuration is surprisingly permissive. In practice, this means that any pod—the smallest deployable computing unit you manage that holds one or more containers—can freely talk to any other pod or service across any namespace, which acts as a logical division to separate environments. If an attacker manages to breach a public-facing web application, they gain free rein to scan the internal network and attempt to take down the database. This is precisely where implementing security barriers at lower network layers becomes urgently necessary.

Many teams blindly rely on cloud perimeter security and forget that lateral movement inside the cluster is one of the favorite attack vectors. To mitigate this risk efficiently, network engineering must look at layers 3 and 4 of the OSI model, controlling IP addresses, TCP, and UDP ports. Just like we tackle complex infrastructure issues—such as investigating why Kubernetes pods get stuck in CrashLoopBackOff or managing CPU resources using cgroups in Docker—network security demands technical rigor, predictability, and constant testing to ensure no loopholes remain open.

What NetworkPolicies are and how they secure your cluster

NetworkPolicies are native declarative rules in Kubernetes that act as an intelligent firewall for your pods. In practice, they use label selectors to decide which connections enter and leave a specific set of pods. When you apply a default deny policy, the cluster drops all traffic by default, requiring you to write specific rules to allow only what is strictly necessary. This transforms a completely open network into a segmented, least-privilege environment.

To understand the technical mechanics, imagine network traffic as an office building where the doors are unlocked. Without a NetworkPolicy, anyone can enter any room. With the policy active, each door requires a specific badge based on who is calling and which service port is being accessed. This approach protects sensitive applications against malicious scans and prevents a credential leak in a minor service from compromising the entire microservice ecosystem. The operational effort of configuration is heavily outweighed by the security gains.

Creating your first Layer 3 and Layer 4 isolation rule

The practical implementation of a NetworkPolicy requires careful attention to namespace and pod selectors to guarantee surgical precision. Below, we present a functional YAML manifest that blocks all incoming traffic in a specific namespace, allowing only a frontend pod to talk to the database on port 5432. This is an excellent starting point to shield production environments from unauthorized access by neighboring pods that have no business seeing confidential data.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: isolate-database
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: postgresql
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 5432

In this manifest, the podSelector block identifies the target of the rule, which in this case is the database labeled as app: postgresql. The ingress block strictly defines who is permitted entry, limiting the origin to pods labeled as app: frontend and restricting the transport protocol strictly to TCP port 5432. Any connection attempt from another source or port will be silently dropped by the cluster's network plugin, ensuring the integrity and confidentiality of the stored information.

Common pitfalls and the crucial role of the CNI in Kubernetes

A classic mistake made by novice administrators is applying NetworkPolicies without checking whether their CNI—the container network interface responsible for implementing connectivity rules at the node level—actually supports this functionality. Basic network plugins like the default kubenet in some simple environments simply ignore these policies without throwing any error warnings, leaving the operator with a false sense of security. For isolation to truly work, you must use robust and compatible CNIs such as Calico, Cilium, or Flannel with policy support enabled.

Another critical point of attention concerns outbound traffic, known as Egress. If you only configure ingress traffic, applications can still make arbitrary requests out of the namespace, opening potential loopholes for data exfiltration to external servers controlled by attackers. Network security planning must cover both ingress and egress, establishing rigid perimeters that hinder any attempt at unwanted lateral communication or leaking sensitive information to the public internet.

Validating and testing traffic isolation in practice

After applying your network policies, never assume they work perfectly without running practical validation tests. The simplest and most direct way to test the block is to create a temporary pod with command-line tools like curl or netcat inside an unauthorized namespace and attempt to reach the protected service. If the traffic is successfully cut off, the connection will hang awaiting a timeout or return a connection refused error, confirming that the cluster firewall is doing its job properly.

Maintaining this testing routine should be part of your infrastructure's continuous delivery lifecycle, integrating security verifications whenever routing rules change. By combining a rigorously segmented network with good observability and resource control practices, we transform Kubernetes into a resilient environment capable of withstanding serious security incidents, protecting user data and company reputation against persistent threats.