目录

一、Docker 网络的底层技术支撑

1. 网络命名空间(Network Namespace, net ns)

2. 虚拟网桥(Bridge)

3. 虚拟以太网设备对(veth pair)

4. iptables(网络地址转换与流量控制)

二、Docker 核心网络模式

1. Host 模式(共享宿主机网络)

2. Container 模式(共享其他容器网络)

3. None 模式(完全无网络)

4. Bridge 模式(默认桥接模式)

三、Bridge 模式深度解析(核心重点)

1. 网桥docker0的初始化与容器接入

2. 端口映射的底层实现(iptables 规则)

3. 多容器通信与外部访问流程

(1)同一宿主机内容器通信

(2)容器访问外部网络(如访问百度)

(3)外部网络访问容器(如远程访问容器内 MySQL)

四、Docker 网络扩展(超出自定义桥接与跨主机通信)

1. 自定义网桥(推荐生产使用)

2. Overlay 网络(跨主机容器通信)

3. Macvlan 网络(容器模拟物理设备)

五、Docker 网络管理常用命令

六、常见 Docker 网络问题排查

1. 容器无法访问外部网络

2. 外部无法访问容器端口

3. 容器间无法通信

总结


Docker 网络的核心目标是实现容器间通信、容器与宿主机通信、容器与外部网络通信,同时保证网络隔离性。其底层依赖 Linux 内核的网络技术,上层通过灵活的网络模式适配不同场景,最终形成高效、可扩展的网络架构。

一、Docker 网络的底层技术支撑

Docker 网络的实现并非完全独立开发,而是基于 Linux 内核提供的原生网络能力封装而来,核心依赖以下 4 类技术:

1. 网络命名空间(Network Namespace, net ns)

  • 作用:实现网络资源的隔离,是 Docker 网络隔离的基础。每个容器启动时,Docker 会为其创建一个独立的net ns,容器内的进程只能看到该命名空间内的网络设备(如网卡、路由表、ARP 缓存、iptables 规则),与宿主机及其他容器的net ns完全隔离。
  • 关键特性
    • 宿主机默认有一个全局net ns,所有未指定net ns的进程均属于此空间;
    • 容器的net ns内仅默认包含lo(回环接口),需额外配置网卡、IP 等才能通信;
    • 通过ip netns命令可直接操作命名空间(如ip netns list查看所有net ns)。

2. 虚拟网桥(Bridge)

  • 作用:相当于软件模拟的 “交换机”,用于连接多个网络设备(如容器的虚拟网卡),实现设备间的数据包转发。
  • 默认网桥docker0:Docker 启动时会自动创建docker0网桥(默认 IP 为172.17.0.1/16),是 Bridge 模式下容器的默认 “网关接入点”。所有使用默认网络的容器,最终都会通过虚拟网卡连接到docker0。
  • 操作工具:通过brctl show(需安装bridge-utils工具)可查看网桥及挂载的设备,例如:
  • brctl show
    # 输出示例:docker0 网桥挂载多个 veth 设备(对应容器)
    bridge name     bridge id               STP enabled     interfaces
    docker0         8000.aa23df03d06c       no              veth3e267bc
                                                            veth45f0d47
    

3. 虚拟以太网设备对(veth pair)

  • 作用:类似一根 “虚拟网线”,由两个相互关联的虚拟网卡组成,一端接入容器的net ns,另一端挂载到宿主机的网桥(如docker0),是容器与网桥通信的 “物理通道”。
  • 工作流程
    1. 容器启动时,Docker 创建一对veth pair(如vethxxx和eth0);
    2. 将eth0放入容器的net ns,作为容器的默认网卡;
    3. 将vethxxx挂载到docker0网桥,完成容器与网桥的连接。

4. iptables(网络地址转换与流量控制)

  • 作用:负责 Docker 网络的地址转换(NAT)、端口映射、流量过滤,是容器与外部网络通信的核心 “路由规则”。
  • 核心链与规则
    • PREROUTING 链(DNAT):实现 “端口映射”,将宿主机端口的请求转发到容器 IP: 端口(如将宿主机8080端口转发到容器172.17.0.2:80);
    • POSTROUTING 链(SNAT):实现 “出口地址伪装”,容器访问外部网络时,将数据包的源 IP(容器 IP)替换为宿主机 IP,确保回程流量能正确返回;
    • FORWARD 链:控制容器间、容器与宿主机的数据包转发权限,默认允许同一网桥内的容器通信。

