Skip to main content
Version: 中文

Docker 网络配置

Docker 网络模式

Docker 提供了多种网络模式,用于容器之间以及容器与外部网络的通信。

网络模式类型

网络模式说明使用场景
bridge桥接模式(默认)适用于同一主机上的容器通信
host主机模式容器与主机共享网络命名空间
none无网络模式容器没有网络配置
container容器模式与其他容器共享网络
自定义网络用户自定义网络更灵活的网络配置

Bridge 桥接模式

Bridge 是 Docker 的默认网络模式,容器通过虚拟网桥与外部通信。

特点

  • Docker 启动时会创建一个名为 docker0 的虚拟网桥
  • 每个容器都会被分配一个独立的 IP 地址
  • 容器可以通过 docker0 网桥与其他容器通信
  • 需要通过端口映射才能从外部访问容器

使用示例

# 使用默认 bridge 网络运行容器
docker run -d --name web1 nginx

# 查看容器的网络信息
docker inspect web1

# 查看 bridge 网络详情
docker network inspect bridge

端口映射

# 映射单个端口
docker run -d -p 8080:80 --name web nginx

# 映射多个端口
docker run -d -p 8080:80 -p 8443:443 --name web nginx

# 映射所有端口(随机映射)
docker run -d -P --name web nginx

# 指定 IP 地址映射
docker run -d -p 192.168.1.100:8080:80 --name web nginx

Host 主机模式

容器与主机共享网络命名空间,容器没有独立的 IP 地址。

特点

  • 容器直接使用主机的网络
  • 不需要进行端口映射
  • 网络性能最好
  • 端口可能会冲突

使用示例

# 使用 host 网络模式
docker run -d --network host --name web nginx

# 此时容器直接使用主机的 80 端口,无需映射

适用场景

  • 需要高性能网络的应用
  • 需要访问主机网络资源的应用
  • 网络监控工具

None 无网络模式

容器没有网络配置,完全隔离的网络环境。

使用示例

# 使用 none 网络模式
docker run -d --network none --name isolated alpine sleep 3600

适用场景

  • 需要完全隔离网络的应用
  • 安全性要求极高的场景

Container 模式

与指定的容器共享网络命名空间。

使用示例

# 先启动一个容器
docker run -d --name web1 nginx

# 新容器共享 web1 的网络
docker run -d --network container:web1 --name web2 nginx

特点

  • 两个容器共享同一个网络命名空间
  • 共享 IP 地址和端口范围
  • 可以通过 localhost 相互访问

自定义网络

创建用户自定义网络,提供更灵活的网络配置。

创建自定义网络

# 创建 bridge 类型的自定义网络
docker network create mynet

# 指定网络驱动和子网
docker network create --driver bridge --subnet 172.18.0.0/16 --gateway 172.18.0.1 mynet

# 查看网络列表
docker network ls

# 查看网络详情
docker network inspect mynet

使用自定义网络

# 在自定义网络中运行容器
docker run -d --name web1 --network mynet nginx

# 在同一网络中运行另一个容器
docker run -d --name web2 --network mynet nginx

# 容器之间可以通过容器名相互访问
docker exec -it web1 ping web2

连接和断开网络

# 将运行中的容器连接到网络
docker network connect mynet 容器名

# 断开容器与网络的连接
docker network disconnect mynet 容器名

# 一个容器可以连接多个网络
docker network connect network1 容器名
docker network connect network2 容器名

网络配置实战

实战一:搭建应用和数据库网络

# 1. 创建应用网络
docker network create app-network

# 2. 启动 MySQL 数据库
docker run -d \
--name mysql \
--network app-network \
-e MYSQL_ROOT_PASSWORD=root123 \
-e MYSQL_DATABASE=myapp \
mysql:5.7

# 3. 启动应用容器
docker run -d \
--name myapp \
--network app-network \
-p 8080:8080 \
-e DB_HOST=mysql \
-e DB_PORT=3306 \
-e DB_NAME=myapp \
myapp:latest

