Skip to content

网络管理

Docker 的网络功能允许容器之间以及容器与外部世界进行通信。本节介绍 Docker 网络的基础知识和常用操作。

Docker 网络模式

Docker 提供以下几种内置网络驱动:

模式说明适用场景
bridge默认模式,通过虚拟网桥通信单主机容器间通信
host容器直接使用宿主机网络高性能场景
none无网络,完全隔离安全隔离
overlay跨主机容器网络Swarm 集群
macvlan容器获得真实 MAC 地址与物理网络直接集成

查看网络

bash
# 列出所有网络
docker network ls

# 查看网络详情
docker network inspect bridge

# 查看容器的网络配置
docker inspect my-container --format '{{json .NetworkSettings}}' | python3 -m json.tool

默认存在的网络:

NETWORK ID     NAME      DRIVER    SCOPE
abc123         bridge    bridge    local
def456         host      host      local
ghi789         none      null      local

bridge 网络(默认)

默认 bridge 网络

不指定网络时,容器默认连接到 bridge 网络(docker0 网桥):

bash
# 运行两个容器,观察网络
docker run -d --name container1 alpine sleep 3600
docker run -d --name container2 alpine sleep 3600

# 查看 IP 地址
docker inspect container1 --format '{{.NetworkSettings.IPAddress}}'
# 输出:172.17.0.2

docker inspect container2 --format '{{.NetworkSettings.IPAddress}}'
# 输出:172.17.0.3

默认 bridge 网络的限制:容器间只能通过 IP 地址互访,不能通过容器名称互访。

端口映射

bash
# 将容器 80 端口映射到宿主机 8080 端口
docker run -d -p 8080:80 nginx

# 绑定到指定 IP
docker run -d -p 127.0.0.1:8080:80 nginx

# 随机端口映射(宿主机随机选择端口)
docker run -d -p 80 nginx

# 映射所有暴露的端口
docker run -d -P nginx

# 查看端口映射
docker port my-nginx

用户定义网络(推荐)

创建自定义网络是容器通信的最佳实践,容器可以通过名称互相访问:

创建自定义网络

bash
# 创建 bridge 网络
docker network create my-network

# 创建时指定子网和网关
docker network create \
  --driver bridge \
  --subnet 172.20.0.0/16 \
  --gateway 172.20.0.1 \
  my-network

# 查看创建的网络
docker network inspect my-network

将容器加入自定义网络

bash
# 创建时指定网络
docker run -d --name web --network my-network nginx
docker run -d --name db --network my-network mysql:8.0 -e MYSQL_ROOT_PASSWORD=secret

# 容器间通过名称访问
docker exec web ping db  # db 可以直接通过名称解析

# 已运行的容器加入网络
docker network connect my-network existing-container

验证容器间通信

bash
# 进入 web 容器
docker exec -it web sh

# 通过容器名称 ping db
ping db
# 通过服务名访问 MySQL
mysql -h db -u root -p

断开网络连接

bash
# 从网络断开容器
docker network disconnect my-network container1

# 删除网络
docker network rm my-network

# 删除所有未使用的网络
docker network prune

host 网络

容器直接使用宿主机的网络命名空间,性能最高但隔离性最差:

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

# 此时容器使用宿主机的 80 端口,无需 -p 映射
curl localhost:80

注意:host 网络模式在 macOS 和 Windows 的 Docker Desktop 上不生效,因为容器运行在 Linux VM 中。

none 网络

容器无任何网络接口,完全与外界隔离:

bash
# 使用 none 网络
docker run -it --network none alpine sh

# 在容器内验证
ip addr
# 只有 lo 回环接口,没有 eth0

DNS 解析

Docker 为用户定义网络提供内置 DNS 服务:

bash
# 在自定义网络中,容器可以通过名称解析
docker network create app-net
docker run -d --name api --network app-net myapi
docker run -d --name web --network app-net myweb

# web 容器可以通过 "api" 名称访问 api 容器
# 例如:http://api:3000/health

# 也可以通过 --network-alias 设置别名
docker run -d --name db --network app-net \
  --network-alias database \
  mysql:8.0

# 其他容器可以通过 "database" 访问

实际案例:前后端 + 数据库

bash
# 创建应用网络
docker network create webapp-net

# 启动数据库
docker run -d \
  --name mysql \
  --network webapp-net \
  -e MYSQL_ROOT_PASSWORD=secret \
  -e MYSQL_DATABASE=myapp \
  -v mysql-data:/var/lib/mysql \
  mysql:8.0

# 启动后端 API(只暴露给内部网络)
docker run -d \
  --name api \
  --network webapp-net \
  -e DB_HOST=mysql \
  -e DB_PASSWORD=secret \
  myapp-api:latest

# 启动 Nginx(对外暴露)
docker run -d \
  --name nginx \
  --network webapp-net \
  -p 80:80 \
  -v ./nginx.conf:/etc/nginx/conf.d/default.conf:ro \
  nginx

Nginx 配置(反向代理到后端):

nginx
server {
    listen 80;
    
    location /api {
        proxy_pass http://api:3000;
    }
    
    location / {
        root /usr/share/nginx/html;
    }
}

常用网络命令汇总

bash
# 列出网络
docker network ls

# 创建网络
docker network create my-net

# 查看网络详情
docker network inspect my-net

# 连接容器到网络
docker network connect my-net container1

# 断开容器的网络连接
docker network disconnect my-net container1

# 删除网络
docker network rm my-net

# 清理未使用的网络
docker network prune

总结

  • 默认 bridge 网络:容器只能通过 IP 互访,不推荐用于容器间通信
  • 用户定义网络:支持通过容器名称互访,是最佳实践
  • host 网络:高性能但无隔离,慎用
  • 端口映射:通过 -p 将容器端口暴露给外部

在实际项目中,推荐为每个应用创建独立的用户定义网络,使用容器名称进行服务发现,通过 -p 只暴露必要的端口。

下一节介绍如何编写 Dockerfile 构建自定义镜像。