Docker容器TCP连接报Connection closed by foreign host错误
Ubuntu 20.04 环境Docker端口映射TCP连接异常排查
已确认的故障前提
- 运行环境为Ubuntu 20.04,故障无征兆突发,出现前未执行系统配置修改、新软件安装操作
- 镜像兼容性验证:自定义Web服务镜像、官方PostgreSQL镜像复现故障表现完全一致,排除自定义镜像本身缺陷
- 端口配置验证:容器内服务监听
0.0.0.0地址,更换容器服务监听端口、更换宿主机映射端口后故障依旧,排除单端口配置错误、端口占用问题 - 连通性验证:容器内部直接访问服务端口正常,容器启动添加
--net=host参数使用主机网络模式时访问完全正常,仅默认bridge网络模式下端口映射规则失效 - 故障表现:宿主机访问映射端口时,TCP连接可短暂建立,挂起一段时间后自动断开,报错
Connection closed by foreign host
故障复现用容器启动命令:
宿主机telnet测试输出:docker run --rm --name my-web-container -p 8080:8080 my-web-image# telnet localhost 8080 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Connection closed by foreign host.
排查与修复步骤(按优先级从高到低执行)
1. 修复iptables/nftables兼容问题
Ubuntu 20.04默认使用nftables作为防火墙后端,部分版本Docker与nftables适配存在已知bug,会导致端口映射转发规则异常:
- 首先查看Docker生成的nat表转发规则是否正常:
正常状态下可看到对应映射端口的DNAT规则,目标地址为容器在docker0网段的分配IP。sudo iptables -t nat -L DOCKER -n -v - 若规则缺失,先重启Docker服务触发规则自动重建:
sudo systemctl restart docker - 重启后规则仍异常的,切换iptables为legacy后端解决兼容问题:
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy sudo systemctl restart docker
2. 校验docker0网桥与系统转发参数
- 检查docker0网桥状态,确认其IP属于Docker默认172.17.0.0/16网段,无局域网IP冲突:
ip addr show docker0 - 检查系统IPv4核心转发开关是否开启:
正常返回值为sysctl net.ipv4.ip_forwardnet.ipv4.ip_forward = 1,若返回值为0,执行sysctl -w net.ipv4.ip_forward=1临时开启,永久开启需在/etc/sysctl.conf中添加net.ipv4.ip_forward=1配置后执行sysctl -p生效。 - 检查FORWARD链规则是否拦截docker0网桥流量:
确认DOCKER、DOCKER-USER链默认策略不是DROP,若存在自定义拦截规则,可临时清空iptables规则后重启Docker验证:sudo iptables -L FORWARD -n -v
注意:清空iptables规则前请确认无需要保留的业务自定义规则,避免影响其他服务正常运行sudo iptables -F sudo iptables -t nat -F sudo systemctl restart docker
3. 重置Docker本地网络配置
上述操作无效时,可重建docker0网桥恢复默认网络配置,操作前先停止所有运行中的容器:
sudo systemctl stop docker sudo ip link set docker0 down # 若brctl命令不存在,先执行apt install -y bridge-utils安装 sudo brctl delbr docker0 sudo systemctl start docker
服务启动后Docker会自动重建docker0网桥和配套转发规则,重新创建容器验证端口映射是否恢复。
4. 非主机网络模式的替代方案
若暂未定位根因,无需长期依赖--net=host模式,可创建自定义bridge网络替代默认bridge使用,自定义bridge的转发规则优先级高于默认bridge,可规避多数默认网络的规则异常问题:
docker network create custom-bridge docker run --rm --name my-web-container --network custom-bridge -p 8080:8080 my-web-image
内容的提问来源于stack exchange,提问作者Ilya Sazonov
相关产品推荐
相关产品推荐

