Docker Network 深入理解与应用

🐳 Docker Network 网络笔记

一、Docker 网络基础概念

Docker 容器之间通信依赖 网络驱动(Network Drivers),它定义了容器如何与宿主机、其他容器、外部世界通信。

Docker 网络的核心命令:

docker network ls           # 查看所有网络
docker network inspect xxx  # 查看某个网络详情
docker network create xxx   # 创建网络
docker network rm xxx       # 删除网络

二、Docker 默认网络类型

安装 Docker 后,默认存在以下网络:

网络名称 类型 (Driver) 说明
bridge bridge 默认网络,用于容器间通信(同主机)
host host 共享主机网络命名空间
none null 无网络连接(完全隔离)

1️⃣ bridge 网络(默认)

  • 每个容器获得一个独立的 IP(通过 docker0 虚拟网桥)
  • 容器间可通过 容器名互相访问(同一自定义网络)
  • 宿主机可通过端口映射访问容器
docker run -d --name web1 --network bridge nginx
docker run -d --name web2 --network bridge nginx

❗默认 bridge 网络中,容器名 不自动解析为 IP,推荐使用 自定义 bridge 网络

使用docker run创建Docker容器时,可以用 --net 或 --network 选项指定容器的网络模式

image-20251108092749130

自定义 bridge 网络示例

docker network create mynet
docker run -d --name c1 --network mynet nginx
docker run -it --rm --network mynet busybox ping c1

➡ 自定义网络中,容器名会自动解析为 IP(DNS 支持)。


2️⃣ host 网络

  • 容器共享宿主机的网络栈(IP、端口等)
  • 无法再使用 -p 端口映射
  • 性能最好,但隔离性最低
docker run --network host nginx

用于性能要求高或需直接访问宿主机网络的场景。

2.1 基本原理

Host 网络模式 下,容器 不会再创建独立的网络命名空间 (Network Namespace),而是与宿主机共用同一个网络栈。

