100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Kubernetes

Network Policies

How Kubernetes NetworkPolicy locks down the default flat, open Pod network using default-deny baselines, selector-based rules, and CNI-dependent enforcement.

NetworkingAdvanced12 min readJul 10, 2026
Analogies

Network Policies

By default, every Pod in a Kubernetes cluster can reach every other Pod, a flat, fully open network, which is convenient for getting started but is a serious liability in production multi-tenant or compliance-sensitive environments. A NetworkPolicy is a namespaced resource that uses a label selector to pick a set of Pods and then declares an allow-list of permitted ingress and/or egress traffic; critically, NetworkPolicies are purely additive and default-deny once any policy selects a Pod, meaning the moment one policy targets a Pod for ingress, all ingress traffic not explicitly allowed by some policy is dropped.

🏏

Cricket analogy: It's like an open-access practice ground where any local player can walk in and bowl in the nets by default, until the academy posts a sign-in sheet restricting access to only registered players for a specific net session, at which point anyone not on that list is turned away from that net.

Ingress and Egress Rule Anatomy

A NetworkPolicy's podSelector picks the target Pods, and its policyTypes list, Ingress, Egress, or both, determines which direction is restricted; each rule under ingress or egress combines from/to peer selectors, which can be podSelector (Pods by label, scoped to the same namespace unless combined with namespaceSelector), namespaceSelector (entire namespaces by label), or ipBlock (CIDR ranges, typically for traffic to/from outside the cluster), with an optional ports list restricting protocol and port. An empty ingress: [] with no rules means default-deny-all-ingress for the selected Pods, while omitting ingress from policyTypes entirely means ingress is left unrestricted by this particular policy, a distinction that trips up almost everyone the first time.

🏏

Cricket analogy: It's like a stadium's VIP box having a guest list where you specify allowed individuals by name, allowed entire delegations by team badge, or an allowed range of seat numbers for corporate blocks, and leaving the guest list completely blank means nobody at all gets in, a subtly different rule from not checking the guest list in the first place.

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-allow-from-frontend
  namespace: prod
spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: gateway
      ports:
        - protocol: TCP
          port: 8080
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: data
      ports:
        - protocol: TCP
          port: 5432
    - to:
        - ipBlock:
            cidr: 0.0.0.0/0
            except: ["169.254.169.254/32"]   # block cloud metadata endpoint
      ports:
        - protocol: TCP
          port: 443

Default-Deny Baselines

A common production pattern is to apply a namespace-wide default-deny policy first, one with an empty podSelector: {} matching every Pod and policyTypes: [Ingress, Egress] with no rules, then layer on specific allow policies for each legitimate communication path, so nothing is reachable except what's been explicitly justified. This whitelist-first posture is far safer than trying to enumerate every bad actor after the fact, but it also means that during incident response or a new deployment, forgetting an egress rule for DNS (port 53 to kube-system) is one of the most common ways teams accidentally break an entire namespace.

🏏

Cricket analogy: It's like a ground curator locking every gate around the stadium first, then issuing individual keys only to groundstaff, security, and ticketed sections one by one, rather than leaving every gate open and trying to eject unauthorized people after they've already wandered onto the pitch.

A default-deny Egress policy silently breaks DNS resolution unless you explicitly allow egress to kube-dns/CoreDNS on UDP and TCP port 53 in kube-system; this is the single most common self-inflicted outage when teams roll out default-deny for the first time, because Pods that can't resolve DNS also can't reach Services by name, masking the real root cause as a mysterious application timeout.

CNI Support and Enforcement Boundaries

NetworkPolicy is a Kubernetes API specification, not an enforcement mechanism, the API server will happily accept and store a NetworkPolicy object even if no component in the cluster is capable of enforcing it, so if your CNI plugin, Flannel in its default configuration, for instance, doesn't implement the NetworkPolicy controller, every policy you write is silently ignored while looking perfectly valid in kubectl get. Calico, Cilium, and Weave Net all implement enforcement, and Cilium in particular extends the base API with CiliumNetworkPolicy for L7-aware rules, like restricting an HTTP path or a specific gRPC method, that plain Kubernetes NetworkPolicy cannot express since it only understands L3/L4, IPs, ports, and protocols.

🏏

Cricket analogy: It's like a league officially publishing a strict anti-doping rulebook that every team receives, but if the specific host board never actually contracts a testing lab to enforce it at a given tournament, the rules exist on paper while zero athletes are ever actually tested that season.

Always verify enforcement with a real test, deploy two Pods, apply a deny policy between them, and confirm connectivity actually fails with kubectl exec and curl or nc, rather than trusting that kubectl get networkpolicy returning your object means anything is actually being blocked.

  • By default, all Pods in a cluster can reach all other Pods; NetworkPolicy is required to restrict this.
  • NetworkPolicies are additive and default-deny-once-selected: the moment any policy selects a Pod for Ingress or Egress, unlisted traffic in that direction is dropped.
  • Peers are matched via podSelector, namespaceSelector, or ipBlock, optionally combined with a ports restriction.
  • A namespace-wide default-deny baseline plus specific allow policies is the recommended production pattern.
  • Forgetting to allow egress to CoreDNS on port 53 is the most common cause of self-inflicted outages after enabling default-deny.
  • NetworkPolicy is only an API spec; it requires a CNI plugin (Calico, Cilium, Weave Net) that implements enforcement, otherwise policies are silently ignored.
  • Cilium's CiliumNetworkPolicy CRD extends beyond L3/L4 to L7-aware rules like HTTP paths or gRPC methods, which plain NetworkPolicy cannot express.

Practice what you learned

Was this page helpful?

Topics covered

#Kubernetes#AdvancedKubernetesStudyNotes#DevOps#NetworkPolicies#Network#Policies#Ingress#Egress#Networking#StudyNotes#SkillVeris