Docker 网络
网络驱动类型
| 驱动 | 说明 | 隔离性 | 适用场景 |
|---|---|---|---|
bridge | 默认网络,通过 veth pair 连接 | 容器间隔离 | 单机多容器 |
host | 共享宿主机网络命名空间 | 无隔离 | 性能优先、网络调试 |
none | 无网络 | 完全隔离 | 安全敏感、离线任务 |
overlay | 跨主机通信(VXLAN) | 跨主机隔离 | Swarm / K8s 集群 |
macvlan | 容器拥有独立 MAC 地址 | 二层隔离 | 需要直接接入物理网络 |
Bridge 网络详解
Bridge 是 Docker 默认的网络模式。每个容器通过 veth pair 连接到 docker0 网桥。
默认 bridge vs 自定义 bridge
| 特性 | 默认 bridge | 自定义 bridge |
|---|---|---|
| DNS 解析 | ❌ 只能用 IP | ✅ 容器名自动解析 |
| 隔离性 | 所有容器共享 | 不同网络隔离 |
| 热连接 | ❌ 需重建容器 | ✅ 运行时可连接/断开 |
| 配置 | 不可自定义 | 可自定义子网、网关 |
推荐使用自定义 bridge
自定义 bridge 网络支持 DNS 自动发现(用容器名访问),是最常用的网络模式。
# 创建自定义网络
docker network create --driver bridge \
--subnet 172.20.0.0/16 \
--gateway 172.20.0.1 \
app-net
# 启动容器并加入网络
docker run -d --name web --network app-net nginx
docker run -d --name api --network app-net myapi
# 容器内可直接用容器名访问
# curl http://web:80
# curl http://api:3000
容器间通信
同一网络内通信
# 创建网络
docker network create backend
# 启动服务
docker run -d --name db --network backend postgres:16
docker run -d --name app --network backend myapp
# app 容器内直接访问:
# postgres://db:5432/mydb ← 用容器名做主机名
跨网络通信
# 容器可同时连接多个网络
docker network create frontend
docker network create backend
docker run -d --name api --network backend myapi
docker network connect frontend api # api 同时在两个网络中
docker run -d --name web --network frontend nginx
docker run -d --name db --network backend postgres
# web → api: ✅(frontend 网络)
# api → db: ✅(backend 网络)
# web → db: ❌(不同网络,隔离)
端口映射
# -p 宿主端口:容器端口
docker run -d -p 8080:80 nginx # 映射到所有接口
docker run -d -p 127.0.0.1:8080:80 nginx # 只映射到 localhost
docker run -d -p 8080:80/udp nginx # UDP 端口
docker run -d -P nginx # 随机映射 EXPOSE 端口
# 查看端口映射
docker port container_name
端口安全
-p 8080:80 默认绑定 0.0.0.0,外网可直接访问。生产环境建议绑定 127.0.0.1,通过 Nginx 反向代理对外。
Host 网络模式
# 容器直接使用宿主机网络,无网络隔离
docker run -d --network host nginx
# nginx 直接监听宿主机 80 端口,无需 -p 映射
适用场景:
- 性能要求极高(省去 NAT 开销)
- 需要访问宿主机所有端口
- 网络抓包调试
网络管理命令
# 列出所有网络
docker network ls
# 查看网络详情(含连接的容器)
docker network inspect app-net
# 连接/断开容器与网络
docker network connect app-net container_name
docker network disconnect app-net container_name
# 删除网络
docker network rm app-net
# 清理未使用的网络
docker network prune
容器内 DNS
Docker 内置 DNS 服务器(127.0.0.11),自定义 bridge 网络中的容器自动注册 DNS。
# 自定义 DNS
docker run -d --dns 8.8.8.8 --dns-search example.com myapp
# 添加 hosts 条目
docker run -d --add-host myhost:10.0.0.1 myapp
Docker Compose 网络
compose.yml
services:
web:
image: nginx
networks:
- frontend
api:
image: myapi
networks:
- frontend
- backend
db:
image: postgres
networks:
- backend
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # 内部网络,不能访问外网
Compose 默认创建一个 项目名_default 网络,所有未指定网络的服务都加入该网络。
常见面试问题
Q1: Docker 容器间如何通信?
答案:
- 同一自定义 bridge 网络:通过容器名 DNS 自动解析(推荐)
- 默认 bridge:只能用 IP 或
--link(已弃用) - Host 模式:共享宿主机网络栈,直接用 localhost
- 跨主机:overlay 网络(Swarm)或第三方方案(Flannel/Calico)
Q2: bridge 模式的网络原理?
答案:
- Docker 创建虚拟网桥
docker0 - 每个容器创建 veth pair(虚拟以太网对)
- 一端在容器内作为 eth0,一端连接到网桥
- 容器通过网桥通信,外部访问通过 iptables NAT 转发
Q3: Docker 网络模式如何选择?
答案:
| 场景 | 推荐模式 |
|---|---|
| 单机多服务(默认) | 自定义 bridge |
| 极致性能需求 | host |
| 安全隔离 / 离线任务 | none |
| 多主机集群通信 | overlay |
| 直连物理网络 | macvlan |