01. Docker 网络是干嘛的
Docker 的网络负责容器之间、容器和宿主机之间、容器和外部网络的通信。每个容器启动时默认会连到一个叫 bridge 的虚拟网络,分配一个内部 IP。
你在容器里访问 localhost 访问的是容器自己的 localhost,不是宿主机的。这是初学者最容易搞错的——想说我在容器里连本机数据库写 localhost,结果发现连不上,因为数据库在宿主机上。
Docker 支持多种网络驱动:bridge(默认,单机容器通信)、host(容器直接用宿主机网络)、overlay(跨主机的容器通信,Swarm 模式用)、macvlan(给容器分配物理网卡的 MAC 地址)、none(无网络)。
bash
# 查看所有网络
docker network ls
# 查看网络详情
docker network inspect bridge
# 创建自定义网络
docker network create --driver bridge mynet
# 运行容器时指定网络
docker run -d --network mynet --name web nginx
docker run -d --network mynet --name db mysql自定义 bridge 网络比默认 bridge 好——支持 DNS 解析,容器之间可以通过容器名互相访问。
02. Bridge 网络详解
Bridge 是 Docker 默认的网络模式,创建一个虚拟网桥 docker0,每个容器通过虚拟网卡连到这个网桥上。默认 bridge 下容器之间只能用 IP 通信,但自定义 bridge 支持 DNS 解析——容器名直接当域名用。
端口映射:容器内的端口默认外部访问不到,需要在 docker run 时用 -p 映射。比如 -p 8080:80 表示宿主机的 8080 端口转发到容器的 80 端口。
容器之间通信:在同一个自定义网络下的容器,直接用容器名就能互相 ping 通。Docker 内置的 DNS 服务器(127.0.0.11)负责解析。这是 docker-compose 多容器服务通信的基础。
bash
# 端口映射
# 宿主 8080 -> 容器 80
docker run -d -p 8080:80 nginx
# 只监听本机(只允许 127.0.0.1 访问)
docker run -d -p 127.0.0.1:8080:80 nginx
# 随机端口映射
docker run -d -P nginx
# 容器间 DNS 通信
docker network create appnet
docker run -d --network appnet --name web nginx
docker run -d --network appnet --name app node:18
# app 容器里直接 curl web 就行自定义 bridge 网络的 DNS 解析只对容器名生效,默认 bridge 网络不支持。所以独立项目最好建自己的网络。
03. Host 与 None 网络
host 网络:容器直接共享宿主机的网络命名空间,没有网络隔离。容器监听的端口直接暴露在宿主机上,不需要 -p 映射。性能最好(没有 NAT 转发开销),但安全性差(容器可以直接访问宿主机所有网络接口)。
适用场景:高性能网络应用(如 Nginx 代理)、容器需要访问宿主机大量端口的场景。Windows 和 Mac 上 host 模式不支持或行为不同。
none 网络:容器没有网络接口,完全隔离。适合不需要网络的纯计算任务,或者安全要求极高、绝不能联网的容器。
bash
# Host 网络
docker run -d --network host nginx
# nginx 的 80 端口直接出现在宿主机上
# None 网络
docker run --network none --name isolated alpine
# 给运行的容器连接/断开网络
docker network connect mynet web
docker network disconnect mynet webhost 网络模式下容器和宿主机共用网络,端口冲突直接报错。一台机器上只能有一个进程监听某个端口。
04. Overlay 网络与跨主机通信
单机用 bridge 就够了,但跑集群(Docker Swarm 或 Kubernetes)时,不同机器上的容器需要互相通信就要用 overlay 网络。
Overlay 网络在多台 Docker 宿主机之间创建分布式网络——不同主机上的容器看起来在同一个局域网里,可以直接 IP 通信。底层用 VXLAN 隧道封装数据包。
创建 overlay 网络需要先初始化 Swarm(docker swarm init),然后创建 overlay 网络,各节点上的容器加入这个网络就能跨主机通信。Kubernetes 的 Flannel、Calico 也是类似原理。
bash
# 初始化 Swarm(主节点)
docker swarm init
# 创建 overlay 网络
docker network create -d overlay --attachable myoverlay
# 在不同节点上运行容器加入 overlay
docker run -d --network myoverlay --name web nginx
# 查看 swarm 节点
docker node ls05. 网络调试与排错
容器网络出问题了?常用排查手段:
docker network inspect——看网络里有哪些容器、IP 分配情况。
docker exec 进容器 ping 另一个容器名——测试 DNS 解析是否正常。
docker run --rm alpine nslookup 容器名——用 alpine 自带的 nslookup 手动测 DNS。
docker logs 容器名——看容器的启动日志,很多时候网络问题是因为端口被占用了。
容器内 curl 宿主机 IP:端口——确认是不是端口映射的问题。
宿主机 curl localhost:映射端口——确认是不是防火墙的问题。
bash
# 进容器排查网络
docker exec -it web sh
ping app # 容器名能解析吗?
ping 8.8.4.4 # 能出外网吗?
curl app:3000 # 能连另一个容器吗?
# 宿主机上排查
docker network inspect mynet | jq '.[0].Containers'
docker port web # 查看端口映射
# 手动 DNS 测试
docker run --rm --network mynet alpine nslookup web容器的 curl 默认可能没装。alpine 镜像里 curl 也没有,可以用 wget -qO- 代替,或者 apt-get install curl。
知识测验
第 1/5 题正确 0
默认 bridge 和自定义 bridge 最大的区别?
下一节
下一节 Docker 数据持久化