二、Docker 核心网络模式

Docker 提供 4 种原生网络模式,分别适配 “隔离”“共享”“无网络” 等不同场景,可通过docker run --network <模式>指定,默认使用bridge模式。

1. Host 模式(共享宿主机网络)

原理

容器不创建独立的net ns,直接复用宿主机的net ns—— 即容器的 IP、端口、路由表、网卡均与宿主机完全一致,无任何网络隔离。

特点

  • 优势:网络性能最优(无虚拟网络转发开销),无需端口映射,容器可直接使用宿主机的端口;
  • 劣势:无网络隔离,容器端口会占用宿主机端口(可能冲突),容器内的网络操作会影响宿主机。

操作示例

# 启动nginx容器,使用host模式
docker run -d --network host --name nginx-host nginx

# 宿主机直接访问127.0.0.1:80(容器使用宿主机80端口)
curl http://127.0.0.1:80  # 可正常返回nginx默认页面
适用场景
  • 对网络性能要求极高的服务(如高并发 API、实时数据流处理);
  • 无需网络隔离,且希望简化端口配置的场景(如单机测试)。

2. Container 模式(共享其他容器网络)

原理

新创建的容器不单独创建net ns,而是共享另一个已存在容器的net ns—— 两者共享 IP、端口、路由表,可通过localhost直接通信,且与宿主机网络隔离。

特点

  • 优势:容器间通信高效(localhost无网络转发),避免端口暴露到宿主机,安全性更高;
  • 劣势:共享网络的容器生命周期绑定(若被共享的容器停止,新容器网络会失效)。

操作示例

# 1. 先启动一个基础容器(如nginx,作为网络共享源)
docker run -d --name nginx-base nginx

# 2. 启动新容器,共享nginx-base的网络
docker run --network container:nginx-base --name alpine-share alpine ping localhost

# 输出示例:alpine容器可通过localhost ping通nginx-base的网络
PING localhost (::1): 56 data bytes
64 bytes from ::1: seq=0 ttl=64 time=0.021 ms
适用场景
  • 容器间需紧密协作的场景(如 “应用容器 + 日志收集容器”“前端容器 + 后端容器”);
  • 需避免端口暴露到宿主机,且简化容器间通信的场景。

3. None 模式(完全无网络)

原理

容器创建独立的net ns,但仅保留lo(回环接口),不配置任何物理 / 虚拟网卡、IP、路由 —— 容器无法与宿主机、其他容器或外部网络通信,仅能通过lo接口实现内部进程通信。

特点

  • 优势:网络隔离性最强,彻底避免网络攻击风险;
  • 劣势:无外部通信能力,仅支持本地任务。

操作示例

# 启动alpine容器,使用none模式
docker run --network none --name alpine-none alpine ip addr

# 输出仅包含lo接口(无eth0等网卡)
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
适用场景
  • 无需网络的本地任务(如数据清洗、文件加密、离线计算);
  • 安全性要求极高的场景(如处理敏感数据,禁止任何网络访问)。

4. Bridge 模式(默认桥接模式)

Bridge 模式是 Docker 的默认网络模式,兼顾网络隔离灵活通信,适用于绝大多数生产场景。

原理

① 容器创建独立的net ns;

② Docker 创建veth pair,一端(eth0)放入容器net ns,另一端(vethxxx)挂载到docker0网桥;

③ 为容器分配docker0网段的 IP(默认172.17.0.0/16),设置默认网关为docker0的 IP(如172.17.0.1);

通过iptables实现端口映射(宿主机→容器)和出口伪装(容器→外部网络)。

特点

  • 优势:容器间隔离(独立net ns),支持跨容器通信(同一docker0网桥),可通过端口映射对外暴露服务;
  • 劣势:网络转发存在一定开销(相较于 Host 模式),跨主机通信需额外配置。

操作示例

# 启动nginx容器,Bridge模式(默认),端口映射:宿主机8080→容器80
docker run -d -p 8080:80 --name nginx-bridge nginx

