Networking
Network Policies
Ingress/egress rules, pod/namespace selectors, default deny policies, and CIDR blocks.
Overview
- Namespace-scoped resources that control traffic flow to/from pods
- Work as a whitelist — once a NetworkPolicy selects a pod, all traffic not explicitly allowed is denied
- Pods without any NetworkPolicy applied accept all traffic by default
- Require a CNI plugin that supports NetworkPolicies (Calico, Weave — Flannel does NOT)
Key Concepts
Pod Selector
spec.podSelectorselects which pods the policy applies to- Empty
podSelector: {}selects all pods in the namespace
Policy Types
Ingress: controls incoming traffic to selected podsEgress: controls outgoing traffic from selected pods- If not specified, defaults to Ingress only (if ingress rules exist)
Ingress Rules (from)
Traffic sources can be defined using:
- podSelector: pods in the same namespace matching labels
- namespaceSelector: pods in namespaces matching labels
- ipBlock: CIDR ranges (e.g.,
172.17.0.0/16), with optionalexcept
Egress Rules (to)
Traffic destinations can be defined using:
- podSelector: pods in the same namespace matching labels
- namespaceSelector: pods in namespaces matching labels
- ipBlock: CIDR ranges
- ports: specific ports and protocols (TCP/UDP)
Combining Selectors
- Multiple items in a single
from/toentry = AND (all must match) - Multiple entries in the
from/toarray = OR (any can match)
Allow ingress from specific pods
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-app
spec:
podSelector:
matchLabels:
app: nginx
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 80
Allow ingress from specific namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-namespace
spec:
podSelector:
matchLabels:
app: nginx
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
env: production
ports:
- protocol: TCP
port: 80
Allow egress to specific CIDR
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-egress-cidr
spec:
podSelector:
matchLabels:
app: nginx
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 443
Default Policies
Default deny all ingress
- Apply a NetworkPolicy with
podSelector: {}andpolicyTypes: ["Ingress"]with no ingress rules - Denies all incoming traffic to all pods in the namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
spec:
podSelector: {}
policyTypes:
- Ingress
Default deny all egress
- Apply a NetworkPolicy with
podSelector: {}andpolicyTypes: ["Egress"]with no egress rules - Denies all outgoing traffic from all pods in the namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
spec:
podSelector: {}
policyTypes:
- Egress
Default deny all (ingress + egress)
- Combine both policy types with no rules
Useful Commands
# list network policies
kubectl get networkpolicies
# or
kubectl get netpol
# describe a network policy
kubectl describe netpol <policy-name> -n <namespace>
# check which pods are selected by a policy
kubectl get pods -n <namespace> -l <label-selector-from-policy>
Notes
- NetworkPolicies are additive — they never conflict, the union of all policies applies
- DNS traffic (port 53 TCP/UDP) is often needed in egress rules, otherwise pods can't resolve service names
- Allow egress to
kube-dnswhen applying default deny egress