Docker 网络
Docker 网络概述
Docker 使用网络驱动程序提供网络功能,每个容器都有自己的网络 namespace。
Docker 网络架构
┌─────────────────────────────────────────┐
│ Docker Host │
│ ┌───────────────────────────────────┐ │
│ │ docker0 (bridge) │ │
│ │ 172.17.0.1/16 │ │
│ │ ┌─────────┐ ┌─────────┐ │ │
│ │ │nginx │ │ mysql │ │ │
│ │ │172.17.0.2│ │172.17.0.3│ │ │
│ │ └─────────┘ └─────────┘ │ │
│ └───────────────────────────────────┘ │
└─────────────────────────────────────────┘1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
网络驱动类型
| 驱动 | 说明 | 使用场景 |
|---|---|---|
| bridge | 默认驱动,容器连接到 bridge 网络 | 单主机容器通信 |
| host | 容器直接使用主机网络 | 性能敏感场景 |
| overlay | 跨主机容器通信(Swarm) | 集群环境 |
| macvlan | 给容器分配 MAC 地址 | 需要直接暴露容器 |
| none | 禁用网络 | 网络隔离 |
| network plugins | 第三方网络插件 | 特殊网络需求 |
查看网络
bash
# 列出所有网络
docker network ls
# NETWORK ID NAME DRIVER SCOPE
# abc123... bridge bridge local
# def456... host host local
# ghi789... none null local
# 查看网络详情
docker network inspect bridge
# 查看容器的网络
docker inspect -f '{{.NetworkSettings.Networks}}' container_name1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
Bridge 网络
默认网络,容器连接到这个虚拟网桥。
容器间通信
bash
# 默认情况下,同一 bridge 网络的容器可以互相通信
docker run -d --name nginx nginx
docker run -d --name app myapp
# 测试连通性
docker exec app ping nginx
# 如果失败,检查防火墙或 iptables
# 查看容器 IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
自定义 Bridge
推荐使用自定义 bridge,优于默认 bridge:
bash
# 创建自定义 bridge
docker network create my-bridge
# 在自定义网络中,容器可以通过名称互相访问
docker run -d --name nginx --network my-bridge nginx
docker run -d --name app --network my-bridge myapp
# 测试(自定义 bridge 支持 DNS 自动解析)
docker exec app ping nginx1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
连接到网络
bash
# 运行容器时指定网络
docker run -d --name app --network my-bridge myapp
# 将运行中的容器连接到网络
docker network connect my-bridge nginx
# 将容器从网络断开
docker network disconnect my-bridge nginx1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
Host 网络
容器直接使用主机网络栈,性能最好但隔离性差。
bash
# 使用 host 网络
docker run -d --name nginx --network host nginx
# 注意:
# - 容器端口直接暴露到主机
# - nginx.conf 中的 80 端口直接绑定主机
# - 不能再用 -p 参数映射端口1
2
3
4
5
6
7
2
3
4
5
6
7
None 网络
禁用容器网络,容器完全隔离。
bash
docker run -d --name isolated --network none nginx
docker exec isolated ping 8.8.8.8 # 会失败1
2
2
端口映射
将容器端口映射到主机端口,外部可以访问。
bash
# 基本语法:-p 主机端口:容器端口
docker run -d --name nginx -p 80:80 nginx
# 访问
curl http://localhost:80
# 多个端口映射
docker run -d --name app -p 3000:3000 -p 5000:5000 myapp
# 指定协议
docker run -d --name app -p 8080:80/tcp -p 8081:80/udp myapp
# 映射到主机随机端口
docker run -d --name nginx -P nginx
# Docker 会分配一个随机端口
docker port nginx
# 80/tcp -> 0.0.0.0:327681
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Overlay 网络(跨主机通信)
用于 Docker Swarm 集群,跨多个主机连接容器。
初始化 Swarm
bash
# 初始化 Swarm 管理节点
docker swarm init
# 加入 Swarm 作为工作节点
docker swarm join --token TOKEN MANAGER_IP:23771
2
3
4
5
2
3
4
5
创建 Overlay 网络
bash
# 创建 overlay 网络
docker network create -d overlay my-overlay
# 查看网络
docker network ls
# 在服务中使用 overlay 网络
docker service create --name web --network my-overlay -p 80:80 nginx1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
Macvlan 网络
给容器分配真实的 MAC 地址,容器像真实机器一样出现在网络中。
bash
# 创建 macvlan 网络
docker network create -d macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 \
my-macvlan
# 运行容器
docker run -d --name app --network my-macvlan --ip=192.168.1.100 myapp1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
容器 DNS
DNS 工作原理
- 默认 bridge:只能通过 IP 通信
- 自定义 bridge:支持容器名称 DNS 解析
- Docker Compose:服务名自动 DNS 解析
bash
# 测试 DNS 解析
docker exec app nslookup nginx # 在默认 bridge 不工作
docker exec app nslookup nginx # 在自定义 bridge 可以
# 查看容器的 DNS 配置
docker exec app cat /etc/resolv.conf1
2
3
4
5
6
2
3
4
5
6
Docker Compose 网络
yaml
version: '3.8'
services:
web:
build: .
networks:
- frontend
ports:
- "80:80"
db:
image: mysql:8
networks:
- backend
volumes:
- db_data:/var/lib/mysql
networks:
frontend:
driver: bridge
backend:
driver: bridge
volumes:
db_data:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
网络通信规则
yaml
# 默认情况下,frontend 可以访问 backend
# backend 不能直接访问 frontend(除非显式连接)
# 不同 Compose 文件的服务默认隔离
services:
web:
networks:
- frontend
- backend
db:
networks:
- backend1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
常见问题
1. 容器无法访问外网
bash
# 检查主机 iptables
sudo iptables -L -n
# 检查 DNS
docker exec container_name cat /etc/resolv.conf
# 重启 Docker 网络
sudo systemctl restart docker1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
2. 端口冲突
bash
# 检查端口占用
netstat -tlnp | grep 80
lsof -i :80
# 使用其他端口
docker run -d -p 8080:80 nginx1
2
3
4
5
6
2
3
4
5
6
3. 容器间无法通过名称通信
bash
# 确保在同一网络
docker network connect my-bridge container-a
docker network connect my-bridge container-b
# 检查网络驱动
docker inspect -f '{{.NetworkSettings.Networks}}' container-a1
2
3
4
5
6
2
3
4
5
6
4. 网络性能问题
bash
# 使用 host 网络提升性能
docker run -d --network host myapp
# 检查网络统计
docker stats
# 查看容器网络 IO
docker exec container_name cat /sys/class/net/eth0/statistics/rx_bytes1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
网络命令
bash
# 列出网络
docker network ls
# 创建网络
docker network create my-network
# 连接容器
docker network connect my-network container-name
# 断开容器
docker network disconnect my-network container-name
# 删除网络
docker network rm my-network
# 删除未使用的网络
docker network prune
# 查看网络详情
docker network inspect my-network1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
网络工具
在容器中安装网络工具进行调试:
bash
# 安装网络工具
docker exec container_name apt-get update && apt-get install -y iputils-ping net-tools curl
# 常用命令
docker exec container_name ping -c 3 8.8.8.8
docker exec container_name netstat -tuln
docker exec container_name curl http://localhost1
2
3
4
5
6
7
2
3
4
5
6
7
[[返回 Docker 首页|docker/index]]