# 宿主机访问8080端口,即可转发到容器80端口
curl http://127.0.0.1:8080  # 正常返回nginx页面

三、Bridge 模式深度解析(核心重点)

Bridge 模式是 Docker 网络的核心,其内部流程涉及网桥管理、IP 分配、iptables 转发等,需深入理解以排查网络问题。

1. 网桥docker0的初始化与容器接入

  • Docker 启动时:自动创建docker0网桥,默认 IP 为172.17.0.1/16,子网掩码255.255.0.0;
  • 容器启动时

Docker 为容器创建veth pair(如vetha1b2c3和eth0);

将eth0放入容器net ns,并配置 IP(如172.17.0.2)和网关(172.17.0.1);

将vetha1b2c3挂载到docker0网桥,更新docker0的 ARP 缓存(记录容器 IP 与veth设备的映射);

容器通过eth0→vetha1b2c3→docker0,实现与其他容器或宿主机的通信。


2. 端口映射的底层实现(iptables 规则)

当使用-p 宿主机端口:容器端口(如-p 8080:80)时,Docker 会在iptables的nat表中添加两条核心规则:

(1)入站转发(宿主机→容器):DNAT 规则

  • :PREROUTING(数据包进入宿主机时触发);
  • 作用:将宿主机8080端口的 TCP 请求,转发到容器的172.17.0.2:80;
  • 规则查看

    iptables -t nat -L PREROUTING | grep 8080
    # 输出示例:
    DNAT       tcp  --  anywhere             anywhere             tcp dpt:http-alt to:172.17.0.2:80
    

(2)出站伪装(容器→外部网络):SNAT 规则

  • :POSTROUTING(数据包离开宿主机时触发);
  • 作用:将容器(172.17.0.0/16网段)访问外部的数据包,源 IP 替换为宿主机 IP,确保外部服务的回程流量能正确返回容器;
  • 规则查看

    iptables -t nat -L POSTROUTING | grep 172.17
    # 输出示例:
    MASQUERADE  all  --  172.17.0.0/16        anywhere
    

3. 多容器通信与外部访问流程

(1)同一宿主机内容器通信

  • 场景:nginx容器(172.17.0.2)与redis容器(172.17.0.3)通信;
  • 流程:nginx发送数据包→eth0→vethxxx→docker0网桥→vethyyy→redis的eth0;
  • 特点:无需额外配置,直接通过容器 IP 通信,docker0网桥自动转发数据包。

(2)容器访问外部网络(如访问百度)

  • 流程:容器发送数据包(源 IP:172.17.0.2)→docker0→宿主机ens33(物理网卡)→iptables POSTROUTING链将源 IP 伪装为宿主机 IP→外部网络(百度)→回程数据包通过宿主机 IP→iptables转发到容器;
  • 关键:依赖SNAT规则实现 “地址伪装”,确保外部网络能识别回程流量的源 IP。

(3)外部网络访问容器(如远程访问容器内 MySQL)

  • 场景:外部机器通过宿主机192.168.1.100:3306访问容器内 MySQL(172.17.0.4:3306);
  • 流程:外部数据包→宿主机ens33→iptables PREROUTING链将192.168.1.100:3306 DNAT 到172.17.0.4:3306→docker0→容器eth0→MySQL 服务;
  • 验证:外部机器执行mysql -h 192.168.1.100 -P 3306 -u root -p,可正常连接容器内 MySQL。

四、Docker 网络扩展(超出自定义桥接与跨主机通信)

除原生 4 种模式外,Docker 还支持自定义网络和跨主机网络,以满足复杂场景需求。

1. 自定义网桥(推荐生产使用)

默认docker0网桥功能有限(如不支持容器名通信),自定义网桥可解决以下问题:

  • 支持容器间通过容器名通信(无需记忆 IP);
  • 实现不同业务的网络隔离(如 “支付服务网桥”“日志服务网桥”);
  • 可自定义 IP 网段(避免与宿主机 / 外部网络冲突)。

操作示例

# 1. 创建自定义网桥(指定驱动为bridge)
docker network create --driver bridge my-bridge --subnet 192.168.100.0/24 --gateway 192.168.100.1