也就是说:

  • 容器不会再虚拟出自己的网卡(如 eth0
  • 容器不会再分配独立的 IP 地址
  • 容器直接使用宿主机的 IP 和端口范围
  • 容器与宿主机共用同一个 Network Namespace

但是,文件系统、进程、用户空间等仍然与宿主机隔离

image-20251108093310549

2.2 使用方式

docker run -d --network host --name webhost nginx

或简写为:

docker run -d --net=host nginx

此时:

  • 容器内 ifconfigip addr 看到的网络接口与宿主机完全相同
  • 容器监听的端口即宿主机的端口,无需再做端口映射 (-p 无效)

2.3 通信特性

  • 容器内的服务可通过宿主机 IP 直接被外部访问
  • 宿主机和容器之间 无 NAT 转换过程
  • 网络性能最佳(无虚拟化层转发损耗)
  • 但网络隔离性最差(共享网络环境)

❗容器使用 host 模式时,如果宿主机端口已被占用,则无法在容器中再次使用同一端口。

2.4 优势与适用场景

优势:

  • 网络性能最优(无桥接、无 NAT)
  • 无需端口映射,直接使用宿主机 IP 通信
  • 解决了容器 IP 地址动态变化导致的访问不稳定问题

适用场景:

  • 高性能网络服务(如负载均衡、监控探针等)
  • 需要与宿主机共用网络环境的容器
  • 不希望通过端口映射暴露端口的部署场景

3️⃣ none 网络

  • 容器完全无网络连接
  • 仅保留 loopback 接口(127.0.0.1)
  • 用于自定义网络配置或安全隔离
docker run -it --network none busybox

三、Docker 自定义网络

Docker 支持多种网络驱动:

驱动类型 说明
bridge 默认本地主机桥接
host 使用宿主机网络
none 无网络
overlay 跨主机网络(Docker Swarm)
macvlan 为容器分配宿主机子网内真实 IP
ipvlan 类似 macvlan,但更轻量

🧱 自定义 bridge 网络示例

# 创建网络
docker network create --driver bridge mynet

# 查看网络详情
docker network inspect mynet

添加容器到网络

docker run -d --name web --network mynet nginx
docker run -it --name client --network mynet busybox ping web

🌐 macvlan 网络示例(让容器拥有独立 IP)

docker network create -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 my-macvlan

容器会直接出现在物理网络中,可被局域网设备直接访问。


四、容器网络连接与断开

docker network connect <network> <container>
docker network disconnect <network> <container>

示例:

docker network connect mynet web
docker network disconnect bridge web

五、Docker Compose 中的网络

docker-compose.yml 中定义网络:

version: '3'
services:
  web:
    image: nginx
    networks:
      - mynet

  db:
    image: mysql
    networks:
      - mynet

networks:
  mynet:
    driver: bridge

同一网络下的服务可通过 服务名互相访问


六、常用命令速查表

功能 命令
查看所有网络 docker network ls
查看网络详情 docker network inspect <name>
创建网络 docker network create <name>
删除网络 docker network rm <name>
连接容器到网络 docker network connect <net> <container>
从网络断开容器 docker network disconnect <net> <container>

七、Docker 网络原理总结

🧩 Tomcat 示例理解

假设我们运行两个容器:

docker run -d --name tomcat01 tomcat
docker run -d --name tomcat02 tomcat
  • tomcat01tomcat02 公用同一个“虚拟路由器” —— docker0
  • 未指定网络的容器 默认都会连接到 docker0 网桥
  • Docker 会自动给每个容器分配一个可用的私有 IP(通常是 172.17.x.x
  • 容器之间可以通过该虚拟网桥互相通信(同一主机内)

🌉 Docker 默认网络的本质

Docker 使用的是 Linux 的桥接网络(Bridge)机制
宿主机中存在一个 虚拟网桥接口 docker0,它就像一个隐藏的虚拟交换机:

  • 每当创建一个容器,Docker 会自动创建一对 虚拟网卡(veth pair)
  • 一端放在容器内(命名如 eth0),另一端放入宿主机上并连接到 docker0
  • 当容器删除时,相关虚拟网卡也会一并删除

容器之间通信流程:

[容器1 eth0] ⇄ [veth pair] ⇄ [docker0] ⇄ [veth pair] ⇄ [容器2 eth0]

宿主机访问容器:

[宿主机网络栈] ⇄ [docker0 网桥] ⇄ [容器 eth0]

🧱 Docker 自定义网络的底层原理

  • Docker 通过 Linux 虚拟网桥 (bridge) 实现容器间互通
  • 网桥属于 数据链路层设备(但 Linux 可为其分配 IP,因此也具备三层能力)
  • 相当于拥有了一块“隐藏的虚拟网卡”,可以作为路由或交换设备使用
  • 每个自定义网络都会对应宿主机上的一个独立虚拟网桥(如 br-xxxxxx
# 查看宿主机所有网桥
brctl show

⚙️ Bridge 模式与端口映射

  • bridge 模式是 Docker 的默认网络模式
  • 若未显式指定 --network,默认使用 --network bridge
  • 当使用 -p 映射端口时,Docker 实际在 iptables 的 NAT 表 中添加了 DNAT 规则,实现端口转发
docker run -d -p 8080:8080 tomcat

查看 NAT 规则:

iptables -t nat -vnL

端口映射过程:

外部访问: 宿主机IP:8080
     ↓ (iptables DNAT 转发)
容器内服务: 172.17.0.x:8080

🧠 小结

  • Docker 默认使用 Linux bridge 桥接机制 实现容器互联
  • docker0 是 Docker 默认创建的虚拟网桥,相当于“共享路由器”
  • 不指定网络时,容器会自动连接到 docker0 并分配 IP
  • 使用 -p 时通过 iptables DNAT 实现宿主机端口映射
  • 删除容器时,其对应的虚拟网卡接口(veth pair)会自动销毁
  • 自定义网络(bridge/overlay/macvlan)本质上是创建新的虚拟网桥或网络命名空间

🧭 一句话记忆:

Docker 网络的核心在于 Linux 虚拟网桥,docker0 是默认的桥,veth pair 是连接容器与宿主机的“数据线”。


八、总结对比

网络类型 是否隔离 是否支持容器名解析 可跨主机通信 适用场景
bridge(默认) 单机容器通信
自定义 bridge 单机容器互访
host - 高性能网络需求
none - 安全隔离
overlay Swarm/多主机集群
macvlan 容器需要独立局域网 IP 时

📚 参考命令实战

# 1. 创建网络
docker network create mynet

# 2. 启动容器并加入网络
docker run -d --name nginx1 --network mynet nginx

# 3. 测试互通
docker run -it --rm --network mynet busybox ping nginx1

📘 补充说明

  • 容器名解析通过 内置 DNS(127.0.0.11) 完成
  • 可使用 docker network prune 清理未使用网络
  • 自定义网络更推荐使用,因为默认 bridge 网络中容器名不解析

🧩 推荐实践

  • 为每个项目创建独立的自定义网络
  • 在 Compose 文件中定义网络,统一管理
  • 生产环境建议使用 overlaymacvlan