宿主机端口冲突需用ss -tuln | grep :端口直接验证,因host模式下容器复用宿主机网络栈且忽略-p参数,docker ps无法显示非容器进程占用。

docker run --net=host 时端口冲突怎么快速定位
宿主机上已被占用的端口(比如 3306、6379、80)在 host 模式下容器会直接复用,一旦冲突,docker run 会静默失败或容器内服务启动报 “Address already in use”,但错误信息不指向宿主机端口。最直接的验证方式是:ss -tuln | grep :端口号,而不是只看容器日志。
常见踩坑点:
- 误以为
-p 8080:80在 host 模式下还有作用 —— 实际上--net=host下-p参数被完全忽略 - 多个 host 模式容器同时监听
0.0.0.0:9090,第二个必然失败,且 Docker 不提示“端口被其他容器占”,只提示系统级 bind 失败 - systemd 或其他守护进程(如 nginx、apache)可能悄悄占用了端口,
docker ps看不到,必须查宿主机
自定义 bridge 网络为什么比默认 docker0 更适合生产
默认的 docker0 是全局共享网桥,所有未指定 --network 的容器都挤进去,容易引发三类问题:IP 地址重复分配、容器名 DNS 解析失败、iptables 规则膨胀导致转发延迟上升。而自定义 bridge 是显式创建、按需加入,关键优势在可配置性和确定性。
实操建议:
- 创建带子网的网络:
docker network create --subnet=172.20.0.0/16 --gateway=172.20.0.1 mynet - 启动容器时强制指定:
docker run --network mynet --name db postgres - 已有容器接入:
docker network connect mynet app_container - 避免硬编码 IP:
--ip只在极少数需要固定地址的场景用,日常通信优先靠容器名(如curl http://db:5432)
container 模式下两个容器如何真正共享网络栈
--net=container:NAME 不是“互通”,而是“合并”——新容器不会创建自己的网络设备,eth0、路由表、/proc/sys/net 全部继承自目标容器。这意味着它们共用一个 IP、一个端口空间、一个 lo 接口,甚至 netstat -tuln 看到的监听端口也完全一致。
使用 Python 脚本下载 Docker 镜像并打包为 tar 文件。用户说“下载镜像”“拉取镜像”“pull xxx”“帮我下载 nginx 镜像”等时触发。支持 SOCKS5 代理直连(推荐)和国内镜像站加速两种模式。
典型使用场景和限制:
- 常用于 nginx + php-fpm 绑定部署:php-fpm 容器用
--net=container:nginx,两者通过127.0.0.1:9000通信,零网络开销 - 不能跨宿主机:目标容器必须在同一台机器上运行
- 目标容器不能是
none或已退出状态,否则启动失败并报错No such container - 若目标容器重启,新容器的网络命名空间不会自动更新,需手动重建
容器 ping 不通外网时该查哪三层
不是所有 bridge 网络天生能上网。断点通常卡在三层:宿主机 FORWARD 链策略、Docker daemon 是否接管 iptables、内核 rp_filter 设置。别一上来就改容器配置。
排查顺序建议:
- 先验证宿主机是否能通外网:
ping -c2 8.8.8.8 - 再验证 Docker 是否具备转发能力:
docker run --rm --network host alpine ping -c2 8.8.8.8;如果这步失败,说明是宿主机网络或防火墙问题 - 检查 FORWARD 链是否被 DROP:
iptables -L FORWARD -n | grep DROP;若有,临时放行:iptables -I FORWARD -i docker0 -o eth0 -j ACCEPT - 确认 Docker 是否启用 iptables 管理:
grep 'iptables' /etc/docker/daemon.json,值应为true(默认),否则需重启 dockerd
rp_filter 导致的丢包最难察觉:它会让从非对称路径进来的包被内核静默丢弃,现象是容器能发请求但收不到响应,解决方法是 echo 0 > /proc/sys/net/ipv4/conf/docker0/rp_filter(临时)或写入 /etc/sysctl.conf(持久化)。










