为何Nginx Ingress Controller会抢占宿主机Apache的流量?
核心现象
裸金属Kubernetes集群(1控制节点+2工作节点)中,工作节点kubenode-2宿主机的Apache HTTP Server监听80/443端口,但访问时流量被DaemonSet部署的Nginx Ingress Controller接管,返回404页面;netstat显示仅Apache监听80/443,Ingress Service为NodePort类型(使用31902/31903端口),且集群无任何Ingress资源。
可能原因及排查步骤
1. Nginx Ingress Pod启用了hostNetwork或hostPort
Ingress Controller Pod可能通过hostNetwork: true直接使用宿主机网络命名空间,或通过hostPort将容器内端口映射到宿主机80/443。即使netstat未显示,也可能是进程监听IP非0.0.0.0或工具显示限制。
排查命令:
# 查看Pod的网络配置和端口映射 kubectl describe pod bkk-ingress-rxjw4 -n nginx
重点检查:
Host Network字段是否为truePorts列表中是否存在HostPort: 80或HostPort: 443
2. Kubernetes iptables规则劫持宿主机流量
Kubernetes的kube-proxy或Ingress Controller会自动配置iptables规则,若规则错误将宿主机80/443流量转发到Nginx Pod的端口,会导致流量绕过Apache直接到达Nginx。由于iptables的PREROUTING链优先于本地进程接收流量,Apache无法获取请求,Nginx因无匹配Ingress规则返回404。
排查命令:
# 检查PREROUTING链中80/443端口的转发规则 iptables -t nat -L PREROUTING -n -v | grep -E ":80|:443" # 检查Kubernetes服务相关链 iptables -t nat -L KUBE-SERVICES -n -v | grep -E "(80|443)" # 查找Ingress相关的iptables链 iptables -t nat -L | grep -i ingress
若输出中存在将目标80/443流量转发到Nginx Pod IP:端口的规则,即可确认是此原因。
3. 工具显示限制
netstat可能存在权限或进程名称显示问题,改用ss命令查看更完整的监听信息:
ss -tulpn | grep -E ":80|:443"
解决方法
针对hostNetwork/hostPort问题
若Pod启用了hostNetwork或错误的hostPort,修改Ingress Controller配置:
- 若通过Helm安装,调整values.yaml参数:
controller: hostNetwork: false hostPort: http: 801 # 与Service targetPort一致 https: 4431 - 重新部署Ingress Controller:
helm upgrade bkk nginx/nginx-ingress -n nginx -f values.yaml
针对iptables规则劫持问题
- 检查Ingress Controller配置,关闭自动转发宿主机80/443端口的参数(不同版本参数可能不同,参考对应文档)。
- 手动清理错误的iptables规则(操作前备份规则:
iptables-save > iptables-backup.txt):# 删除相关转发规则(需根据排查结果调整具体链和规则编号) iptables -t nat -D PREROUTING [规则编号]
内容的提问来源于stack exchange,提问作者bkk

