【Docker】(六)Docker网络
目录
1. 网络命名空间(Network Namespace, net ns)
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),是容器与网桥通信的 “物理通道”。
- 工作流程:
- 容器启动时,Docker 创建一对veth pair(如vethxxx和eth0);
- 将eth0放入容器的net ns,作为容器的默认网卡;
- 将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 网络问题的关键。
更多推荐


所有评论(0)