Kubernetes Tutorial · Networking · Lesson 16 of 26

Network Policies

Default-deny traffic between pods and allow only what each service needs.

Create a free account to save this page, take notes and track your progress. Sign in

Pods can talk to everything by default

Without policies, any pod can connect to any other pod in the cluster. NetworkPolicies restrict that, if the network plugin enforces them (Calico, Cilium and others do; check yours).

A common pattern per namespace:

  1. A default-deny policy selecting all pods.
  2. Allow rules for the traffic each service needs (for example, from pods labelled app: api to app: db on port 5432), plus DNS egress if you also restrict egress.
Default deny, then allow api to db
kubectl create namespace demo-netpol > /dev/null
trap 'kubectl delete namespace demo-netpol --wait=false > /dev/null' EXIT
kubectl -n demo-netpol run db --image=redis:8-alpine --labels=app=db > /dev/null
kubectl -n demo-netpol expose pod db --port=6379 > /dev/null
kubectl -n demo-netpol wait --for=condition=Ready pod/db --timeout=120s > /dev/null
try() { kubectl -n demo-netpol run "client-$1" --rm -i --restart=Never --image=redis:8-alpine --labels="app=$1" -- sh -c 'timeout 3 redis-cli -h db ping 2>/dev/null || echo blocked' 2>/dev/null | head -1; }
echo "no policy, from app=api:     $(try api)"
cat > policy.yaml <<'EOF'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: {name: default-deny}
spec:
  podSelector: {}
  policyTypes: [Ingress]
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: {name: api-to-db}
spec:
  podSelector: {matchLabels: {app: db}}
  ingress:
    - from: [{podSelector: {matchLabels: {app: api}}}]
      ports: [{port: 6379}]
EOF
kubectl -n demo-netpol apply -f policy.yaml > /dev/null
sleep 3
echo "with policies, from app=api: $(try api)"
echo "with policies, from app=web: $(try web)"

Output

no policy, from app=api:     PONG
with policies, from app=api: PONG
with policies, from app=web: blocked

Run this on your computer — see “Get Started” for setup.

Test yourself

After a default-deny ingress policy, which traffic reaches a pod?

  1. All traffic from the same namespace
  2. Only traffic explicitly allowed by another policy selecting that pod
  3. Nothing, ever
  4. Only DNS
Show answer

Answer: Only traffic explicitly allowed by another policy selecting that pod

Policies are additive allow-lists once a pod is selected by any policy.

Was this page helpful?