✦ For everyone, free.

Practical knowledge for real and everyday life

Home

Kubernetes Network Safety Guidelines

Kubernetes Network Safety Guidelines outline best practices for securing cluster communication, isolation, and access control.

Kubernetes Network Safety Guidelines describe the practices for restricting and securing traffic flow between workloads inside a cluster and between the cluster and the outside world, given that Kubernetes' default networking model permits any Pod to reach any other Pod across the entire cluster unless something explicitly restricts it. These guidelines cover network policy design, ingress and egress control, encryption in transit, and the layered defenses needed to prevent a single compromised workload from becoming a pivot point into the rest of the cluster.


The Default-Open Network Model

Flat Pod-to-Pod Connectivity

By default, every Pod in a Kubernetes cluster can initiate a connection to every other Pod, regardless of namespace, unless a NetworkPolicy says otherwise and a CNI plugin capable of enforcing NetworkPolicy is installed. This flat model is convenient for getting workloads talking to each other quickly, but it means a compromised Pod anywhere in the cluster can, by default, probe and reach every other workload — including ones with no legitimate reason to be reachable from it.

CNI Plugin Enforcement Is a Prerequisite

NetworkPolicy objects are inert unless the cluster's CNI plugin actually implements policy enforcement. A cluster running a CNI plugin without NetworkPolicy support will silently accept policy objects without enforcing them at all, giving a false sense of security — verifying enforcement capability is a prerequisite to relying on network policy as a control.


Designing NetworkPolicy

Default Deny as the Baseline

The strongest starting posture is a default-deny NetworkPolicy per namespace (an empty pod selector with no ingress/egress rules allowed), after which specific, minimal allow rules are added for exactly the traffic each workload legitimately needs. Building policies additively from default-deny produces a far tighter final posture than starting open and trying to subtract dangerous paths after the fact.

Ingress and Egress Are Independent

Kubernetes NetworkPolicy controls ingress and egress separately, and a policy restricting one does not implicitly restrict the other. Egress control is frequently neglected relative to ingress control, but is equally important — it's what prevents a compromised Pod from exfiltrating data to an arbitrary external endpoint or scanning the internal network for other targets.

Namespace and Pod Selector Scoping

Policies should scope allowed traffic as narrowly as the actual application topology requires — allowing traffic only from Pods with a specific label in a specific namespace, rather than allowing an entire namespace or, worse, all namespaces. Namespace-level allow rules are a common source of unintended over-permissiveness, since they implicitly trust everything currently or later deployed into that namespace.

DNS as a Required Exception

Because DNS resolution is itself a network call, a default-deny egress policy must explicitly allow traffic to the cluster's DNS service (commonly kube-dns on port 53), or every affected workload will fail to resolve any service name, including ones it's otherwise allowed to reach.


Ingress Traffic From Outside the Cluster

Ingress Controllers as a Single, Auditable Entry Point

Consolidating externally-facing HTTP(S) traffic behind a small number of Ingress controllers, rather than exposing many individual LoadBalancer Services directly, creates a single point where TLS termination, request validation, and rate limiting can be applied consistently, and a single surface that needs to be audited for exposure.

TLS Termination and Certificate Management

Ingress resources should terminate TLS using certificates managed through an automated issuance and rotation mechanism, since manually managed certificates are a frequent source of expiry-related outages. Traffic between the ingress layer and backend Pods should also be encrypted where it crosses trust boundaries, not just at the external edge.


Service Mesh and mTLS

Mutual TLS Between Workloads

A service mesh (or a CNI plugin with built-in encryption support) can enforce mutual TLS for all Pod-to-Pod traffic automatically, providing both encryption in transit and cryptographic workload identity — meaning traffic can be authorized based on a verified service identity rather than trusting the network path or source IP alone.

Defense in Depth, Not a Replacement for NetworkPolicy

mTLS provides encryption and identity verification, but is not a substitute for NetworkPolicy — the two operate at different layers and should be applied together. mTLS proves who is talking, NetworkPolicy restricts who is allowed to talk to whom in the first place.


Namespace and Cluster-Level Isolation

Multi-Tenant Isolation

In clusters shared across multiple teams or applications, namespace boundaries paired with default-deny NetworkPolicy per namespace form the baseline isolation layer between tenants, preventing one team's workload from being network-reachable by another's without an explicit, reviewed exception.

Control Plane and Node Metadata Endpoint Protection

Egress policies should specifically restrict access to sensitive infrastructure endpoints — the Kubernetes API server from workloads that don't need it, and cloud provider instance metadata endpoints, which are a common target for credential theft from a compromised Pod if left reachable by default.


Example Configuration

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: codartium
spec:
  podSelector: {}
  policyTypes: ["Ingress", "Egress"]
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: codartium-api-allow
  namespace: codartium
spec:
  podSelector:
    matchLabels:
      app: codartium-api
  policyTypes: ["Ingress", "Egress"]
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: ingress-nginx
      ports:
        - protocol: TCP
          port: 8080
  egress:
    - to:
        - namespaceSelector: {}
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - protocol: UDP
          port: 53
    - to:
        - podSelector:
            matchLabels:
              app: codartium-db
      ports:
        - protocol: TCP
          port: 5432

Practical Consequences

A cluster built around these guidelines confines a compromised workload's blast radius to only what it was explicitly permitted to reach, encrypts sensitive traffic in transit, and exposes a small, auditable set of external entry points. Neglecting them leaves the default flat network in place, where a single exploited application-layer vulnerability in one workload becomes a foothold for lateral movement across the entire cluster, unrestricted data exfiltration, and unauthorized access to internal services that were never meant to be reachable from outside their intended callers.