




















https://chat.deepseek.com/share/hl3g8f3j9eqi57rb5b
imes-ui(前端 Nginx)imes-server(后端 Spring Boot)imes_mes-network。captchaImage 失败。curl http://imes-server:8080/captchaImage 无响应或超时。curl http://localhost:8080/captchaImage 正常返回。ping 通,但端口访问不通。确认后端服务正常
在后端容器内执行 curl http://localhost:8080/captchaImage,成功返回图片数据 → 后端应用已启动,监听 8080 端口。
确认容器间 DNS 解析和 IP 连通性
在前端容器内执行 nslookup imes-server,返回正确 IP(如 172.23.0.3);ping imes-server 成功 → DNS 正常,网络层可达。
确认后端监听地址
使用 cat /proc/net/tcp | grep ':1F90' 或临时安装 net-tools,确认后端监听在 0.0.0.0:8080(启动参数 --server.address=0.0.0.0 已保证)。排除后端绑定 127.0.0.1 的问题。
最终定位到宿主机 iptables 规则
检查宿主机 iptables 的 DOCKER-USER 链,发现缺少允许容器间访问所需端口的规则。由于宿主机可能被手动添加了限制性策略,导致来自 172.23.0.0/16 网段到目标端口(如 8080)的 TCP 请求被丢弃。
验证:临时添加允许规则后,前端立即可以访问后端。
宿主机 iptables 的 DOCKER-USER 链中缺少允许 172.23.0.0/16 网段访问后端所需端口(8080 等)的规则,导致容器间 TCP 通信被阻断。
ping 通?因为 ICMP 协议未被过滤。curl localhost 通?因为流量不经过宿主机 iptables。在宿主机上执行以下命令,放行 172.23.0.0/16 网段到所有 MES 系统需要使用的端口的 TCP 流量。
sudo iptables -I DOCKER-USER 1 -s 172.23.0.0/16 -p tcp -m multiport --dports 3306,6379,1883,8123,9000,9009,8088,8080,9092,80,39001,9090 -j ACCEPT
参数说明:
-I DOCKER-USER 1:插入到 DOCKER-USER 链的第一条,优先级最高。-s 172.23.0.0/16:源地址为 Docker 自定义网络的子网。-p tcp:仅针对 TCP 协议。-m multiport --dports:指定多个目标端口。-j ACCEPT:接受这些流量。如果只需要解决前端访问后端的问题,可以只添加 8080 端口:
sudo iptables -I DOCKER-USER 1 -s 172.23.0.0/16 -p tcp --dport 8080 -j ACCEPT
防止宿主机重启后规则丢失。
方法一(使用 netfilter-persistent,适用于 Debian/Ubuntu):
sudo netfilter-persistent save
方法二(使用 iptables-save,适用于 CentOS/RHEL):
sudo iptables-save > /etc/sysconfig/iptables
# 或
sudo service iptables save
方法三(安装 iptables-persistent):
sudo apt-get install iptables-persistent
sudo netfilter-persistent save
# 查看 DOCKER-USER 链规则
sudo iptables -L DOCKER-USER -n -v
应能看到第一条规则为 ACCEPT,源地址为 172.23.0.0/16。
从前端容器执行:
docker exec imes-ui curl -s http://imes-server:8080/captchaImage | head -c 100
应返回图片数据的二进制内容或 HTTP 响应头(如 JFIF 等)。
从宿主机测试前端暴露的端口:
curl -I http://localhost:38080/captchaImage
应返回 HTTP/1.1 200 OK。
执行以下所有验证,确保问题彻底解决:
| 验证项 | 命令 | 预期结果 |
|---|---|---|
| 后端本地健康 | docker exec imes-server curl -s http://localhost:8080/captchaImage -o /dev/null -w "%{http_code}" |
200 |
| 前端直连后端 | docker exec imes-ui curl -s http://imes-server:8080/captchaImage -o /dev/null -w "%{http_code}" |
200 |
| 宿主机访问前端 | curl -s http://localhost:38080/captchaImage -o /dev/null -w "%{http_code}" |
200 |
| 外部访问(如需要) | curl -s http://10.66.11.135:38080/captchaImage -o /dev/null -w "%{http_code}" |
200 |
iptables 规则顺序很重要
DOCKER-USER 链中如果有 REJECT/DROP 规则在前面,会导致允许规则不生效。使用 -I 插入到第一条可确保优先匹配。
不要轻易清空 DOCKER-USER 链
该链用于 Docker 自定义规则,清空可能破坏其他容器的网络。建议只添加允许规则,不删除现有规则。
容器间通信无需 -p 端口映射
-p 只用于宿主机访问容器。但 iptables 规则依然会影响容器间通信,因为 Docker 网络依赖 iptables 实现隔离。
检查是否已有其他防火墙工具冲突
如 firewalld、ufw 可能覆盖 iptables 规则。若使用这些工具,需通过它们开放相应端口或放行 Docker 网段。
持久化方法因系统而异
netfilter-persistent。iptables-services 或 firewalld 的 rich rule。如果问题依旧,检查 conntrack
有时已有连接状态被记录为无效,可以尝试:
sudo conntrack -D -s 172.23.0.0/16
--link 已弃用,推荐自定义网络)。本次故障的根本原因是宿主机 iptables 的 DOCKER-USER 链缺少允许容器间通信的规则,导致前端容器无法访问后端容器的 8080 端口。通过添加一条源地址为 Docker 网络子网、目标端口为所需端口的 ACCEPT 规则,并持久化保存,问题得以解决。
核心命令回顾:
sudo iptables -I DOCKER-USER 1 -s 172.23.0.0/16 -p tcp -m multiport --dports 8080 -j ACCEPT
sudo netfilter-persistent save
以上操作总结可直接作为运维手册参考,确保类似问题能够快速定位与解决。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。