Hedronite · Ops Lesson · 01-Earth-DevOps / EKS · Wed 2026-09-09

EKS NetworkPolicy with VPC CNI — namespace isolation, least-permissive ingress

Default-deny is a decision. An empty ingress list is not the same as no policy object.

Lesson Class: Ops (DevOps + EKS + NetworkPolicy)
Cloud Referent: EKS VPC CNI network policy agent + frontend/backend isolation
Paired Dev: Python kubernetes NetworkPolicy inventory
Paired Cert: CKA Network Policies least-permissive allowlists
Paired Go: client-go NetworkPolicy informer
Grounding: CKA Q13 · Q8 · Kubernetes Up & Running
Enforce
CNI must honor NetworkPolicy.
Select
Labels and namespaces, not hope.
Narrow
Least permissive peer list.
Ship the narrow allow. Measure enforcement first.

Default-deny is a decision. An empty ingress list is not the same as "no policy object."

§I — Frame

On EKS, pods speak through the Amazon VPC CNI by default. Adding a NetworkPolicy only helps if the cluster actually enforces policies. Today is the ops shape for that: enable enforcement, isolate namespaces, and pick the least-permissive ingress that still lets frontend reach backend. This is not IRSA (09-06) and not Ingress HTTP routing (09-03).

§II — Foundations: three layers

  1. CNI capability. Flannel without a policy engine will not honor NetworkPolicy. Calico will. On EKS, Amazon VPC CNI can enforce network policies when the network policy agent is enabled for the cluster version you run. If enforcement is off, YAML applies and nothing changes. That is the first outage class: "we shipped policy, traffic still flows."
  1. Namespace selection. podSelector: {} selects all pods in the policy namespace. Cross-namespace allowlists need namespaceSelector (and often podSelector) on ingress peers. Frontend in frontend talking to backend in backend is the Bootcamp Q13 shape.
  1. Ingress vs egress. Ingress rules answer "who may dial me." Egress rules answer "where may I dial." Least privilege usually starts with default-deny ingress in the sensitive namespace, then explicit allow from the caller labels.

§III — Worked EKS shape

Assume two Deployments: app=frontend in frontend, app=backend in backend, Service DNS backend-service.backend.svc.cluster.local.

Ops checklist before YAML:

Example least-permissive ingress on backend:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: backend
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes: ["Ingress"]
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: frontend
          podSelector:
            matchLabels:
              app: frontend
      ports:
        - protocol: TCP
          port: 80

Compare to a policy that allows all namespaces, or that adds an extra CIDR "just in case." Those are wider. CKA Q13 trains the eye: pick the YAML that matches the requirement and nothing more.

§IV — Failure modes

§V — What belongs outside NetworkPolicy

§VI — How this differs from last K8s Ops

09-06 spent OIDC issuer, SA annotation, IAM trust. 09-03 spent AKS Ingress paths. Today spends EKS policy enforcement and least-permissive ingress between namespaces.

§VII — Operator checklist

  1. Enforcement enabled on VPC CNI / policy agent.
  2. Namespaces and pod labels verified.
  3. Backend ingress allows only frontend peer selectors + needed port.
  4. Connectivity test from a frontend pod; deny test from an outsider namespace.
  5. Inventory NetworkPolicies cluster-wide (Dev/Go companions).

§VIII — Closing

Ship the narrow allow. Measure enforcement first. Leave Ingress and IRSA lessons on their own shelves.

Related