网络架构图:
┌─────────────────────────────────────────┐
│ Docker主机网络 │
├─────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ │ Container│ │ Container│ │ Container│
│ │ eth0 │ │ eth0 │ │ eth0 │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │ │
│ ┌────┴─────────────┴─────────────┴─────┐
│ │ docker0 (Bridge Network) │
│ │ 172.17.0.1/16 │
│ └──────────────┬───────────────────────┘
│ │
│ ┌──────────────┴───────────────────────┐
│ │ eth0 (Host Network) │
│ │ 192.168.1.100 │
│ └──────────────┬───────────────────────┘
└─────────────────┼─────────────────────────┘
│
┌────────┴────────┐
│ 外部网络 │
└─────────────────┘
东巴文理解:
Docker网络 = 虚拟交换机
就像:为每个容器分配独立的网络接口
网络组成:
├─ docker0网桥:虚拟交换机
├─ veth pair:虚拟网线
├─ 容器网卡:eth0
└─ iptables:网络地址转换
工作原理:
├─ 容器通过veth pair连接到docker0
├─ docker0作为网桥转发数据包
├─ iptables实现NAT和端口映射
└─ 容器可以相互通信和访问外部网络
命名空间概念:
网络命名空间:
├─ 隔离网络资源
├─ 独立的网络栈
├─ 独立的IP地址
├─ 独立的路由表
└─ 独立的iptables规则
每个容器:
├─ 有自己的网络命名空间
├─ 有自己的网络设备
├─ 有自己的IP地址
└─ 与其他容器网络隔离
模式列表:
bridge模式(默认):
├─ 桥接网络
├─ 容器连接到docker0网桥
├─ 容器有独立IP
└─ 通过NAT访问外部
host模式:
├─ 主机网络
├─ 容器共享主机网络
├─ 没有网络隔离
└─ 性能最优
none模式:
├─ 无网络
├─ 容器没有网络接口
├─ 完全网络隔离
└─ 安全性最高
container模式:
├─ 容器网络
├─ 共享另一个容器的网络
├─ 共享IP和端口
└─ 用于容器间通信
自定义网络:
├─ 用户创建的网络
├─ 支持DNS解析
├─ 灵活配置
└─ 推荐使用
网络拓扑:
┌───────────────────────────────────────┐
│ Docker主机 │
├───────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ Container│ │ Container│ │
│ │ 172.17.0.2│ │ 172.17.0.3│ │
│ └────┬─────┘ └────┬─────┘ │
│ │ veth │ veth │
│ └─────┬─────────────┘ │
│ │ │
│ ┌──────┴──────┐ │
│ │ docker0 │ │
│ │ 172.17.0.1 │ │
│ └──────┬──────┘ │
│ │ │
│ ┌──────┴──────┐ │
│ │ eth0 │ │
│ │ 192.168.1.100│ │
│ └──────┬──────┘ │
└─────────────┼─────────────────────────┘
│
外部网络
数据包转发:
容器访问外部:
├─ 容器(172.17.0.2) → docker0(172.17.0.1)
├─ docker0 → eth0(192.168.1.100)
├─ iptables NAT转换
└─ 发送到外部网络
外部访问容器:
├─ 外部请求 → eth0:8080
├─ iptables端口映射
├─ 转发到容器(172.17.0.2:80)
└─ 容器处理请求
查看默认网络:
# 查看网络列表
docker network ls
# 输出
NETWORK ID NAME DRIVER SCOPE
a1b2c3d4e5f6 bridge bridge local
b2c3d4e5f6a7 host host local
c3d4e5f6a7b8 none null local
# 查看bridge网络详情
docker network inspect bridge
# 输出
[
{
"Name": "bridge",
"Id": "a1b2c3d4e5f6...",
"Driver": "bridge",
"IPAM": {
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Containers": {
"容器ID": {
"Name": "mynginx",
"IPv4Address": "172.17.0.2/16"
}
}
}
]
基本使用:
# 默认使用bridge模式
docker run -d --name mynginx nginx:latest
# 指定bridge模式
docker run -d --name mynginx --net=bridge nginx:latest
# 查看容器网络
docker inspect mynginx | grep IPAddress
# 输出
"IPAddress": "172.17.0.2"
端口映射:
# 映射单个端口
docker run -d -p 8080:80 --name mynginx nginx:latest
# 映射多个端口
docker run -d -p 8080:80 -p 8443:443 --name mynginx nginx:latest
# 指定IP映射
docker run -d -p 127.0.0.1:8080:80 --name mynginx nginx:latest
# 随机端口映射
docker run -d -P --name mynginx nginx:latest
# 查看端口映射
docker port mynginx
# 输出
80/tcp -> 0.0.0.0:8080
默认bridge网络限制:
# 创建两个容器
docker run -d --name web nginx:latest
docker run -d --name app myapp:latest
# 进入web容器
docker exec -it web bash
# 尝试通过容器名访问app容器
ping app
# ping: app: Name or service not known
# 只能通过IP访问
ping 172.17.0.3
# PING 172.17.0.3 (172.17.0.3): 56 data bytes
说明:
默认bridge网络:
❌ 不支持DNS解析
❌ 容器间不能通过名称访问
❌ 只能通过IP地址访问
❌ 需要使用--link(已废弃)
解决方案:
✅ 使用自定义网络
✅ 支持DNS解析
✅ 容器间可通过名称访问
网络拓扑:
┌───────────────────────────────────────┐
│ Docker主机 │
├───────────────────────────────────────┤
│ │
│ ┌──────────┐ │
│ │ Container│ │
│ │ 共享网络命名空间 │
│ └────┬─────┘ │
│ │ │
│ ┌────┴─────────────────────────────┐
│ │ eth0 │
│ │ 192.168.1.100 │
│ │ 共享主机网络栈 │
│ └──────────────┬───────────────────┘
└─────────────────┼─────────────────────┘
│
外部网络
特点:
Host模式:
├─ 容器共享主机网络命名空间
├─ 使用主机IP地址
├─ 使用主机端口
├─ 没有网络隔离
├─ 性能最优
└─ 端口冲突风险
优势:
✅ 网络性能最优(无NAT)
✅ 无需端口映射
✅ 适合高性能应用
劣势:
❌ 没有网络隔离
❌ 端口冲突风险
❌ 安全性较低
基本使用:
# 使用host模式
docker run -d --name mynginx --net=host nginx:latest
# 查看容器网络
docker inspect mynginx | grep NetworkMode
# 输出
"NetworkMode": "host"
# 容器直接使用主机端口
curl http://localhost:80
注意事项:
# 端口冲突示例
docker run -d --name nginx1 --net=host nginx:latest
docker run -d --name nginx2 --net=host nginx:latest
# nginx2启动失败
# Error: port is already allocated
# 解决方法:修改应用端口
docker run -d --name nginx2 --net=host -e NGINX_PORT=8080 nginx:latest
推荐场景:
高性能应用:
├─ 网络密集型应用
├─ 需要极低网络延迟
├─ 大量网络IO
└─ 示例:游戏服务器、实时通信
端口已知应用:
├─ 应用端口固定
├─ 不需要动态端口映射
└─ 示例:数据库、消息队列
网络监控:
├─ 需要监控主机网络
├─ 需要访问主机网络接口
└─ 示例:网络监控工具
网络拓扑:
┌───────────────────────────────────────┐
│ Docker主机 │
├───────────────────────────────────────┤
│ │
│ ┌──────────┐ │
│ │ Container│ │
│ │ lo (127.0.0.1) │
│ │ 没有其他网络接口 │
│ └──────────┘ │
│ │
│ ┌────────────────────────────────────┐
│ │ eth0 │
│ │ 192.168.1.100 │
│ └──────────────┬─────────────────────┘
└─────────────────┼─────────────────────┘
│
外部网络
特点:
None模式:
├─ 容器没有网络接口
├─ 只有loopback接口
├─ 完全网络隔离
├─ 安全性最高
└─ 需要手动配置网络
优势:
✅ 完全网络隔离
✅ 安全性最高
✅ 适合敏感应用
劣势:
❌ 无法访问外部网络
❌ 外部无法访问容器
❌ 需要手动配置网络
基本使用:
# 使用none模式
docker run -d --name myapp --net=none myapp:latest
# 查看容器网络
docker exec myapp ip addr
# 输出
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
# 只有loopback接口,没有其他网络接口
推荐场景:
安全敏感应用:
├─ 不需要网络访问
├─ 完全隔离环境
└─ 示例:加密解密服务
离线处理:
├─ 本地数据处理
├─ 不需要网络连接
└─ 示例:批处理任务
测试环境:
├─ 测试网络隔离
├─ 安全测试
└─ 示例:渗透测试
网络拓扑:
┌───────────────────────────────────────┐
│ Docker主机 │
├───────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ Container│ │ Container│ │
│ │ (Web) │ │ (App) │ │
│ └────┬─────┘ └────┬─────┘ │
│ │ │ │
│ └─────┬─────────────┘ │
│ │ 共享网络命名空间 │
│ ┌──────┴──────┐ │
│ │ docker0 │ │
│ │ 172.17.0.2 │ │
│ └──────┬──────┘ │
└─────────────┼─────────────────────────┘
│
外部网络
特点:
Container模式:
├─ 共享另一个容器的网络命名空间
├─ 共享IP地址和端口
├─ 共享网络配置
├─ 可以通过localhost通信
└─ 紧密耦合的容器
优势:
✅ 容器间通信高效
✅ 共享网络资源
✅ 适合紧密耦合的应用
劣势:
❌ 网络隔离性差
❌ 端口冲突风险
❌ 依赖关系复杂
基本使用:
# 创建第一个容器
docker run -d --name web nginx:latest
# 创建第二个容器,共享web容器的网络
docker run -d --name app --net=container:web myapp:latest
# 查看两个容器的IP
docker inspect web | grep IPAddress
docker inspect app | grep IPAddress
# 输出(IP地址相同)
"IPAddress": "172.17.0.2"
"IPAddress": "172.17.0.2"
# 在app容器中访问web容器
docker exec app curl http://localhost:80
推荐场景:
紧密耦合应用:
├─ Web服务器 + 应用服务器
├─ 需要通过localhost通信
└─ 示例:Nginx + PHP-FPM
监控代理:
├─ 应用容器 + 监控代理
├─ 共享网络命名空间
└─ 示例:应用 + Sidecar
调试工具:
├─ 应用容器 + 调试工具
├─ 共享网络环境
└─ 示例:应用 + 网络调试工具
基本语法:
docker network create [OPTIONS] NETWORK
OPTIONS:
--attachable 允许手动连接容器
--aux-address map 辅助IP地址
--config-from string 从指定网络复制配置
--config-only 创建仅配置网络
-d, --driver string 网络驱动(bridge/overlay)
--gateway strings 网关
--internal 禁止外部访问
--ip-range strings IP地址范围
--ipam-driver string IPAM驱动
--ipam-opt map IPAM选项
--ipv6 启用IPv6
--label list 设置标签
-o, --opt map 网络选项
--scope string 网络范围
--subnet strings 子网
使用示例:
# 创建bridge网络
docker network create mynetwork
# 指定子网和网关
docker network create \
--driver bridge \
--subnet 172.20.0.0/16 \
--gateway 172.20.0.1 \
mynetwork
# 指定IP范围
docker network create \
--driver bridge \
--subnet 172.20.0.0/16 \
--ip-range 172.20.1.0/24 \
mynetwork
# 创建overlay网络(用于Swarm)
docker network create -d overlay myoverlay
# 查看网络
docker network ls
# 查看网络详情
docker network inspect mynetwork
驱动类型:
bridge(默认):
├─ 单主机网络
├─ 容器间通信
└─ 适合单机部署
overlay:
├─ 多主机网络
├─ 跨主机容器通信
├─ 用于Docker Swarm
└─ 适合集群部署
macvlan:
├─ 容器有独立MAC地址
├─ 直接连接到物理网络
├─ 性能最优
└─ 需要网络设备支持
ipvlan:
├─ 类似macvlan
├─ 共享MAC地址
└─ 需要网络设备支持
none:
├─ 无网络
└─ 完全隔离
host:
├─ 主机网络
└─ 共享主机网络栈
基本使用:
# 创建自定义网络
docker network create mynetwork
# 创建容器并连接到网络
docker run -d --name web --net mynetwork nginx:latest
docker run -d --name app --net mynetwork myapp:latest
# 查看容器IP
docker inspect web | grep IPAddress
docker inspect app | grep IPAddress
# 进入web容器,通过容器名访问app容器
docker exec -it web bash
ping app
# PING app (172.20.0.3): 56 data bytes
# DNS解析成功!
优势:
自定义网络:
✅ 支持DNS解析
✅ 容器间可通过名称访问
✅ 动态连接和断开
✅ 网络隔离
✅ 灵活配置
docker network connect:
# 将运行中的容器连接到网络
docker network connect mynetwork mycontainer
# 指定IP地址
docker network connect --ip 172.20.0.100 mynetwork mycontainer
# 指定别名
docker network connect --alias web mynetwork mycontainer
# 查看容器连接的网络
docker inspect mycontainer | grep Networks
docker network disconnect:
# 断开容器与网络的连接
docker network disconnect mynetwork mycontainer
# 强制断开
docker network disconnect -f mynetwork mycontainer
常用选项:
# 创建网络时设置MTU
docker network create -d bridge -o com.docker.network.driver.mtu=1400 mynetwork
# 设置网络内部(禁止外部访问)
docker network create --internal mynetwork
# 设置IPv6网络
docker network create --ipv6 --subnet fd00:dead:beef::/48 mynetwork
# 设置DNS服务器
docker run -d --name mycontainer --dns 8.8.8.8 --net mynetwork nginx
# 设置DNS搜索域
docker run -d --name mycontainer --dns-search example.com --net mynetwork nginx
# 设置主机名
docker run -d --name mycontainer --hostname myhost --net mynetwork nginx
IP地址配置:
# 指定容器IP地址
docker run -d --name web --net mynetwork --ip 172.20.0.100 nginx:latest
# 指定MAC地址
docker run -d --name web --net mynetwork --mac-address 02:42:ac:14:00:64 nginx:latest
# 指定多个网络
docker run -d --name web --net network1 --net network2 nginx:latest
查看网络列表:
# 查看所有网络
docker network ls
# 输出
NETWORK ID NAME DRIVER SCOPE
a1b2c3d4e5f6 bridge bridge local
b2c3d4e5f6a7 host host local
c3d4e5f6a7b8 none null local
d4e5f6a7b8c9 mynetwork bridge local
查看网络详情:
# 查看网络配置
docker network inspect mynetwork
# 查看容器网络配置
docker inspect mycontainer | grep -A 20 "NetworkSettings"
# 查看容器端口映射
docker port mycontainer
# 查看容器IP地址
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mycontainer
进入容器测试:
# 进入容器
docker exec -it mycontainer bash
# 测试网络连接
ping 8.8.8.8
ping google.com
# 查看网络接口
ip addr
# 查看路由表
ip route
# 查看DNS解析
cat /etc/resolv.conf
nslookup google.com
# 测试端口连接
curl http://localhost:80
telnet localhost 80
从主机测试:
# 测试容器端口
curl http://localhost:8080
# 查看端口监听
netstat -tulpn | grep 8080
# 查看iptables规则
iptables -t nat -L -n
# 查看网络连接
ss -tulpn
问题排查:
# 1. 检查容器网络模式
docker inspect mycontainer | grep NetworkMode
# 2. 检查容器DNS
docker exec mycontainer cat /etc/resolv.conf
# 3. 检查主机网络
ping 8.8.8.8
# 4. 检查iptables规则
iptables -t nat -L -n
# 5. 检查IP转发
cat /proc/sys/net/ipv4/ip_forward
# 应该为1
解决方法:
# 启用IP转发
echo 1 > /proc/sys/net/ipv4/ip_forward
# 或修改配置文件
vim /etc/sysctl.conf
net.ipv4.ip_forward=1
# 应用配置
sysctl -p
# 重启Docker
systemctl restart docker
问题排查:
# 1. 检查容器是否在同一网络
docker network inspect mynetwork
# 2. 检查防火墙规则
iptables -L -n
# 3. 检查容器IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container1
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container2
# 4. 测试连通性
docker exec container1 ping container2
解决方法:
# 使用自定义网络
docker network create mynetwork
docker network connect mynetwork container1
docker network connect mynetwork container2
# 或重新创建容器
docker run -d --name container1 --net mynetwork image1
docker run -d --name container2 --net mynetwork image2
问题排查:
# 1. 检查端口映射
docker port mycontainer
# 2. 检查容器进程
docker exec mycontainer netstat -tulpn
# 3. 检查主机端口
netstat -tulpn | grep 8080
# 4. 检查iptables规则
iptables -t nat -L -n | grep 8080
解决方法:
# 检查容器内应用是否监听正确端口
docker exec mycontainer netstat -tulpn
# 检查应用配置
docker exec mycontainer cat /etc/nginx/nginx.conf
# 重新创建容器,确保端口映射正确
docker run -d -p 8080:80 --name mycontainer nginx:latest
Bridge模式:
├─ 默认模式
├─ 容器有独立IP
├─ 通过NAT访问外部
├─ 需要端口映射
└─ 推荐使用自定义bridge
Host模式:
├─ 共享主机网络
├─ 性能最优
├─ 无网络隔离
├─ 端口冲突风险
└─ 适合高性能应用
None模式:
├─ 完全网络隔离
├─ 安全性最高
├─ 无法访问外部
└─ 适合安全敏感应用
Container模式:
├─ 共享容器网络
├─ 共享IP和端口
├─ 通过localhost通信
└─ 适合紧密耦合应用
自定义网络:
├─ 支持DNS解析
├─ 灵活配置
├─ 网络隔离
└─ 推荐使用
网络管理:
├─ docker network ls:查看网络列表
├─ docker network create:创建网络
├─ docker network rm:删除网络
├─ docker network inspect:查看网络详情
├─ docker network connect:连接容器到网络
└─ docker network disconnect:断开容器与网络
网络排查:
├─ docker port:查看端口映射
├─ docker inspect:查看容器网络配置
├─ docker exec:进入容器测试网络
└─ iptables:查看防火墙规则
网络规划:
✅ 使用自定义网络
✅ 按应用类型划分网络
✅ 合理规划IP地址段
✅ 设置网络隔离
容器部署:
✅ 使用自定义网络
✅ 通过容器名访问
✅ 避免使用默认bridge
✅ 合理配置端口映射
安全建议:
✅ 使用网络隔离
✅ 限制容器间通信
✅ 配置防火墙规则
✅ 定期检查网络配置
网络性能:
✅ 高性能应用使用host模式
✅ 合理设置MTU
✅ 优化DNS配置
✅ 使用连接池
网络监控:
✅ 监控网络流量
✅ 监控网络延迟
✅ 监控网络错误
✅ 设置告警
下一章:Docker存储
将学习:
网络模式:创建三个容器,分别使用bridge、host、none网络模式,观察它们的网络配置差异。
端口映射:创建一个nginx容器,映射端口8080:80,然后在浏览器中访问。
自定义网络:创建一个自定义bridge网络,将两个容器连接到该网络,测试容器间通过名称通信。
网络隔离:创建两个自定义网络network1和network2,创建三个容器,其中两个连接到network1,一个连接到network2,测试网络隔离效果。
Container模式:创建一个nginx容器和一个调试容器,调试容器共享nginx容器的网络,测试通过localhost访问nginx。
故障排查:模拟一个容器无法访问外部网络的场景,排查并解决问题。
完整应用网络:为一个三层Web应用(前端、后端、数据库)设计网络架构,要求:
网络监控:部署一个网络监控容器,监控其他容器的网络流量和连接状态。