EKS中禁用指定容器公网访问的NetworkPolicy失效求助
我来帮你一步步排查这个NetworkPolicy不生效的问题,先把你提供的配置贴出来方便参考:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: foo-deny-external-egress spec: podSelector: matchLabels: app: foo policyTypes: - Egress egress: - ports: - port: 53 protocol: UDP - port: 53 protocol: TCP to: - namespaceSelector: {}
确认Pod标签匹配
首先检查你要限制的Pod是否带有app: foo标签,执行命令:kubectl get pods -n <你的目标命名空间> --show-labels如果目标Pod没有这个标签,NetworkPolicy根本不会作用在它身上,这是最常见的问题之一。
确认NetworkPolicy部署的命名空间正确
你要限制的是指定Namespace内的容器,那这个NetworkPolicy必须部署在对应的Namespace下。执行命令检查:kubectl get networkpolicy -n <你的目标命名空间>如果这个Policy是部署在其他Namespace(比如default),那它只会作用在那个Namespace里带
app:foo标签的Pod,不会影响你目标Namespace的Pod。检查CNI插件是否支持NetworkPolicy
这是EKS环境里很容易踩的坑:Amazon VPC CNI默认不支持NetworkPolicy!如果你用的是默认CNI,那不管怎么配置NetworkPolicy都不会生效。你需要确认集群使用的是支持NetworkPolicy的CNI,比如Calico、Cilium或者Weave Net。可以通过查看节点上的CNI配置或者执行以下命令确认:kubectl get daemonsets -n kube-system | grep -E "(calico|cilium|weave)"如果没有相关的DaemonSet,说明你用的是默认VPC CNI,需要先安装支持NetworkPolicy的CNI插件。
检查是否存在其他允许Egress的NetworkPolicy
NetworkPolicy的规则是累加生效的:如果有多个NetworkPolicy作用在同一个Pod上,只要其中一个允许了某类流量,那这个流量就会被放行。执行命令查看目标Namespace下所有的NetworkPolicy:kubectl get networkpolicy -n <你的目标命名空间> -o yaml看看有没有其他Policy包含允许外部Egress的规则,比如允许所有端口到0.0.0.0/0的规则。
验证Pod是否使用HostNetwork
如果你的Pod配置了hostNetwork: true,那它会直接使用节点的网络栈,不受NetworkPolicy的限制。查看Pod的配置:kubectl get pod <你的Pod名称> -n <目标命名空间> -o yaml | grep hostNetwork如果输出是
hostNetwork: true,那这个Pod的流量不会被NetworkPolicy拦截。跳过域名解析,直接测试公网IP访问
你的Policy只允许了DNS(53端口)的流量,所以先测试直接访问公网IP,比如:kubectl exec -n <目标命名空间> <你的Pod名称> -- wget -qO- 8.8.8.8如果这个命令能成功,说明你的Policy完全没生效;如果失败但访问
google.com成功,那可能是Pod使用了集群外的DNS服务器,DNS请求被允许后,实际的HTTP流量通过其他规则被放行(比如其他NetworkPolicy)。查看CNI插件的日志,确认Policy是否加载
如果你用的是Calico这类CNI,可以查看节点上的Calico日志:kubectl logs -n kube-system -l k8s-app=calico-node | grep -i policy看看有没有加载你创建的
foo-deny-external-egressPolicy的相关日志,是否有报错信息。
内容的提问来源于stack exchange,提问作者Abdennour TOUMI

