CentOS 下 Docker 网络配置错误排查与修复
一、快速自检清单
- 查看网络与服务状态:
- 列出网络:docker network ls
- 查看详情:docker network inspect <网络名>
- 服务状态:systemctl status docker;必要时查看日志:journalctl -u docker.service
- 检查宿主机网络与转发:
- 接口与网桥:ip a、brctl show(若提示无命令,安装:yum install -y bridge-utils)
- 路由:ip route
- IPv4 转发:cat /proc/sys/net/ipv4/ip_forward(为 0 则需开启)
- 检查内核与防火墙:
- 桥接相关内核参数:sysctl net.bridge.bridge-nf-call-iptables、net.bridge.bridge-nf-call-ip6tables
- firewalld:systemctl status firewalld;容器访问外部需开启:firewall-cmd --permanent --add-masquerade && firewall-cmd --reload
- 容器内部连通性:
- 进入容器:docker exec -it <容器名> sh
- 查看地址:ip a;测试外网:ping 8.8.8.8;测试 DNS:nslookup www.example.com
- 抓包定位:tcpdump -i docker0
以上命令覆盖网络、路由、转发、防火墙与容器侧的基本验证,可快速定位大多数问题。
二、常见症状与对应修复
- 宿主机访问不到容器端口
- 确认容器端口已发布:如 docker run -p 8080:80 nginx;宿主机访问 http://127.0.0.1:8080。
- 检查 firewalld 是否放行 masquerade(SNAT):firewall-cmd --permanent --add-masquerade && firewall-cmd --reload。
- 排查端口占用:ss -ltnp | grep 8080 或 lsof -i :8080,释放或更换端口。
- 若仅需本机访问且网络复杂,可临时使用 –net=host(注意端口与宿主机冲突风险)。
- 容器无法访问外部网络
- 开启转发:echo 1 > /proc/sys/net/ipv4/ip_forward;持久化到 /etc/sysctl.conf:net.ipv4.ip_forward=1。
- 启用桥接到 iptables 的钩子:net.bridge.bridge-nf-call-iptables=1、net.bridge.bridge-nf-call-ip6tables=1;若提示 proc 节点不存在,先加载模块:modprobe br_netfilter,再 sysctl -p。
- 确认 iptables/nftables 未拦截 FORWARD 链(见下一节“重置 Docker 网络规则”)。
- 只有 TCP6 或 IPv6 优先
- 检查 /etc/docker/daemon.json 是否误开启 IPv6(如 “ipv6”: true);如不需要,改为 “ipv6”: false 并重启:systemctl restart docker。
- 确保 ip_forward=1,避免仅走回环或仅 IPv6 路由。
- 网段冲突(如客户端在 172.17.0.0/16)
- 修改默认 docker0 网段或创建自定义网桥使用不冲突子网(见下一节“自定义网桥与子网”)。
- 创建自定义网络失败
- 常见原因:网络名重复、Docker 未启动、配置语法错误(如 /etc/docker/daemon.json 格式错误)、驱动不支持。
- 处理:改名或删除旧网络(docker network rm <名>)、启动 Docker、校验 JSON、查看 journalctl -u docker.service 获取详细报错。
以上场景覆盖了端口发布、外部访问、IPv6 优先、网段冲突与网络创建失败等高发问题。
三、进阶修复与配置
- 重置 Docker 网络规则(iptables/nftables 异常时)
- 停止 Docker:systemctl stop docker
- 清理并重装网桥:
- ip link set dev docker0 down
- brctl delbr docker0
- brctl addbr docker0
- ip addr add 172.17.0.1/24 dev docker0
- ip link set dev docker0 up
- 启动 Docker:systemctl start docker(会自动重建必要的 DOCKER 链与规则)。
- 自定义网桥与子网(规避冲突、支持固定 IP)
- 创建自定义桥接网络并指定子网:
- docker network create --driver bridge --subnet=192.168.100.0/24 mynet
- 在该网络上可指定静态 IP:docker run -d --network=mynet --ip=192.168.100.10 --name c1 nginx
- 注意:默认 bridge 不支持 –ip;固定 IP 必须在自定义网络的子网范围内且唯一。
- 使用 host 网络模式(绕过 NAT,直用宿主机网络)
- 场景:端口发布复杂、性能敏感。
- 命令:docker run --net=host …;注意端口与宿主机冲突、容器隔离性降低。
以上方法用于网桥/规则损坏、网段冲突与需要固定 IP 或更高网络性能的场景。
四、最小可用配置示例
- 修复转发与桥接钩子并持久化
- 开启转发与桥接钩子:
- echo ‘net.ipv4.ip_forward=1’ >> /etc/sysctl.conf
- echo ‘net.bridge.bridge-nf-call-iptables=1’ >> /etc/sysctl.conf
- echo ‘net.bridge.bridge-nf-call-ip6tables=1’ >> /etc/sysctl.conf
- modprobe br_netfilter && sysctl -p
- 允许容器出网 NAT:
- firewall-cmd --permanent --add-masquerade && firewall-cmd --reload
- 创建自定义桥接网络并运行容器
- docker network create --driver bridge --subnet=192.168.100.0/24 app_net
- docker run -d --name web --network=app_net -p 8080:80 nginx
- 验证:
- 宿主机:curl -I http://127.0.0.1:8080
- 容器内:docker exec -it web sh -c “ip a; ping -c 4 8.8.8.8; nslookup www.example.com”
该示例确保转发、NAT、桥接钩子与防火墙策略正确,并以自定义网络提供稳定的子网与端口发布。