Docker容器网络配置入门:四种模式怎么选、怎么连通与排错
Docker 装好之后,容器默认能访问外网,但容器之间互相 ping 不通、宿主机访问不到容器里的服务,是最常见的两类问题。
根因基本都是网络模式选错或没做端口映射。
下面按“先搞清楚四种模式,再动手配一个自定义网络,最后排错”的顺序讲,照着做即可。
先判断你的场景属于哪一类
Docker 默认给每个容器分配一个 IP,但这个 IP 只在 Docker 自己的网络里有效。
你要先回答一个问题:谁需要访问这个容器?
- 只有宿主机需要访问:用默认 bridge + 端口映射即可。
- 多个容器之间需要互相访问:建议创建自定义 bridge 网络,用容器名当域名。
- 容器需要直接占用宿主机端口、追求性能:考虑 host 模式。
- 容器不需要任何网络:用 none 模式隔离。
可以先看一眼当前环境:
docker version
docker network ls
ip addr show docker0
docker network ls 默认会列出 bridge、host、none 三个网络,这是 Docker 自带的,不要随意删除。
四种网络模式的差别与选用
bridge(默认):容器拿到一个内网 IP(常见 172.17.0.0/16 网段),通过 NAT 出外网。
宿主机要访问容器里的服务,必须加 -p 映射端口。
容器之间用 IP 能通,但用容器名默认不通。
自定义 bridge:本质还是 bridge,但 Docker 内置了 DNS,容器可以直接用容器名互相访问。
这是多容器部署(比如应用连数据库)最推荐的方案。
host:容器直接共享宿主机网络,不再有独立 IP,-p 会失效。
性能最好,但端口冲突风险高,隔离性差。
none:只有 lo 回环网卡,没有外网。
适合纯计算、不需要通信的任务。
| 模式 | 容器独立IP | 容器名互访 | 端口映射 | 典型场景 |
| --- | --- | --- | --- | --- |
| bridge | 有 | 不支持 | 支持 | 单容器对外提供服务 |
| 自定义bridge | 有 | 支持 | 支持 | 多容器互相调用 |
| host | 无 | 不适用 | 不生效 | 高性能、端口固定 |
| none | 无 | 不支持 | 不支持 | 完全隔离 |
动手配一个自定义网络并验证互通
第一步,创建网络。
网段按自己环境填,避免和现有内网冲突:
docker network create --driver bridge --subnet 172.20.0.0/16 mynet
执行后确认:
docker network inspect mynet
能看到 Subnet 为你设置的网段,说明创建成功。
第二步,启动两个容器加入同一网络。
这里用 alpine 做测试镜像:
docker run -d --name web1 --network mynet nginx:alpine
docker run -it --name test1 --network mynet alpine sh
第三步,在 test1 容器里验证。
用容器名直接访问:
ping -c 2 web1
wget -qO- http://web1
能 ping 通并且拿到 nginx 返回内容,说明自定义网络的 DNS 解析和互通都正常。
第四步,验证宿主机访问。
如果想让宿主机通过端口访问,需要在启动时加映射:
docker run -d --name web2 --network mynet -p 8080:80 nginx:alpine
curl http://127.0.0.1:8080
返回 HTML 内容即成功。
注意 -p 8080:80 的格式是宿主机端口:容器端口,顺序写反会连不上。
连不上时按这个顺序排查
容器 ping 不通外网:先在容器内执行 ping 8.8.8.8,再执行 ping www.baidu.com。
IP 通但域名不通,是 DNS 问题,检查宿主机 /etc/resolv.conf,或启动容器时用 --dns 223.5.5.5 指定。
宿主机访问不到映射端口:确认启动时确实带了 -p,用 docker port 容器名 看映射关系;
再确认服务在容器内监听的是 0.0.0.0 而不是 127.0.0.1,只监听回环的进程外部访问不到。
容器名解析失败:默认 bridge 网络不支持容器名互访,必须把容器放到同一个自定义网络里。
已经启动的容器可以临时接入:
docker network connect mynet 容器名
端口被占用:docker run 报 port is already allocated,用 ss -lntp | grep 端口号 找到占用进程,换端口或先停掉旧容器。
改了网络后容器失联:网络变更通常需要重建容器,docker network disconnect 后再 connect 只适合临时调整。
生产环境建议用 docker-compose 把网络配置写进文件,避免手工改乱。
几个容易踩的坑
- 不要手动删除
bridge、host、none这三个默认网络,删了会影响后续容器启动。 - 自定义网络的子网不要和公司内网、云服务器 VPC 网段重叠,否则路由会出问题。
--network host和-p同时写没有意义,host 模式下端口映射不生效。- 容器重启后 IP 可能变化,所以容器间通信优先用容器名而不是写死 IP。
- 改防火墙、iptables 前先确认规则来源,Docker 会自动写入 NAT 规则,手工清理容易导致所有容器断网。
常见疑问
容器之间一定要用自定义网络吗? 如果只是偶尔用 IP 通信,默认 bridge 也能通。
但 IP 会变,多容器长期协作建议用自定义网络加容器名。
host 模式是不是一定更快? 省去了 NAT 转发,网络路径更短,但差异在多数 Web 服务里并不明显,反而带来端口冲突和隔离性问题,非特殊需求不建议首选。
怎么确认容器实际用的哪个网络? 执行 docker inspect 容器名,看 NetworkSettings.Networks 字段,里面会列出网络名和分配到的 IP。
配好之后,建议用 docker network inspect 复查网段、用 curl 或 wget 验证连通性,确认无误再把配置固化到 compose 文件里。
遇到异常时,优先回看上面的排查顺序,从“外网通不通、端口有没有映射、容器名能不能解析”三步依次定位,基本都能找到原因。