在 Kubernetes 中配置 NetworkPolicy 是限制 Pod 间通信的标准做法,但前提是集群使用的 CNI 插件必须支持该功能,否则策略不会生效。
先说结论:NetworkPolicy 依赖 CNI 插件支持,配置前需先确认网络插件兼容性,建议从默认拒绝策略开始逐步放通。
- 适合:需要实现微服务间访问控制、隔离 Namespace 或限制外部访问的场景
- 先准备:确认 CNI 插件(如 Calico、Cilium)支持 NetworkPolicy 资源
- 验收:通过临时 Pod 测试连通性,确保策略按预期拦截或放行流量
工作原理与前置检查
Kubernetes 默认的网络行为是“允许所有”,即任何 Pod 都可以互相通信,也可以访问外部网络。NetworkPolicy 的作用机制是“白名单”:一旦某个 Pod 被至少一个 NetworkPolicy 选中,它就会进入默认拒绝状态,只有通过规则明确允许的流量才能通过。
重要提示:NetworkPolicy 只是一个 API 资源,实际的网络隔离效果由集群的 CNI(容器网络接口)插件实现。如果插件不支持(例如默认配置的 Flannel),即使创建了策略,流量也不会被拦截。
1. 确认 CNI 插件支持
查看集群使用的网络插件,常见支持 NetworkPolicy 的插件包括 Calico、Cilium、Weave Net 等。如果是云厂商托管集群,通常默认支持,但需查阅对应文档确认。可使用以下命令查看节点网络信息辅助判断:
kubectl get nodes -o wide核心配置示例
以下是一个默认拒绝所有入站流量的策略示例,应用后该 Namespace 下的 Pod 将无法被外部访问,除非另有允许策略。
警告:请勿直接在生产环境 Namespace 应用默认拒绝策略,除非已确认业务流量规则并已配置放行策略,否则会导致业务中断。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress若需允许特定 Pod 访问,可补充如下允许策略:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-specific
namespace: default
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend应用命令:
kubectl apply -f policy.yaml配置实施步骤
1. 编写默认拒绝策略
为了安全起见,建议先在测试 Namespace 应用默认拒绝策略。注意 podSelector: {} 表示选中该 Namespace 下所有 Pod。
2. 编写业务允许策略
根据业务调用链,编写允许特定标签 Pod 访问的策略。可以使用 podSelector 限制源 Pod,也可以使用 namespaceSelector 允许跨 Namespace 通信。
3. 应用策略
使用 kubectl apply 提交配置。建议先在非生产环境验证,确认无误后再推广。
验证与测试
创建一个临时 Pod 尝试访问目标服务,观察连接是否被阻断。
查看当前策略:
在应用前后,可查看当前 Namespace 下的策略列表:
kubectl get networkpolicy -n <namespace>测试被拒绝的访问:
kubectl run -it `--rm` `--image`=busybox `--restart`=Never test-pod -- wget `--timeout`=2 http://<target-service-ip>如果策略生效,连接会超时或显示 Connection refused。如果仍能通,说明策略未生效(可能是 CNI 不支持或标签选择器写错)。
测试被允许的访问:
给测试 Pod 打上允许策略中指定的标签,再次运行上述命令,应能正常返回 HTTP 响应。
策略管理:查看与删除
查看策略详情:
kubectl describe networkpolicy <policy-name> -n <namespace>删除策略:
若策略配置错误导致网络中断,需立即删除策略恢复通信:
kubectl delete networkpolicy <policy-name> -n <namespace>若需临时禁用所有策略,可删除该 Namespace 下所有 NetworkPolicy 资源。
常见问题与风险
1. CNI 插件不支持
这是最常见的问题。例如使用 Flannel 插件时,默认不开启 NetworkPolicy 支持,需要更换插件或启用特定后端。
2. 命名空间隔离
NetworkPolicy 是 Namespace scoped 的资源。如果在 default 命名空间创建策略,不会影响其他命名空间的 Pod。跨命名空间访问需显式配置
namespaceSelector。3. 标签选择器错误
策略中的
podSelector必须与 Pod 实际标签完全匹配。如果标签写错,策略可能选中了错误的 Pod,导致意外断网。4. 出站流量未限制
默认策略通常只限制入站(Ingress)。如果需要限制 Pod 访问外部网络,需显式声明
policyTypes: ["Egress"]并配置相应规则。参考来源
- Kubernetes Documentation, "Network Policies", https://kubernetes.io/docs/concepts/services-networking/network-policies/