Docker 网络配置
核心知识点
1. Docker 网络基础
1.1 网络驱动类型
Docker 提供多种网络驱动,适用于不同的使用场景:
┌─────────────────────────────────────────────────────────────┐
│ Docker 网络驱动 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Bridge (桥接) ──> 默认模式,容器间通信 │
│ Host (主机) ──> 共享主机网络栈 │
│ None (无) ──> 独立网络,无网络访问 │
│ Overlay ──> 跨主机容器通信(集群) │
│ Macvlan ──> 直接连接物理网络 │
│ IPvlan ──> 共享物理接口 │
│ │
└─────────────────────────────────────────────────────────────┘1.2 网络架构
Docker 网络采用虚拟网桥架构:
┌─────────────────────────────────────────────────────────────┐
│ 宿主机 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ 容器 A │ │ 容器 B │ │
│ │ 172.17.0.2 │ │ 172.17.0.3 │ │
│ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │
│ └────────┬───────────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ docker0 网桥 │ 172.17.0.1 │
│ └────────┬────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ 物理网卡 eth0 │ │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘2. 网络模式详解
2.1 Bridge 模式(默认)
Bridge 模式是 Docker 的默认网络模式,容器通过虚拟网桥连接。
# 使用默认 bridge 网络运行容器
docker run -d --name web1 nginx:latest
docker run -d --name web2 nginx:latest
# 查看容器网络
docker inspect web1 | grep -A 10 NetworkSettings
# 查看网桥信息
docker network inspect bridge
# 容器间通信
docker exec web1 ping web22.2 Host 模式
Host 模式使容器共享宿主机的网络命名空间。
# 使用 host 网络模式
docker run -d --network host --name web-host nginx:latest
# 查看容器网络
docker inspect web-host | grep -A 5 NetworkMode
# 注意:端口映射在 host 模式下无效
docker run -d --network host -p 8080:80 nginx:latest
# 容器将直接监听宿主机的 80 端口2.3 None 模式
None 模式为容器创建独立的网络环境,无网络访问。
# 使用 none 网络模式
docker run -d --network none --name web-none nginx:latest
# 查看容器网络
docker inspect web-none | grep -A 5 NetworkMode
# 容器无法访问外部网络
docker exec web-none ping google.com
# ping: bad address 'google.com'3. 自定义网络
3.1 创建 Bridge 网络
# 创建自定义 bridge 网络
docker network create my-bridge
# 指定子网和网关
docker network create \
--driver bridge \
--subnet 192.168.100.0/24 \
--gateway 192.168.100.1 \
my-custom-bridge
# 创建网络时指定 IP 范围
docker network create \
--driver bridge \
--subnet 172.20.0.0/16 \
--ip-range 172.20.10.0/24 \
my-limited-bridge
# 查看网络列表
docker network ls
# 查看网络详细信息
docker network inspect my-bridge3.2 连接容器到网络
# 创建容器时指定网络
docker run -d --network my-bridge --name app1 nginx:latest
docker run -d --network my-bridge --name app2 nginx:latest
# 将现有容器连接到网络
docker run -d --name app3 nginx:latest
docker network connect my-bridge app3
# 断开容器与网络的连接
docker network disconnect my-bridge app3
# 连接时指定 IP 地址
docker network connect \
--ip 192.168.100.100 \
my-bridge \
app13.3 创建 Overlay 网络
Overlay 网络用于跨主机的容器通信(需要 Docker Swarm)。
# 初始化 Swarm
docker swarm init
# 创建 overlay 网络
docker network create \
--driver overlay \
--attachable \
my-overlay
# 在 overlay 网络上运行服务
docker service create \
--name my-service \
--network my-overlay \
nginx:latest
# 查看网络
docker network ls
docker network inspect my-overlay4. 容器间通信
4.1 通过容器名称通信
# 创建自定义网络
docker network create app-network
# 启动 Web 服务器
docker run -d \
--network app-network \
--name web-server \
nginx:latest
# 启动应用容器
docker run -d \
--network app-network \
--name app-client \
alpine:latest \
sh -c "while true; do wget -qO- http://web-server; sleep 5; done"
# 查看客户端日志
docker logs app-client
# 测试通信
docker exec app-client ping web-server4.2 通过 IP 地址通信
# 查看容器 IP 地址
docker inspect web-server | grep IPAddress
# 使用 IP 地址通信
docker exec app-client wget -qO- http://172.18.0.2
# 查看网络中的所有容器
docker network inspect app-network | grep -A 10 Containers4.3 多网络连接
# 创建两个网络
docker network create frontend
docker network create backend
# 启动数据库容器(连接到 backend 网络)
docker run -d \
--name database \
--network backend \
-e POSTGRES_PASSWORD=password \
postgres:13
# 启动应用容器(连接到两个网络)
docker run -d \
--name app \
--network frontend \
nginx:latest
docker network connect backend app
# 验证网络连接
docker inspect app | grep -A 20 Networks
# 从不同网络访问
docker exec app ping database5. 端口映射
5.1 基本端口映射
# 映射单个端口
docker run -d -p 8080:80 --name web1 nginx:latest
# 映射多个端口
docker run -d \
-p 80:80 \
-p 443:443 \
--name web2 \
nginx:latest
# 映射到随机端口
docker run -d -p 80 --name web3 nginx:latest
# 查看端口映射
docker port web1
docker ps5.2 高级端口映射
# 绑定到特定接口
docker run -d -p 127.0.0.1:8080:80 --name web-local nginx:latest
docker run -d -p 0.0.0.0:8080:80 --name web-all nginx:latest
# 映射 UDP 端口
docker run -d -p 53:53/udp --name dns-server bind9
# 映射端口范围
docker run -d -p 8000-8010:8000-8010 --name web-range nginx:latest6. DNS 配置
6.1 容器 DNS 设置
# 使用宿主机 DNS
docker run -d --dns 8.8.8.8 --name dns-custom nginx:latest
# 使用多个 DNS 服务器
docker run -d \
--dns 8.8.8.8 \
--dns 8.8.4.4 \
--name dns-multi \
nginx:latest
# 添加 DNS 搜索域
docker run -d \
--dns-search example.com \
--name dns-search \
nginx:latest
# 查看容器 DNS 配置
docker exec dns-custom cat /etc/resolv.conf6.2 自定义 DNS 服务器
# 运行 DNS 服务器
docker run -d \
--name dns-server \
-p 53:53/udp \
-p 53:53 \
andyshinn/dnsmasq
# 配置容器使用自定义 DNS
docker run -d \
--dns $(docker inspect dns-server | grep IPAddress | head -1 | awk '{print $2}' | tr -d '"') \
--name dns-client \
alpine:latest \
nslookup google.com7. 网络安全
7.1 网络隔离
# 创建隔离的网络
docker network create isolated-network
# 启动隔离的容器
docker run -d --network isolated-network --name isolated-app nginx:latest
# 尝试从其他容器访问(失败)
docker run --rm alpine:latest ping isolated-app
# ping: bad address 'isolated-app'7.2 网络访问控制
# 创建内部网络
docker network create --internal internal-network
# 启动容器
docker run -d --network internal-network --name internal-app nginx:latest
# 容器无法访问外部网络
docker exec internal-app ping google.com
# ping: bad address 'google.com'实用案例分析
案例 1:Web 应用与数据库通信
场景描述
部署一个包含 Nginx 和 PostgreSQL 的 Web 应用,实现容器间通信。
操作步骤
# 1. 创建应用网络
docker network create app-network
# 2. 启动 PostgreSQL 数据库
docker run -d \
--name postgres \
--network app-network \
-e POSTGRES_DB=myapp \
-e POSTGRES_USER=myapp \
-e POSTGRES_PASSWORD=password \
-v postgres-data:/var/lib/postgresql/data \
postgres:13
# 3. 等待数据库启动
sleep 10
# 4. 启动 Nginx Web 服务器
docker run -d \
--name nginx \
--network app-network \
-p 80:80 \
nginx:latest
# 5. 测试容器间通信
docker exec nginx ping postgres
# 6. 从 Nginx 容器测试数据库连接
docker exec nginx sh -c "apt-get update && apt-get install -y postgresql-client"
docker exec nginx psql -h postgres -U myapp -d myapp -c "SELECT version();"
# 7. 查看网络配置
docker network inspect app-network
# 8. 清理
docker stop nginx postgres
docker rm nginx postgres
docker network rm app-network案例 2:多网络架构
场景描述
创建前端、后端和数据库三层架构,使用不同的网络进行隔离。
操作步骤
# 1. 创建网络
docker network create frontend
docker network create backend
docker network create database
# 2. 启动数据库(仅连接到 database 网络)
docker run -d \
--name mysql \
--network database \
-e MYSQL_ROOT_PASSWORD=rootpassword \
-e MYSQL_DATABASE=myapp \
-v mysql-data:/var/lib/mysql \
mysql:5.7
# 3. 启动后端应用(连接到 backend 和 database 网络)
docker run -d \
--name backend \
--network backend \
-e DB_HOST=mysql \
-e DB_PASSWORD=rootpassword \
node:16-alpine \
node server.js
docker network connect database backend
# 4. 启动前端应用(连接到 frontend 和 backend 网络)
docker run -d \
--name frontend \
--network frontend \
-p 80:80 \
nginx:latest
docker network connect backend frontend
# 5. 验证网络连接
docker inspect backend | grep -A 30 Networks
# 6. 测试通信
docker exec frontend ping backend
docker exec backend ping mysql
# 7. 查看网络拓扑
docker network ls
docker network inspect frontend
docker network inspect backend
docker network inspect database
# 8. 清理
docker stop frontend backend mysql
docker rm frontend backend mysql
docker network rm frontend backend database案例 3:端口映射与负载均衡
场景描述
运行多个 Web 容器,通过端口映射实现负载均衡。
操作步骤
# 1. 启动多个 Web 容器
docker run -d --name web1 -p 8081:80 nginx:latest
docker run -d --name web2 -p 8082:80 nginx:latest
docker run -d --name web3 -p 8083:80 nginx:latest
# 2. 查看端口映射
docker port web1
docker port web2
docker port web3
# 3. 测试访问
curl http://localhost:8081
curl http://localhost:8082
curl http://localhost:8083
# 4. 创建负载均衡器
docker run -d \
--name lb \
-p 80:80 \
nginx:latest
# 5. 配置负载均衡
docker exec lb sh -c "cat > /etc/nginx/conf.d/lb.conf << 'EOF'
upstream backend {
server web1:80;
server web2:80;
server web3:80;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
EOF"
# 6. 连接网络
docker network connect app-network lb
docker network connect app-network web1
docker network connect app-network web2
docker network connect app-network web3
# 7. 重启负载均衡器
docker restart lb
# 8. 测试负载均衡
for i in {1..10}; do
curl -s http://localhost | grep -o "Welcome to nginx"
done
# 9. 清理
docker stop lb web1 web2 web3
docker rm lb web1 web2 web3
docker network rm app-network最佳实践
使用自定义网络:避免使用默认的 bridge 网络,提高网络隔离性。
合理规划网络架构:根据应用需求选择合适的网络模式。
使用有意义的网络名称:便于识别和管理网络。
定期清理未使用的网络:释放系统资源。
# 清理未使用的网络
docker network prune
# 查看所有网络
docker network ls
# 查看网络详细信息
docker network inspect network-name- 监控网络流量:及时发现网络问题。
# 查看容器网络统计
docker stats --no-stream
# 使用 tcpdump 抓包
docker exec container-name tcpdump -i eth0- 使用 DNS 服务发现:避免硬编码 IP 地址。
# 使用容器名称而非 IP 地址
docker exec app1 ping app2总结
本教程详细介绍了 Docker 网络的配置方法,包括网络模式、自定义网络、容器间通信、端口映射等。通过实际案例,我们学习了如何构建多网络架构、实现负载均衡以及配置 DNS。掌握这些技能后,可以设计和管理复杂的 Docker 网络架构。