Administrator
Published on 2025-07-25 / 0 Visits
0
0

《Docker 网络、虚拟网卡与宿主机的底层连接全景解构》

你以为容器之间能通信,是 Docker 的“魔法”?其实背后是 Linux 网络栈与 iptables 搭桥牵线。掌握这些原理,容器就像你手中的水流,可控可塑。


一、为什么你必须理解 Docker 网络?

Docker 虽然“即开即用”,但当你遇到这些问题时,原理就至关重要:

  • 容器之间网络互通靠什么?

  • 容器访问外网,IP 是哪里来的?

  • 容器监听的端口如何映射到宿主机?

  • 改 iptables 或宿主机网卡,会不会影响 Docker?

✅ 本文从底层拆解 Docker 网络,从 namespace虚拟网卡对 veth pair,再到 Bridge、iptables、NAT 转发链路,最后附上一张逻辑网络图,助你彻底吃透 Docker 网络的“幕后黑手”。


二、先看概念地图:核心组件速览

概念

说明

net namespace

容器网络的隔离单位

veth pair

宿主机和容器之间的虚拟网卡“管道”

docker0

默认桥接设备,连接容器网卡

iptables NAT

实现容器访问外部网络的关键

brctl / ip link

查看网桥与网卡关系的命令

network inspect

查看 Docker 网络结构的利器


2.1、Docker 网络类型

容器网络是指容器之间或与Docker工作负载之外的其他工作负载进行连接和通信的能力。

容器默认启用网络能力,它们可以进行出站连接,容器不知道自己连接到哪种网络,也不知道它们的对等方是否也是Docker工作负载。启用网络驱动的容器能看到一个具有IP地址、网关、路由表、DNS服务和其他网络详细信息的网络接口。

Docker容器网络支持以下几种默认的网络驱动类型:

  • bridge

桥接网络,Docker的默认网络驱动程序,它在Docker主机内创建一个内部网络,允许容器之间以及与主机机器进行通信。桥接网络从私有子网中为容器分配IP地址,并使用Docker内置的DHCP服务器来管理IP分配。

  • host

主机网络驱动程序,Docker容器共享主机机器的网络命名空间。这意味着容器可以直接访问主机的网络接口和端口,Container和主机共享网络堆栈。当应用程序需要直接访问主机的网络资源或性能至关重要时,此驱动程序非常有用。

  • none

无网络驱动网络,将容器与任何网络访问隔离开来,包括主机和其他容器。当容器不需要网络访问或出于安全原因需要网络隔离时,此驱动程序非常有用。

  • overlay

不同主机上的Docker守护程序之间能够进行通信。这在多主机环境中特别有用,其中容器需要在不同物理或虚拟机之间进行通信。overlay网络使用VXLAN(虚拟可扩展局域网)技术封装和路由主机之间的网络流量。

  • ipvlan

IPvlan网络对IPv4和IPv6地址提供了完全控制。它们允许您创建子网并将IP地址直接分配给容器,与默认的桥接网络相比提供了更多的灵活性和控制。根据您的网络需求,IPvlan网络可以配置为L2(第二层)或L3(第三层)模式。

  • macvlan

Macvlan驱动程序为每个容器分配唯一的MAC地址,使它们看起来像是网络上的独立物理设备。当应用程序需要直接访问物理网络或需要绕过Docker默认网络堆栈的场景时,此驱动程序非常有用。

2.2 Linux网络类型

在介绍Docker网络类型之前,我们先看一下Linux本身支持的网络设备类型,Linux为了满足虚拟化,网络隔离,流量控制等各种复杂不同场景的网络需求,引入了各种不同的网络技术,除了我们常见的ethernet和loopback两种网卡,我们可以通过ip link工具创建和管理如下Linux已经支持的网络设备类型:

1. bridge (以太网桥设备)

• 内核引入时间:大约在Linux 2.2内核版本中引入(1999年)。

• 功能:bridge设备充当以太网桥,用于将多个网络接口连接在一起,使它们像在同一个局域网中一样工作。