# 应用可以通过 mysql:3306 访问数据库

实战二:前后端分离架构

# 1. 创建前端网络
docker network create frontend

# 2. 创建后端网络
docker network create backend

# 3. 启动数据库(只在后端网络)
docker run -d \
--name postgres \
--network backend \
-e POSTGRES_PASSWORD=password \
postgres:13

# 4. 启动后端 API(连接前后端网络)
docker run -d \
--name api \
--network backend \
-e DB_HOST=postgres \
api:latest

docker network connect frontend api

# 5. 启动前端应用(只在前端网络)
docker run -d \
--name web \
--network frontend \
-p 80:80 \
-e API_URL=http://api:8080 \
web:latest

# 前端可以访问 API,但不能直接访问数据库

实战三:使用 Docker Compose 配置网络

创建 docker-compose.yml 文件:

version: '3'

services:
web:
image: nginx:latest
ports:
- "80:80"
networks:
- frontend
depends_on:
- api

api:
image: myapi:latest
networks:
- frontend
- backend
environment:
- DB_HOST=db
depends_on:
- db

db:
image: mysql:5.7
networks:
- backend
environment:
- MYSQL_ROOT_PASSWORD=root123
- MYSQL_DATABASE=myapp
volumes:
- db_data:/var/lib/mysql

networks:
frontend:
driver: bridge
backend:
driver: bridge

volumes:
db_data:

启动服务:

docker-compose up -d

网络故障排查

查看容器网络配置

# 查看容器 IP 地址
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 容器名

# 查看容器所有网络信息
docker inspect 容器名 | grep -A 20 NetworkSettings

# 查看容器连接的网络
docker inspect 容器名 | grep -A 10 Networks

测试容器网络连通性

# 进入容器测试网络
docker exec -it 容器名 /bin/bash

# 在容器内测试连通性
ping 目标地址
curl http://目标地址
telnet 目标地址 端口

# 测试 DNS 解析
nslookup 域名
dig 域名

查看端口映射

# 查看容器端口映射
docker port 容器名

# 查看所有容器的端口映射
docker ps --format "table {{.Names}}\t{{.Ports}}"

抓包分析

# 在主机上抓取容器网络包
docker run --rm --net=container:容器名 nicolaka/netshoot tcpdump -i eth0

# 使用 nsenter 进入容器网络命名空间
PID=$(docker inspect -f '{{.State.Pid}}' 容器名)
nsenter -t $PID -n tcpdump -i eth0

网络性能优化

使用 Host 网络模式

对于性能要求高的应用,使用 host 网络模式:

docker run -d --network host 镜像名

调整 MTU 值

# 创建网络时指定 MTU
docker network create --opt com.docker.network.driver.mtu=1450 mynet

使用 Overlay 网络

对于跨主机通信,使用 overlay 网络:

# 创建 overlay 网络(需要 Swarm 模式)
docker network create --driver overlay --attachable my-overlay-net

安全配置

网络隔离

# 创建隔离的网络
docker network create --internal secure-net

# 在隔离网络中运行容器(无法访问外网)
docker run -d --network secure-net 镜像名

禁用容器间通信

# 创建禁止容器间通信的网络
docker network create --opt com.docker.network.bridge.enable_icc=false isolated-net

限制网络带宽

# 限制容器的网络带宽
docker run -d --network-alias web --net mynet \
--memory 512m \
--cpus 0.5 \
nginx

常见问题

容器无法访问外网

检查 DNS 配置:

# 运行容器时指定 DNS
docker run -d --dns 8.8.8.8 --dns 114.114.114.114 镜像名

# 或在 daemon.json 中配置
{
"dns": ["8.8.8.8", "114.114.114.114"]
}

端口冲突

# 使用随机端口
docker run -d -P 镜像名

# 或使用不同的端口
docker run -d -p 8081:80 镜像名

网络删除失败

# 查看网络被哪些容器使用
docker network inspect 网络名

# 先删除或断开相关容器
docker network disconnect 网络名 容器名

# 再删除网络
docker network rm 网络名