Network Policies
Deny-All Default Policies
# Deny all ingress in a namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: production
spec:
podSelector: {} # applies to ALL pods in namespace
policyTypes:
- Ingress
---
# Deny all egress in a namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
---
# Deny all ingress and egress (most restrictive)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Ingress Rules
# Allow ingress from specific pods in same namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-api
namespace: production
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
---
# Allow from specific namespace + pod selector
spec:
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring
podSelector:
matchLabels:
app: prometheus
ports:
- protocol: TCP
port: 9090
Egress Rules
# Allow egress to database only
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-egress
namespace: production
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Egress
egress:
# Allow to database pods
- to:
- podSelector:
matchLabels:
app: postgres
ports:
- protocol: TCP
port: 5432
# Allow DNS resolution
- ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
# Allow to external HTTPS
- ports:
- protocol: TCP
port: 443
Namespace Selectors
# Allow ingress from all pods in "frontend" namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-frontend-ns
spec:
podSelector:
matchLabels:
app: api
ingress:
- from:
- namespaceSelector:
matchLabels:
team: frontend
# IMPORTANT: namespaceSelector AND podSelector in same
# "from" element means BOTH must match (AND logic)
# Separate "from" elements mean OR logic
# OR: from frontend namespace OR from monitoring pod
ingress:
- from:
- namespaceSelector:
matchLabels:
team: frontend
- from:
- podSelector:
matchLabels:
app: prometheus
IP Block Rules
# Allow ingress from specific CIDR
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-external-loadbalancer
spec:
podSelector:
matchLabels:
app: web
ingress:
- from:
- ipBlock:
cidr: 203.0.113.0/24
except:
- 203.0.113.5/32
ports:
- protocol: TCP
port: 80
# Allow egress to external services (exclude cluster range)
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
Common Patterns
| Pattern | Use Case |
|---|---|
| Deny-all + explicit allows | Zero-trust namespace isolation |
| Allow same-namespace only | Micro-service namespace isolation |
| Allow from ingress controller | Restrict external traffic path |
| Allow DNS egress only | Internet-isolated workloads |
| Allow monitoring scrape | Prometheus can reach all namespaces |