15.6.2 默认网络与自定义网络

默认网络类型与特点#

默认网络驱动是 bridge/host/none。以下为核心特点与适用场景:

文章图片
  • bridge:默认网络,容器通过虚拟网桥 docker0 通信,适合单机多容器;支持端口映射对外提供服务。
  • host:容器共享宿主机网络栈,无隔离,性能高但端口冲突风险大。
  • none:无网络连接,适合高安全隔离或自定义网络需求。

命令解释示例:

# 列出网络列表,查看默认网络类型
docker network ls
# 预期:能看到 bridge / host / none 三个网络

默认网络的创建与查看#

默认网络由 Docker 安装后自动创建,以下命令用于查看与理解其结构:

# 查看默认桥接网络详情(子网、网关、容器接入情况)
docker network inspect bridge

# 查看容器网络信息
docker inspect nginx-demo --format '{{json .NetworkSettings}}' | jq .

# 查看宿主机网桥与veth设备
ip a
bridge link

常见输出重点说明:
- Subnet/Gateway:决定默认桥接网络 IP 段
- Containers:列出已连接到该网络的容器
- veth:容器与 docker0 的虚拟网卡对

默认网络的通信机制#

  • 容器通过 veth pair 接入 docker0,同桥接网络容器可直接互通。
  • 不同默认网络之间不互通,需通过端口映射或外部路由实现访问。
  • DNS 解析:默认仅通过容器 IP 访问,容器名解析在自定义网络中更友好。

通信验证示例:

# 启动两个容器(默认 bridge 网络)
docker run -d --name c1 busybox:1.36 sleep 3600
docker run -d --name c2 busybox:1.36 sleep 3600

# 查看 c1 与 c2 的IP
docker inspect c1 --format '{{.NetworkSettings.IPAddress}}'
docker inspect c2 --format '{{.NetworkSettings.IPAddress}}'

# 从 c1 ping c2
docker exec c1 ping -c 2 $(docker inspect c2 --format '{{.NetworkSettings.IPAddress}}')

预期效果: ping 成功,说明 bridge 内互通。

自定义网络的优势#

  • 支持容器名解析(内置 DNS)
  • 更好的隔离性与分段管理
  • 可自定义子网、网关、IP 段
  • 易于组织微服务与多环境

自定义网络的创建与使用#

# 创建桥接网络
docker network create --driver bridge my_net

# 指定网段与网关
docker network create --subnet 172.20.0.0/16 --gateway 172.20.0.1 my_net

# 运行容器并加入网络
docker run -d --name app1 --network my_net nginx:1.25
docker run -d --name app2 --network my_net busybox:1.36 sleep 3600

# 连接已有容器到网络
docker network connect my_net c1

# 断开网络
docker network disconnect my_net c1

命令解释:
- --subnet:指定自定义网段
- --gateway:指定网关 IP
- --network:将容器加入指定网络

容器间通信示例#

# app2 通过容器名访问 app1(自定义网络内置DNS)
docker exec app2 ping -c 2 app1

# app2 访问 app1 的 Nginx 服务
docker exec app2 wget -qO- http://app1:80 | head -n 2

预期效果: ping 成功,wget 返回 Nginx 默认页面片段。

常见问题与运维建议#

1) 端口冲突#

现象: 宿主机端口已占用,容器映射失败
排错:

# 查看端口占用
ss -lntp | grep 80

# 重新映射端口
docker run -d --name web1 -p 8080:80 nginx:1.25

2) IP 冲突#

现象: 容器无法访问外网或互通异常
排错与建议:

# 检查默认网段
docker network inspect bridge --format '{{(index .IPAM.Config 0).Subnet}}'

# 创建新的网段规避冲突
docker network create --subnet 172.30.0.0/16 my_net2

3) DNS 解析失败#

现象: 容器名无法解析
排错:

# 容器名解析只在自定义网络有效
docker network ls
docker inspect app2 --format '{{json .NetworkSettings.Networks}}' | jq .

# 连接到自定义网络后重试
docker network connect my_net app2
docker exec app2 ping -c 2 app1

4) 无用网络清理#

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

练习与实战#

  1. 创建一个自定义网段 172.21.0.0/16 的网络 dev_net,启动两个容器互相 ping。
  2. 在默认 bridge 上启动容器,尝试用容器名访问另一个容器并解释原因。
  3. 设计一个端口映射方案,将容器 nginx 映射到宿主机 8081,并用 curl 验证。
  4. 故意创建与宿主机网段冲突的网络,观察网络异常并修复。