Network Policy¶
NetworkPolicy is a Kubernetes resource that controls traffic between pods and/or network endpoints. It acts as a firewall for your pods, allowing you to specify which connections are allowed.
什么是Network Policy¶
Key Concepts:
Pod-level Firewall: Controls ingress (incoming) and egress (outgoing) traffic for pods
Label-based Selection: Uses labels to select which pods the policy applies to
Default Deny: By default, all traffic is allowed; NetworkPolicies create restrictions
Namespace-scoped: NetworkPolicies are namespace resources
Requires CNI Support: Your CNI plugin must support NetworkPolicy (Calico, Cilium, Weave Net)
Without NetworkPolicy:
All pods can communicate with all pods (default allow-all behavior)
With NetworkPolicy:
You can:
Isolate pods from each other
Allow only specific pods to communicate
Restrict access to specific ports
Control external traffic
前提条件¶
Check if your CNI supports NetworkPolicy:
# Common CNI plugins with NetworkPolicy support:
# ✅ Calico
# ✅ Cilium
# ✅ Weave Net
# ✅ Antrea
# ❌ Flannel (does not support NetworkPolicy)
# Check your CNI
$ kubectl get pods -n kube-system | grep -E "calico|cilium|weave|flannel"
If using Flannel, you need to switch to a NetworkPolicy-capable CNI or use Flannel + Canal.
NetworkPolicy基础¶
Simple Example:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: default
spec:
podSelector: {} # Empty selector = all pods in namespace
policyTypes:
- Ingress
- Egress
This policy blocks ALL ingress and egress traffic for all pods in the namespace (except what you explicitly allow).
NetworkPolicy结构¶
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: example-policy
namespace: default
spec:
podSelector: # Which pods this policy applies to
matchLabels:
role: db
policyTypes: # Types of traffic to control
- Ingress
- Egress
ingress: # Ingress rules (incoming traffic)
- from:
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 3306
egress: # Egress rules (outgoing traffic)
- to:
- podSelector:
matchLabels:
role: monitoring
ports:
- protocol: TCP
port: 9090
字段说明:
podSelector: 选择该策略应用到哪些Pod(基于标签)policyTypes: 指定策略类型(Ingress、Egress或两者)ingress: 入站规则列表(允许哪些流量进入)egress: 出站规则列表(允许哪些流量出去)from: 允许的流量来源to: 允许的流量目的地ports: 允许的端口和协议
Ingress规则¶
Example 1: Allow Traffic from Specific Pods
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: default
spec:
podSelector:
matchLabels:
app: backend # Apply to backend pods
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend # Allow from frontend pods
ports:
- protocol: TCP
port: 8080
Example 2: Allow Traffic from Specific Namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-monitoring-namespace
namespace: default
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring # Allow from monitoring namespace
ports:
- protocol: TCP
port: 9090
Example 3: Allow Traffic from IP Blocks
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-external-traffic
namespace: default
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 192.168.1.0/24 # Allow from this CIDR
except:
- 192.168.1.5/32 # Except this IP
ports:
- protocol: TCP
port: 80
Example 4: Combine Multiple Selectors (OR logic)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-multiple-sources
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend # OR
- namespaceSelector:
matchLabels:
name: monitoring # OR
- ipBlock:
cidr: 10.0.0.0/8 # OR
Example 5: Combine Selectors (AND logic)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-specific-namespace-and-pod
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: production
podSelector:
matchLabels:
app: frontend # Must match BOTH namespace AND pod label
Egress规则¶
Example 1: Allow DNS
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: default
spec:
podSelector:
matchLabels:
app: myapp
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
Example 2: Allow External HTTPS
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-external-https
namespace: default
spec:
podSelector:
matchLabels:
app: myapp
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0 # All external IPs
except:
- 169.254.169.254/32 # Except metadata service
ports:
- protocol: TCP
port: 443
Example 3: Allow Traffic to Database
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-to-database
namespace: default
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: mysql
ports:
- protocol: TCP
port: 3306
常见策略模式¶
Pattern 1: Default Deny All
Block all traffic and explicitly allow what’s needed:
# Deny all ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
spec:
podSelector: {}
policyTypes:
- Ingress
---
# Deny all egress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
spec:
podSelector: {}
policyTypes:
- Egress
Pattern 2: Allow All (Explicitly)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
spec:
podSelector: {}
ingress:
- {}
egress:
- {}
policyTypes:
- Ingress
- Egress
Pattern 3: Three-Tier Application
# Frontend: Allow ingress from LoadBalancer, egress to backend
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: frontend-policy
spec:
podSelector:
matchLabels:
tier: frontend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 0.0.0.0/0 # Public internet
ports:
- protocol: TCP
port: 80
egress:
- to:
- podSelector:
matchLabels:
tier: backend
ports:
- protocol: TCP
port: 8080
- to: # DNS
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: UDP
port: 53
---
# Backend: Allow from frontend, allow to database
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
spec:
podSelector:
matchLabels:
tier: backend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
tier: frontend
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
tier: database
ports:
- protocol: TCP
port: 5432
- to: # DNS
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: UDP
port: 53
---
# Database: Allow only from backend
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: database-policy
spec:
podSelector:
matchLabels:
tier: database
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
tier: backend
ports:
- protocol: TCP
port: 5432
egress:
- to: # DNS
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: UDP
port: 53
Pattern 4: Namespace Isolation
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-from-other-namespaces
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {} # Allow only from same namespace
实际操作¶
Step 1: Deploy Test Application
# Create namespaces
$ kubectl create namespace frontend
$ kubectl create namespace backend
# Deploy frontend
$ kubectl run nginx --image=nginx --labels="app=frontend" -n frontend
# Deploy backend
$ kubectl run httpd --image=httpd --labels="app=backend" -n backend
Step 2: Verify Initial Connectivity (No Policies)
# Get backend pod IP
$ kubectl get pod -n backend -o wide
NAME READY STATUS RESTARTS AGE IP
httpd 1/1 Running 0 1m 10.244.1.5
# Test connectivity from frontend
$ kubectl exec -n frontend nginx -- curl -m 3 10.244.1.5
# Should work (default allow-all)
Step 3: Apply Deny-All Policy to Backend
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: backend
spec:
podSelector: {}
policyTypes:
- Ingress
$ kubectl apply -f deny-all.yaml
# Test connectivity again
$ kubectl exec -n frontend nginx -- curl -m 3 10.244.1.5
# Timeout (connection blocked)
Step 4: Allow Specific Traffic
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-frontend
namespace: backend
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: frontend
podSelector:
matchLabels:
app: frontend
$ kubectl apply -f allow-from-frontend.yaml
# Label the frontend namespace
$ kubectl label namespace frontend name=frontend
# Test connectivity
$ kubectl exec -n frontend nginx -- curl -m 3 10.244.1.5
# Works again!
查看和调试¶
# List all NetworkPolicies
$ kubectl get networkpolicy
$ kubectl get netpol # Short form
# List in all namespaces
$ kubectl get netpol -A
# Describe NetworkPolicy
$ kubectl describe netpol <policy-name>
# Get YAML
$ kubectl get netpol <policy-name> -o yaml
# Delete NetworkPolicy
$ kubectl delete netpol <policy-name>
Testing Connectivity:
# Method 1: curl from one pod to another
$ kubectl exec <source-pod> -- curl -m 5 <target-pod-ip>:<port>
# Method 2: Use netcat
$ kubectl exec <source-pod> -- nc -zv <target-pod-ip> <port>
# Method 3: Deploy debug pod
$ kubectl run debug --rm -it --image=nicolaka/netshoot -- bash
# Then test from inside
故障排查¶
Issue: Policy Not Working
# 1. Check if CNI supports NetworkPolicy
$ kubectl get pods -n kube-system | grep -E "calico|cilium|weave"
# 2. Verify pod labels match policy selector
$ kubectl get pods --show-labels
$ kubectl get netpol <policy> -o yaml | grep -A 5 podSelector
# 3. Check if policy is in correct namespace
$ kubectl get netpol -A
# 4. Test with a simple policy first
# Start with deny-all, then gradually add allow rules
Issue: DNS Not Working
When using egress policies, you must explicitly allow DNS:
egress:
- to:
- namespaceSelector:
matchLabels:
name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
Issue: Can’t Access External Services
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 169.254.169.254/32 # AWS metadata
ports:
- protocol: TCP
port: 443
- protocol: TCP
port: 80
Debugging Tips:
Start with deny-all policy
Add allow rules incrementally
Use
kubectl execto test connectivityCheck pod and namespace labels carefully
Remember: policies are additive (multiple policies combine with OR logic)
最佳实践¶
Default Deny, Explicit Allow
Start with deny-all and explicitly allow required traffic:
kubectl apply -f default-deny-all.yaml # Then add specific allow policies
Use Namespace Labels
Label namespaces for easier policy management:
kubectl label namespace production env=prod kubectl label namespace development env=dev
Document Your Policies
Add clear descriptions in metadata:
metadata: name: allow-frontend-to-backend annotations: description: "Allows frontend pods to connect to backend on port 8080"
Test Policies in Non-Prod First
Always test NetworkPolicies in development before applying to production.
Include DNS Egress
If using egress policies, always allow DNS:
egress: - to: - namespaceSelector: {} podSelector: matchLabels: k8s-app: kube-dns ports: - protocol: UDP port: 53
Use Multiple Policies
Create separate policies for different concerns rather than one complex policy.
Monitor Policy Effects
Use metrics and logging to monitor policy impacts:
# Check dropped packets (depends on CNI) # For Calico: kubectl exec -n kube-system <calico-pod> -- calico-node -status
Version Control Your Policies
Store NetworkPolicies in Git like other Kubernetes resources.
高级主题¶
Cilium Network Policies
Cilium provides extended NetworkPolicy features:
Layer 7 (HTTP, gRPC) filtering
DNS-based policies
Cluster mesh for multi-cluster
Calico Network Policies
Calico has its own GlobalNetworkPolicy resource:
Applies across namespaces
More powerful selectors
Host endpoint protection
Policy Validation
Use tools to validate policies before applying:
Network Policy Viewer: https://github.com/runoncloud/network-policy-viewer
Cilium Editor: https://editor.cilium.io/
实用工具¶
Network Policy Recipes:
https://github.com/ahmetb/kubernetes-network-policy-recipes
Collection of common NetworkPolicy patterns.
Policy Simulation:
Test policies before applying:
# Use kubectl dry-run
kubectl apply -f policy.yaml --dry-run=client
Visualization:
Cilium Hubble: Visual network flows
Weave Scope: Topology and network visualization
参考资料¶
Network Policies: https://kubernetes.io/docs/concepts/services-networking/network-policies/
Network Policy Recipes: https://github.com/ahmetb/kubernetes-network-policy-recipes
Calico Network Policy: https://docs.tigera.io/calico/latest/network-policy/
Cilium Network Policy: https://docs.cilium.io/en/stable/policy/