# 2. 启动容器并加入自定义网桥
docker run -d --name nginx-mybridge --network my-bridge nginx
docker run -d --name redis-mybridge --network my-bridge redis

# 3. 容器间通过容器名通信(无需IP)
docker run --network my-bridge alpine ping nginx-mybridge  # 直接ping容器名,可通

2. Overlay 网络(跨主机容器通信)

适用于多宿主机场景(如 Docker Swarm、Kubernetes),通过 VXLAN 技术将不同宿主机的容器纳入同一虚拟网络,实现跨主机通信。

  • 原理:在宿主机间建立 VXLAN 隧道,将容器数据包封装在 UDP 报文中传输,使跨主机容器认为处于同一网段;
  • 操作:通过docker network create --driver overlay my-overlay创建 Overlay 网络,多宿主机的容器加入后可直接通过 IP / 容器名通信;
  • 适用场景:分布式服务(如微服务集群、分布式数据库),需跨主机部署容器并保持通信。

3. Macvlan 网络(容器模拟物理设备)

为容器分配物理网卡的 MAC 地址,使容器像独立的物理设备一样接入局域网,适用于需要 “独立 IP/MAC” 的场景(如传统应用迁移,需绑定特定 MAC 地址)。

  • 特点:容器直接使用宿主机物理网卡的子接口,无需网桥转发,网络性能接近物理机;
  • 操作:docker network create --driver macvlan --subnet 192.168.1.0/24 --gateway 192.168.1.1 --parent ens33 my-macvlan。

五、Docker 网络管理常用命令

命令

作用

示例

docker network ls

列出所有 Docker 网络

docker network ls

docker network inspect <网络名>

查看网络详情(容器、IP、规则)

docker network inspect my-bridge

docker network create

创建自定义网络

docker network create --driver bridge my-bridge

docker network connect <网络名> <容器名>

将容器加入指定网络

docker network connect my-bridge nginx

docker network disconnect <网络名> <容器名>

将容器从网络中移除

docker network disconnect my-bridge nginx

docker network rm <网络名>

删除网络(需先断开所有容器)

docker network rm my-bridge

brctl show

查看宿主机网桥及挂载设备

brctl show

iptables -t nat -L

查看 NAT 表规则(端口映射、SNAT)

iptables -t nat -L PREROUTING

六、常见 Docker 网络问题排查

1. 容器无法访问外部网络

  • 检查容器网关是否正确:docker exec <容器名> ip route(默认网关应为docker0或自定义网桥的 IP);
  • 检查iptables SNAT 规则:iptables -t nat -L POSTROUTING | grep 172.17(确保有MASQUERADE规则);
  • 检查宿主机 DNS 配置:容器默认继承宿主机/etc/resolv.conf,若宿主机 DNS 错误,容器无法解析域名(可通过docker run --dns 8.8.8.8指定 DNS)。

2. 外部无法访问容器端口

  • 检查端口映射是否正确:docker ps查看PORTS列(如0.0.0.0:8080->80/tcp表示映射正常);
  • 检查iptables DNAT 规则:iptables -t nat -L PREROUTING | grep 8080(确保规则存在);
  • 检查宿主机防火墙:ufw status(若开启防火墙,需允许宿主机端口访问,如ufw allow 8080)。

3. 容器间无法通信

  • 确认容器在同一网络:docker network inspect <网络名>查看容器是否在同一网络内;
  • 检查iptables FORWARD链:iptables -L FORWARD(默认允许转发,若规则拒绝需调整);
  • 检查容器是否禁用 ICMP:部分容器(如 Alpine)默认无ping命令,可通过telnet <容器IP> <端口>测试端口连通性。

总结

Docker 网络的核心是 “基于 Linux 技术的隔离与转发”:通过net ns实现隔离,通过bridge和veth实现连接,通过iptables实现路由与映射。4 种原生网络模式覆盖了从 “完全隔离” 到 “完全共享” 的场景,其中 Bridge 模式是生产默认选择;自定义网桥和 Overlay 网络则扩展了 Docker 网络的适用范围,满足多业务隔离和跨主机通信需求。理解底层原理(尤其是 iptables 规则和网桥流程)是高效排查 Docker 网络问题的关键。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