Cheveo Cheatsheet

NetworkPolicy Cheatsheet

12 production-ready YAML patterns for copy-paste. From deny-all to Prometheus scraping, including the AND-vs-OR trap and common mistakes.

Read the article →

The workflow

1 Deny-All
2 Ingress
3 Egress
4 Test
5 Monitoring

CNI compatibility

Not every CNI plugin enforces NetworkPolicies. kubectl apply always accepts the policy — even if it's never enforced.

CNI plugin Enforced? Note
Flannel No Ignores policies completely
kubenet No No policy support
kindnet No Policies accepted, never enforced
AWS VPC CNI (EKS) No Opt-in: Network Policy Controller v1.14+
Azure CNI (AKS) No Opt-in: Network Policy Manager or Calico
GKE Default No Opt-in: Dataplane V2 or Calico at creation
Cilium Yes eBPF-based, full support
Calico Yes Full support, also as add-on (Canal)
Weave Net Yes Full support
Antrea Yes Full support

Managed K8s (EKS, AKS, GKE): Policy enforcement is an opt-in feature. Verify your CNI actually enforces policies before deploying them.

kubectl get pods -n kube-system -l k8s-app=cilium
kubectl get pods -n kube-system -l k8s-app=calico-node
# EKS: check Network Policy Controller
kubectl describe daemonset aws-node -n kube-system | grep ENABLE_NETWORK_POLICY

Deny defaults

1

Deny All Ingress

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
  namespace: <ns>
spec:
  podSelector: {}
  policyTypes:
    - Ingress

→ Blocks all inbound traffic. Foundation for zero-trust.

2

Deny All Egress

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-egress
  namespace: <ns>
spec:
  podSelector: {}
  policyTypes:
    - Egress

→ Blocks all outbound traffic. Always combine with DNS egress (pattern 10).

3

Deny All (beides)

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
  namespace: <ns>
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress

→ Full namespace isolation. Open patterns one by one from here.

Namespace & pod

4

Allow Same Namespace

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-same-namespace
  namespace: <ns>
spec:
  podSelector: {}
  ingress:
    - from:
        - podSelector: {}
  policyTypes:
    - Ingress

→ Pods in the same namespace can reach each other, nothing from outside.

5

Allow from Namespace

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-namespace
  namespace: <ns>
spec:
  podSelector: {}
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              name: backend
  policyTypes:
    - Ingress

→ Allows traffic from a specific namespace (label required).

6

Allow Specific Port

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-http-only
  namespace: <ns>
spec:
  podSelector:
    matchLabels:
      app: web
  ingress:
    - ports:
        - port: 8080
          protocol: TCP
      from:
        - podSelector: {}
  policyTypes:
    - Ingress

→ Only port 8080/TCP, only from the same namespace.

Infrastructure

7

Allow Ingress Controller

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-ingress
  namespace: <ns>
spec:
  podSelector:
    matchLabels:
      app: web
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              name: ingress-nginx
  policyTypes:
    - Ingress

→ Lets the ingress controller reach the app. Without it: app unreachable from outside.

8

Allow Prometheus (AND)

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-prometheus
  namespace: <ns>
spec:
  podSelector: {}
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              name: monitoring
          podSelector:
            matchLabels:
              app.kubernetes.io/name: prometheus
      ports:
        - port: 9090
          protocol: TCP
  policyTypes:
    - Ingress

→ AND variant: only Prometheus from the monitoring namespace.

9

Allow Backend → DB

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-backend-to-db
  namespace: <ns>
spec:
  podSelector:
    matchLabels:
      app: database
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: backend
      ports:
        - port: 5432
          protocol: TCP
  policyTypes:
    - Ingress

→ Only the backend may reach the DB, only port 5432.

Egress control

10

Allow DNS Only

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-egress
  namespace: <ns>
spec:
  podSelector: {}
  egress:
    - ports:
        - port: 53
          protocol: UDP
        - port: 53
          protocol: TCP
  policyTypes:
    - Egress

→ Most important egress pattern. Without DNS no service discovery.

11

Allow External CIDR

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-egress-to-db
  namespace: <ns>
spec:
  podSelector:
    matchLabels:
      app: backend
  egress:
    - to:
        - ipBlock:
            cidr: 10.0.0.0/24
      ports:
        - port: 5432
          protocol: TCP
    - ports:
        - port: 53
          protocol: UDP
  policyTypes:
    - Egress

→ Egress to external DB (subnet + port) plus DNS.

12

Allow Internal Service

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-api
  namespace: <ns>
spec:
  podSelector:
    matchLabels:
      app: frontend
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: api
      ports:
        - port: 8080
          protocol: TCP
    - ports:
        - port: 53
          protocol: UDP
  policyTypes:
    - Egress

→ Frontend may only talk to the API service plus DNS.

5 most common mistakes

Each one has cost us hours in production at least once.

1

Forgot DNS egress

Deny-all-egress without port 53 breaks everything

2

Confused AND vs OR

One dash opens access far wider than intended

3

Missing namespace labels

namespaceSelector matches labels, not the name

4

CNI does not enforce

Flannel, kubenet, kindnet, and the defaults of EKS, AKS, GKE silently ignore policies. Need Cilium/Calico/Weave/Antrea.

5

Ingress only, no egress

Ingress alone does not control outbound traffic

Quick decisions

Pods can access everything
→ Deny-all + explicit allows
Service unreachable after policy
→ Forgot DNS egress (pattern 10)
Ingress controller blocked
→ Allow from ingress NS (pattern 7)
Prometheus stopped scraping
→ Allow from monitoring NS (pattern 8)
Policy has no effect
→ Check CNI (Cilium/Calico?)
1-Day Intensive Workshop

Kubernetes Debugging - systematic, not guesswork

Replay real production incidents, internalise kubectl workflows, find root causes in minutes.

View workshop details