• 实际应用:广泛应用于虚拟化环境,如KVM、QEMU、VirtualBox等,用于将虚拟机或容器的虚拟网卡桥接到宿主机的物理网卡上,实现不同网络间的通信。

2. can (控制器局域网络接口)

• 内核引入时间:大约在Linux 2.4内核版本中引入(2001年)。

• 功能:用于支持控制器局域网(CAN),这是一种专为汽车、工业和嵌入式系统设计的通信协议。

• 实际应用:主要用于汽车电子系统(如汽车的车载网络),工业自动化(如PLC控制系统)等领域。

3. dummy (虚拟网络接口)

• 内核引入时间:大约在Linux 2.0内核版本中引入(1996年)。

• 功能:不进行实际的数据传输,主要用于网络配置和测试。

• 实际应用:用于模拟网络设备,进行网络配置和测试,一些网络服务的测试环境中也会使用。

4. ifb (中间功能块设备)

• 内核引入时间:大约在Linux 2.6内核版本中引入(2005年)。

• 功能:用于网络流量的转发和控制,通常用于流量整形和流量控制。

• 实际应用:在需要对网络流量进行监控和控制的场景中使用,如流量整形和网络性能测试。

5. ipoib (基于Infiniband的IP设备)

• 内核引入时间:大约在Linux 2.6内核版本中引入(2005年)。

• 功能:在Infiniband网络上传输IP数据包,实现高带宽和低延迟的网络通信。

• 实际应用:用于高性能计算(HPC)和数据中心网络,特别是在需要低延迟和高带宽的应用中。

6. macvlan (基于链路层地址的虚拟接口)

• 内核引入时间:大约在Linux 2.6.22内核版本中引入(2007年)。

• 功能:将一个物理接口分割成多个虚拟接口,每个虚拟接口都有独立的MAC地址。

• 实际应用:在容器网络中,通过给每个容器分配一个独立的MAC地址,使其可以像独立的设备一样连接到网络。

7. vcan (虚拟局域CAN接口)

• 内核引入时间:大约在Linux 3.0内核版本中引入(2011年)。

• 功能:用于模拟和测试控制器局域网络(CAN)。

• 实际应用:用于CAN网络的开发和测试,不需要实际的CAN硬件,如汽车电子系统的开发测试环境。

8. veth (虚拟以太网接口)

• 内核引入时间:大约在Linux 2.6.24内核版本中引入(2008年)。

• 功能:成对存在,一个接口连接到一个网络命名空间,另一个接口连接到另一个网络命名空间。

• 实际应用:用于容器(如Docker、Kubernetes)和虚拟机之间的网络连接,实现网络隔离和通信。

9. vlan (基于802.1q标签的虚拟局域网接口)

• 内核引入时间:大约在Linux 2.2内核版本中引入(1999年)。

• 功能:在同一物理网络上创建多个逻辑网络,通过802.1q VLAN标签区分。

• 实际应用:用于网络隔离和分段,提高网络安全性和管理效率,广泛应用于企业网络。

10. vxlan (虚拟扩展局域网)

• 内核引入时间:大约在Linux 3.7内核版本中引入(2012年)。

• 功能:在物理网络上创建虚拟网络隧道,实现跨数据中心的虚拟网络连接。

• 实际应用:用于大规模云计算环境和数据中心的虚拟网络,如OpenStack中的虚拟网络实现

11. ip6tnl (IPv4/IPv6 over IPv6的虚拟隧道接口)

• 内核引入时间:大约在Linux 2.6内核版本中引入(2005年)。

• 功能:在IPv6网络上传输IPv4或IPv6数据包,实现不同协议之间的互通。

• 实际应用:用于IPv4和IPv6网络的互联互通,如IPv6过渡技术中的应用。

12. ipip (IPv4 over IPv4的虚拟隧道接口)

• 内核引入时间:大约在Linux 2.2内核版本中引入(1999年)。

