大多数情况下,这是宿主机的 IP 转发未开启或防火墙规则拦截了 Docker 的 NAT 流量,优先检查 sysctl 配置和 iptables 规则。
先说结论:问题通常出在宿主机的网络转发配置或防火墙策略上,而非 Docker 本身故障。
- 先确认:检查 Docker 网络驱动是否为 bridge 且子网正常
- 先处理:开启 net.ipv4.ip_forward 并放行 iptables NAT 规则
- 再验证:在容器内 ping 外网 IP 确认连通性
命令速用版
# 检查 Docker 网络模式
docker network inspect bridge
# 检查 IP 转发状态
sysctl net.ipv4.ip_forward
# 查看 NAT 表规则(关键)
iptables -t nat -L -n
# 测试容器网络
docker run `--rm` alpine ping -c 4 8.8.8.8为什么会这样
Docker 默认使用 iptables 管理网络地址转换(NAT)。容器发出的数据包需要经过宿主机网卡转发到外部网络。如果宿主机内核禁止 IP 转发,或者防火墙软件(如 ufw、firewalld)重置了 iptables 规则,容器就无法通过宿主机的网卡访问外网。此外,部分海外 VPS 服务商会在底层限制特定协议或端口,也可能导致桥接模式异常。
分步处理
1. 确认 Docker 网络驱动模式
首先确认容器是否运行在 bridge 网络下,且子网配置正常:
docker network inspect bridge检查输出中的 Driver 是否为 bridge,以及 Subnet 是否已分配。如果驱动异常,可能需要重置 Docker 网络。
2. 检查并开启 IP 转发
执行 sysctl net.ipv4.ip_forward。如果返回 net.ipv4.ip_forward = 0,说明转发未开启。
临时开启:sysctl -w net.ipv4.ip_forward=1
永久开启:编辑 /etc/sysctl.conf,确保包含 net.ipv4.ip_forward=1,然后执行 sysctl -p 生效。
3. 检查防火墙与 NAT 规则
查看 NAT 表规则,确认是否存在 MASQUERADE 规则:
iptables -t nat -L -n正常输出应包含 MASQUERADE 目标规则。如果缺失,可能是防火墙软件重置了规则。
关于 UFW 的安全配置:
不建议直接执行 ufw disable,这会暴露服务器端口。建议修改转发策略:
编辑 /etc/default/ufw,将 DEFAULT_FORWARD_POLICY 改为 ACCEPT:
DEFAULT_FORWARD_POLICY="ACCEPT"然后重启 ufw:ufw reload。如果必须临时关闭测试,测试完成后请立即启用。
4. 检查 Docker 配置(可选)
部分海外机房 MTU 值较小,可能导致大包丢弃。创建或编辑 /etc/docker/daemon.json:
{
"mtu": 1450,
"ipv6": false
}修改后重启 Docker:systemctl restart docker。
怎么验证是否生效
运行一个临时容器测试外网连通性:
docker run `--rm` alpine ping -c 4 8.8.8.8如果能收到回复,说明网络已通。还可以测试 DNS 解析:
docker run `--rm` alpine nslookup google.com如果 ping 通 IP 但无法解析域名,检查容器内的 /etc/resolv.conf 配置。
常见坑
1. 盲目关闭 Docker 的 iptables 管理
不要在 daemon.json 中随意设置 "iptables": false,这会导致 Docker 无法自动配置 NAT 规则,除非你有能力手动编写所有规则。
2. 服务商安全组限制
部分 VPS 提供商的控制面板有独立的安全组设置,确保出站流量(Outbound)未被限制。
3. 防火墙配置风险
调整 ufw 或 firewalld 后,务必确认 SSH 端口仍允许访问,避免把自己锁在门外。