Appearance
NetworkPolicy
NetworkPolicy 用来限制 Pod 的入站和出站流量。默认很多集群里 Pod 之间是互通的,NetworkPolicy 可以把访问范围收窄到特定 namespace、Pod label、端口和协议。
前提——CNI 必须支持
NetworkPolicy 是否生效取决于 CNI。Calico、Cilium 完全支持;Flannel 等简单 CNI 不支持或支持有限。
bash
kubectl -n kube-system get pods -o wide | grep -E 'calico|cilium|flannel'CNI 不支持 NetworkPolicy 时,创建策略对象也不会真的拦截流量。这种"策略创建了但实际没生效"的情况很容易被误判为策略已生效。
策略作用对象
NetworkPolicy 先用 podSelector 选择被保护的 Pod:
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-policy
namespace: demo
spec:
podSelector:
matchLabels:
app: api # 策略作用到 app=api 的 Pod
policyTypes:
- IngresspodSelector: {} 表示当前 namespace 所有 Pod。
默认拒绝入站
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: demo
spec:
podSelector: {}
policyTypes:
- Ingress创建后,demo namespace 里所有 Pod 的入站流量被拒绝,除非有明确的 allow 规则放行。
白名单规则
允许带 role=frontend 的 Pod 访问 app=api 的 8080:
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-api
namespace: demo
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 8080这里的 from.podSelector 只匹配同 namespace 的 Pod。跨 namespace 需要加 namespaceSelector:
yaml
ingress:
- from:
- namespaceSelector:
matchLabels:
team: platform
ports:
- protocol: TCP
port: 8080给 namespace 打标签:
bash
kubectl label namespace platform team=platform出站限制——别忘了 DNS
限制出站时要特别注意 DNS。很多服务配置出站策略后第一个问题是 DNS 被拦,导致所有外部依赖看起来都断了:
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-egress
namespace: demo
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53排查
bash
kubectl -n demo get networkpolicy
kubectl -n demo describe networkpolicy allow-frontend-to-api临时 Pod 测试:
bash
kubectl -n demo run test-client --rm -it --image=curlimages/curl --restart=Never -- sh
curl -v http://api:8080/healthz| 现象 | 方向 |
|---|---|
| 策略创建但不生效 | CNI 不支持策略 |
| 同 namespace 访问失败 | podSelector、端口、Pod label |
| 跨 namespace 失败 | namespace label、namespaceSelector |
| 域名解析失败 | Egress 策略没放 DNS |
| Service 访问超时 | 策略拦的是 Pod 流量,先直连 Pod IP 对比 |
NetworkPolicy 是白名单思路。实施时先从非核心 namespace 开始,观察日志和连接关系,再逐步收紧——一次性全集群默认拒绝,容易把监控、日志采集、CoreDNS 和基础设施也一起拦掉。