根本原因是默认 bridge 网络依赖 iptables nat 和内核 ip_forward,而云服务器常默认关闭该参数;需开启 net.ipv4.ip_forward 并配置 firewalld/ufw 转发规则。

为什么容器间 ping 不通,但 docker exec 进去能 curl 通?
根本原因是默认 bridge 网络下,容器间通信依赖 iptables NAT 规则和内核转发开关,而很多宿主机(尤其是云服务器)默认关闭了 net.ipv4.ip_forward。
- 检查是否开启:运行
sysctl net.ipv4.ip_forward,输出net.ipv4.ip_forward = 0就是关着的 - 临时开启:
sudo sysctl -w net.ipv4.ip_forward=1 - 永久生效:把
net.ipv4.ip_forward = 1写进/etc/sysctl.conf或/etc/sysctl.d/99-docker.conf - 别漏掉 firewalld/ufw:CentOS 7+ 的 firewalld 默认 drop 转发链,得加规则
sudo firewall-cmd --permanent --zone=trusted --add-interface=docker0
docker run --network host 真的更快吗?
快,但只在特定场景下有意义——比如你跑的是高性能网络服务(如 Envoy、Nginx),且不需要容器网络隔离;多数应用反而因此失去端口映射、DNS 自动配置、/etc/hosts 容器名解析等便利。
- 性能提升主要来自绕过
docker0网桥和 iptables DNAT/SNAT,延迟降低约 5–10%,吞吐略高 - 副作用明显:容器直接暴露宿主所有网络接口,
localhost指向宿主机而非容器自身,127.0.0.1:8080可能连到宿主机进程 - 不兼容 Swarm 和大多数编排工具,Kubernetes 里
hostNetwork: true是明确标记为“需谨慎使用”的字段
用 overlay 网络时,跨主机容器通信变慢甚至超时
本质是 VXLAN 封包/解包 + 内核路由路径变长,但真正拖慢的往往是 MTU 不匹配或未启用 GRO/GSO 卸载。
- 查宿主机网卡 MTU:
ip link show eth0 | grep mtu,常见是 1500;而 Docker overlay 默认 VXLAN MTU 是 1450,若底层物理网卡 MTU 更小(比如某些云厂商设成 1400),就会触发分片 - 创建 overlay 网络时显式指定:
docker network create -d overlay --opt com.docker.network.driver.mtu=1400 mynet - 确认内核卸载开启:
ethtool -k eth0 | grep generic-receive-offload,若为 off,用sudo ethtool -K eth0 gro on打开 - 避免在 overlay 上跑大量小包 RPC(如 gRPC keepalive 频繁心跳),这类流量对 VXLAN 封包延迟更敏感
docker volume 性能比 bind mount 差很多?
不一定。差的是默认 driver(local)在某些文件系统上的元数据操作开销,不是 volume 本身有“天然瓶颈”。关键看底层存储引擎和挂载选项。
-
bind mount直接透传宿主目录,IO 路径最短,但权限、SELinux 上下文、热迁移支持弱 -
docker volume用localdriver 时,实际就是bind mount的封装,但默认以rw,rprivate挂载,某些 XFS/Btrfs 下 rename() 性能不如rshared - 实测提速法:建 volume 时加选项
--opt o=rw,rshared(注意宿主机必须支持 shared mount) - 真要高 IO:用
tmpfsvolume 存缓存,或对接lvm2/zfsdriver 做快照和压缩
网络和存储优化从来不是调几个参数就完事——bridge 网络的 iptables 规则顺序、overlay 的 VXLAN port 冲突、volume driver 的 mountflags 传递逻辑,都可能在升级 Docker 或内核后悄然变化。上线前务必用真实负载压测,而不是只看 ping 和 dd。










