Kubernetes 1.9.6环境下Egress网络策略未生效问题排查
我来帮你拆解下这个问题——在K8s 1.9.x这类早期版本里,你遇到的「配置了默认拒绝Egress却还能ping通」的情况,通常和CNI插件的支持情况、NetworkPolicy对ICMP的处理逻辑有关,下面一步步给出解决方案:
1. 先确认你的CNI插件是否支持NetworkPolicy
Kubernetes本身并不直接实现NetworkPolicy的流量管控,这部分功能完全依赖集群使用的CNI插件(比如Calico、Weave、Cilium)。如果你的集群用的是默认Docker Bridge,或者像Flannel这种默认不支持NetworkPolicy的插件,那你写的default-deny规则根本不会生效。
怎么验证?
查看kube-system命名空间下的网络插件Pod:
kubectl get pods -n kube-system如果是Calico,你会看到
calico-node开头的Pod;如果是Weave则是weave-net。如果没有这类Pod,或者用的是纯Flannel,那就是CNI不支持导致的。解决办法:切换到支持NetworkPolicy的CNI插件,比如适配K8s 1.9的Calico 3.0系列,或者给Flannel搭配Canal来添加NetworkPolicy支持。
2. 检查NetworkPolicy对ICMP流量的管控逻辑
Ping依赖的是ICMP协议,而部分CNI插件在早期版本里,对ICMP流量的处理和TCP/UDP不同:
- 有些插件默认不把ICMP纳入NetworkPolicy的管控范围,因为K8s节点健康检查可能依赖ICMP,所以即使配置了拒绝所有Egress,ICMP流量依然能正常通行。
- 有些插件需要显式配置规则才能管控ICMP。
验证方法:不要只测ping,试试TCP连接,比如:
curl www.google.com
如果TCP连接被拒绝,但ping还能通,那就是ICMP的管控问题;如果TCP也能正常访问,那说明NetworkPolicy完全没生效(回到第一步检查CNI)。
针对ICMP的解决办法:
如果你的CNI插件支持管控ICMP,可以修改NetworkPolicy,显式添加拒绝ICMP的规则(或者确认默认规则是否覆盖ICMP)。比如Calico的话,可以这样配置:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny namespace: pps-api-gateway-ci spec: podSelector: {} policyTypes: - Egress egress: # 显式拒绝所有ICMP流量,同时拒绝其他所有流量(因为无允许规则) - to: - ipBlock: cidr: 0.0.0.0/0 ports: - protocol: ICMP
不过更核心的是,要确保插件版本支持ICMP过滤,部分早期插件可能需要升级才能实现这个功能。
3. 验证NetworkPolicy的生效范围和配置正确性
- 确认你测试的Pod确实在
pps-api-gateway-ci命名空间下:
进入Pod时也要指定命名空间:kubectl get pods -n pps-api-gateway-cikubectl exec -n pps-api-gateway-ci -it <你的Pod名称> -- /bin/bash - 检查NetworkPolicy的应用状态:
确保kubectl get networkpolicy -n pps-api-gateway-cidefault-deny的状态是Active。
4. 排查CNI插件的日志和控制器状态
如果前面的步骤都没问题,查看CNI插件的日志,看看有没有关于NetworkPolicy的错误:
比如Calico的话,查看calico-node的日志:
kubectl logs -n kube-system <calico-node-Pod名称>
看看是否有加载NetworkPolicy失败的报错,或者规则未生效的提示。
另外,确认Kubernetes的NetworkPolicy控制器是否正常运行(部分插件自带控制器):
kubectl get pods -n kube-system | grep policy
总结一下,最常见的原因就是CNI插件不支持NetworkPolicy,或者插件版本和K8s 1.9.6不兼容,导致规则没生效。先从CNI插件这块入手排查,应该能解决问题。
内容的提问来源于stack exchange,提问作者Priyanka Gandhi

