容器网络配置不当,典型表现是同机两个服务用 localhost 连不上、换 IP 又能通,重建后 IP 还变了。
一、Docker 默认网络模式与 bridge 的两个坑
1. 四种内置网络模式
docker network ls 可列出 bridge、host、none 三个自带网络,container 模式则共享另一容器的网络栈。bridge 是默认模式,容器挂在 docker0 网桥上经 NAT 出网;host 直接用宿主机网络栈;none 只留 lo。
2. 默认 bridge 没有 DNS
默认 bridge 上容器只能靠 IP 互访,Docker 不做名字解析,ping 容器名会报 Name or service not known。按名字访问只能加 --link,它从 Docker 1.9 起已是遗留特性。地址池固定为 172.17.0.0/16,与内网 VPC 撞车时访问不到同网段机器,需改 dockerd 的 --bip 重启。
docker run -d --name web nginx:alpine
docker network create -d bridge --subnet 172.20.0.0/16 appnet
docker run -d --name web2 --network appnet nginx:alpine
docker exec web2 getent hosts web
二、自定义网络与容器间通信
1. 自定义网络与动态接入
docker network create --driver bridge 创建的就是自定义 bridge:可用 --subnet 指定网段躲开内网冲突,并自带内嵌 DNS。已运行的容器无需重建,docker network connect appnet web 即可接入;一个容器还能同时加入多个网络做隔离。
2. 按容器名互访
自定义网络上每个容器都会拿到内嵌 DNS,固定监听 127.0.0.11,把容器名与 --network-alias 别名解析为容器 IP。服务地址直接写容器名,容器重建换 IP 也不用改配置;给两套容器加同一别名 api 还能做灰度。
docker run -d --name mysql --network appnet mysql:8
docker run -d --name app --network appnet php:8.2-fpm-alpine
docker exec app getent hosts mysql
docker network inspect appnet
三、host 模式、端口映射与排查
1. host 与 none 模式怎么选
--network host 让容器复用宿主机网络栈,绑定的端口即宿主机端口,无需 -p,适合单实例网关;代价是端口被独占,且 Docker Desktop 里 host 指向的是虚拟机而非本机。--network none 只留 lo,适合离线编译。
2. 端口映射与排查三连
-p 8080:80 把宿主机 8080 转发到容器 80;写成 -p 127.0.0.1:8080:80 只监听本机网卡。连不上可按「网络是否一致、名字能否解析、路由是否正确」三步排查。
docker run -d --name gw --network host nginx:alpine
docker run -d --network appnet -p 127.0.0.1:8080:80 --name portal nginx:alpine
docker exec app ip route
关键配置提示
- 按容器名互访一律自建 bridge 网络,默认 bridge 不提供任何名字解析。
- 端口映射写成
-p 127.0.0.1:宿主机端口:容器端口,避免中间件暴露公网。 - 网段与内网冲突时用
--subnet指定独立网段,不要动默认的 172.17。


快来评论,快来抢沙发吧~