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

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

kubenet ignores policies, need Cilium/Calico/Weave

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