• 功能:在IPv4网络上传输IPv4数据包,用于创建隧道和实现网络隔离。

• 实际应用:用于构建VPN和其他隧道网络,实现远程网络连接和安全通信。

13. sit (IPv6 over IPv4的虚拟隧道接口)

• 内核引入时间:大约在Linux 2.2内核版本中引入(1999年)。

• 功能:在IPv4网络上传输IPv6数据包,实现IPv6网络的连接。

• 实际应用:用于IPv6网络的部署和过渡,如6to4和6rd等过渡技术。

2.3、Docker 网络的默认结构:bridge 模式剖析

在网络层面中,bridge network是一种链路层设备,用于在网络段之间转发流量。bridge可以是硬件设备,也可以是在主机内核中运行的软件设备。

在Docker中,bridge network使用软件桥接,它允许连接到同一个bridge network的容器之间可以进行通信,同时,保证了未连接同一bridge network的容器网络之间的隔离。Docker桥接驱动程序会自动在主机中安装规则,以便不同桥接网络上的容器不能直接相互通信。

Bridge network只适用于在同一Docker daemon主机上运行的容器。要在不同Docker守护进程的主机上运行的容器之间进行通信,您可以在操作系统级别管理路由,或者使用overlay network.。

当启动Docker dameon后,会自动创建一个 default bridge network,启动的容器会自动连接此桥接网络,当然,我们也可以创建自定义的bridge network,用户定义的桥接网络,优先级高于默认的bridge network。

配置解析-默认的bridge网络的信息:

可以看到默认的bridge网络的信息中的Containers字段新增了刚刚启动的nginx名为my-nginx的容器信息,里面包括了本bridge设备为该容器分配的网络地址信息:172.17.0.2/16

当你执行:

docker run -it busybox

Docker 会做如下操作:

(1)创建网络命名空间

每个容器独享一个 net namespace,它和宿主机的网络栈完全隔离。

可通过 ip netns 工具或查看 /proc/<PID>/ns/net 观察。


(2) 创建一对 veth pair

