Docker容器中Nginx反向代理报113错误的排查求助
Docker容器内Nginx反向代理遇113: No route to host(防火墙开启时)问题分析与解决
先直接给你结论:这个问题不是Docker本身导致的,Docker也不会忽略宿主机防火墙规则,核心是你的防火墙规则没有覆盖Docker容器所在的网络网段,导致容器发起的反向代理请求被拦截了。
问题原因拆解
从你的测试场景就能看出关键:
- 开启防火墙只暴露80端口时,宿主机Nginx正常是因为它的请求属于本地流量,firewalld默认允许本地进程的网络请求;但容器内的Nginx处于Docker桥接网络(你的是
172.18.x.x网段),它向上游172.18.0.249:88发起的请求属于跨网段的外部流量,而你的防火墙只开放了宿主机的80端口,没授权Docker网段访问上游的88端口,所以被拦截,报No route to host。 - 关闭防火墙后所有流量不受限制,自然都正常;开启防火墙只跑容器内的Nginx应用(不反向代理)时,流量是从外部进入容器的80端口,你已经暴露了这个端口,所以没问题——但反向代理是容器主动向外发请求,这部分流量没被防火墙允许。
具体解决方案
针对你的CentOS 7.4 + firewalld环境,按以下步骤修复:
1. 允许Docker容器网段访问上游服务端口
假设你的Docker容器所在网段是172.18.0.0/16,上游地址是172.18.0.249:88,执行以下命令添加精准规则:
# 允许172.18网段访问指定上游的88端口 firewall-cmd --add-rich-rule='rule family="ipv4" source address="172.18.0.0/16" destination address="172.18.0.249" port port="88" protocol="tcp" accept' --permanent # 重载防火墙使规则生效 firewall-cmd --reload
如果上游服务也在Docker容器里,或者需要整个Docker网段的流量正常通行,也可以直接把Docker网段加入trusted zone:
firewall-cmd --add-source=172.18.0.0/16 --zone=trusted --permanent firewall-cmd --reload
2. 确保Docker的NAT规则被firewalld允许
Docker默认会配置iptables处理容器网络,但firewalld可能干扰这部分规则,所以需要开启masquerade规则,让容器流量能通过宿主机正常NAT:
firewall-cmd --zone=public --add-masquerade --permanent firewall-cmd --reload
3. 验证修复效果
执行firewall-cmd --list-all查看已添加的规则,确认Docker网段的相关规则存在;然后重启容器内的Nginx,测试反向代理是否正常工作。
补充说明
别误以为Docker会绕过防火墙——Docker的网络流量依然要经过宿主机的防火墙规则,只是它默认会添加一些iptables规则处理容器的进出流量,但如果你的firewalld规则更严格(比如只开放指定端口),就需要手动补充容器网段的授权规则。
内容的提问来源于stack exchange,提问作者xuncanzhe
相关产品推荐
相关产品推荐

