Linux Docker 网络与存储优化

2次阅读

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

Linux Docker 网络与存储优化

为什么容器间 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 和大多数编排工具,kuberneteshostNetwork: 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 volumelocal driver 时,实际就是 bind mount封装,但默认以 rw,rprivate 挂载,某些 XFS/Btrfs 下 rename() 性能不如 rshared
  • 实测提速法:建 volume 时加选项 --opt o=rw,rshared(注意宿主机必须支持 shared mount)
  • 真要高 IO:用 tmpfs volume 存缓存,或对接 lvm2/zfs driver 做快照和压缩

网络和存储优化从来不是调几个参数就完事——bridge 网络的 iptables 规则顺序、overlay 的 VXLAN port 冲突、volume driver 的 mountflags 传递逻辑,都可能在升级 Docker 或内核后悄然变化。上线前务必用真实负载压测,而不是只看 pingdd

text=ZqhQzanResources