Docker 创建两个虚拟网卡:

  • vethXXXX: 接在容器中(属于容器的 net namespace

  • vethYYYY: 接在宿主机中(并接入 docker0 桥)

这对 veth 类似一根虚拟网线,一端在容器,一端在宿主。

ip link

你会看到很多 vethXXX@ifYY 的虚拟网卡,互为绑定对。


(3) 宿主机默认网桥:docker0

宿主机会有一个默认网桥 docker0

brctl show

显示如下:

这表示容器内的虚拟网卡通过 veth 接入了 docker0,相当于它们接入了同一个二层交换机


(4)NAT 出口:iptables 的 SNAT

容器访问外网不是“直连”,而是通过 NAT 转发:

iptables -t nat -L -n

关键链路如下:

POSTROUTING:
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
  • 容器发出的数据(源地址 172.17.x.x)被改写成宿主机 IP(SNAT)

  • 返回时会自动还原


(5) 容器端口映射:iptables DNAT + docker-proxy

例如:

docker run -p 8080:80 nginx

会生成 DNAT 规则:

iptables -t nat -L -n
PREROUTING:
-A DOCKER -p tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:80

这表示:访问宿主机的 8080 会被转发到容器的 80 端口。

下载和使用容器网络相关的核心命令行工具组件,可以帮助你深入理解和调试 Docker / Linux 下的容器网络机制。以下是常见工具及其功能分类与安装方法。


三、核心组件工具清单(按用途分类)

工具名

所属包

功能说明

brctl

bridge-utils

管理 Linux 网桥,如 docker0(显示桥接网卡)

ip

iproute2

查看网络设备、路由、namespace 等(现代替代 ifconfig

ifconfig

net-tools

传统网卡信息查看工具(老旧,不推荐新项目使用)

ethtool

ethtool

查看/修改网卡底层参数

ss

iproute2

套接字连接状态查看(替代 netstat

iptables

iptables

网络地址转换、包过滤规则配置

tcpdump

tcpdump

抓包分析,追踪容器或 bridge 流量

nsenter

util-linux

进入某个网络命名空间

ip netns

iproute2

管理 Linux 网络命名空间

conntrack

conntrack

跟踪和查看连接跟踪表(netfilter 连接状态)

nft

nftables

替代 iptables 的下一代防火墙框架

tc

iproute2

管理流量控制(QOS / 带宽限速等)

cni

多源

Kubernetes 容器网络插件规范

docker network inspect

docker 内置

查看 docker 网络拓扑与接口绑定详情


3.1、Docker 相关网络工具命令(内置)

无需单独安装,Docker 自带:

docker network ls
docker network inspect <network-name>
docker network create ...

3.2、安装命令(Ubuntu / Debian)

# 安装桥接工具
sudo apt install bridge-utils

# 安装传统网络工具(可选)
sudo apt install net-tools

# 安装网络分析工具
sudo apt install iproute2 ethtool iptables tcpdump conntrack

# 安装 namespace 工具
sudo apt install util-linux

# 安装 nftables(如使用现代内核)
sudo apt install nftables

3.3、推荐调试命令举例

# 查看所有网络接口(含虚拟网卡)
ip link

# 查看 docker0 桥的详细信息
brctl show

# 抓取 veth 相关流量
sudo tcpdump -i vethXXXX

# 查看所有网络命名空间
ip netns list

# 查看 NAT 规则
iptables -t nat -L -n -v

# 进入容器网络命名空间
nsenter -t $(docker inspect -f '{{.State.Pid}}' <container>) -n bash

3.4、常见组件用途关系图(简化)

容器网络原理调试工具地图
┌──────────────┐
│ Namespace    │→ ip netns, nsenter
│              │
│ veth Pair    │→ ip link, tcpdump, brctl
│              │
│ Bridge(docker0) │→ brctl, ip link
│              │
│ NAT 转发      │→ iptables, conntrack
│              │
│ 端口映射     │→ iptables PREROUTING
└──────────────┘

3.5、拓展建议

如你涉及 Kubernetes 或复杂容器网络,还推荐:

  • cilium, calico, flannel:CNI 网络插件工具

  • wireshark:图形化抓包分析

  • netshoot:容器化的全功能网络诊断镜像


四、全景逻辑网络图

      +----------------------+
      |   宿主机主网络栈     |
      |                      |
      |  +--------------+    |
      |  |  docker0     |<--------------------+
      |  |  (网桥)      |                     |
      |  +-----+--------+                     |
      |        |                             |
      |   +----+----+     +----------+       |
      |   | vethXXX |-----| vethYYY  |<--+   |
      |   +---------+     +----------+   |   |
      |                      |           |   |
      |                +------------+    |   |
      |                | 容器网络栈 |    |   |
      |                | netns      |    |   |
      |                +------------+    |   |
      +-------------------------------+  |   |
                      ^                 |   |
                      |  iptables NAT规则   |
                      +---------------------+

五、命令速查表(实战排查必备)

查看容器 veth 对

ip link + docker inspect

查看 bridge 网络

brctl show

查看 namespace 结构

lsns -t net

进入容器网络栈

nsenter -t <pid> -n

查看 iptables 转发规则

iptables -t nat -L -n -v

查看 docker 网络结构

docker network inspect bridge


六、实战建议与延伸阅读

生产环境建议:

  • 避免直接操作 iptables,改用 docker network 管理

  • 若用宿主机网络(--net=host),请注意端口冲突与隔离问题

  • 想实现容器之间跨主机通信?研究 overlay 网络或 CNI 插件如 Flannel、Calico


七、总结:理解 Docker 网络,就是掌控容器通信的“钥匙”

Docker 网络并不神秘,但它涉及 Linux 网络命名空间、虚拟网卡、桥接、iptables、NAT 等多个知识点的交汇。如果你真正理解了上文:

恭喜你,已经不再是“容器初学者”,而是迈入了“网络掌控者”的行列。



Comment