容器技术让应用以轻量级、可移植的方式运行,但当容器分布在多台宿主机上时,如何让它们像在同一台机器上一样直接通信,成为集群组网必须解决的核心问题。单机环境下,容器可以通过Docker默认的bridge网络或自定义网络互相访问,但跨主机场景下,容器的IP地址通常属于不同宿主机各自的私有网段,物理网络无法直接路由这些地址。Overlay网络通过构建一层虚拟的二层网络来跨越底层物理网络限制,使分散的容器看似处于同一个局域网中。

一、容器跨主机通信的挑战与Overlay网络概述
容器默认运行在自己的网络命名空间中,拥有独立的网络栈和IP地址。在单台宿主机上,Docker利用Linux bridge或macvlan等机制,让容器之间可以通过虚拟网卡互通。但当容器被调度到不同宿主机时,其IP地址往往是各自宿主机上私有网段的一部分,例如宿主机A上容器IP为172.17.0.2,宿主机B上容器IP同样可能是172.17.0.2。这种地址重叠以及跨物理网段的不可达性,使得容器无法直接使用这些IP进行跨节点通信。
解决跨主机容器通信有两种基本思路:Underlay网络和Overlay网络。Underlay网络直接使用物理网络基础设施,要求宿主机网络能够路由容器网段,通常需要修改交换机或路由器配置,或者为容器分配与物理网络同网段的IP(如使用macvlan、ipvlan)。这种方式性能好,但灵活性差,需要网络管理员深度介入。Overlay网络则相反,它在现有Underlay网络之上构建一个虚拟网络,容器流量被封装后通过宿主机之间的隧道传输,底层物理网络只看到封装后的数据包,对容器网段完全无感知。
Overlay网络的核心价值在于解耦:容器使用的IP地址与宿主机物理网络IP地址相互独立,容器可以自由迁移,只要目标宿主机加入了同一个Overlay网络,其网络身份(IP、MAC)可以保持不变。这为容器编排系统(如Kubernetes、Swarm)提供了极大的便利,使得Pod或服务可以在集群内任意节点间调度而不中断网络连接。
二、Overlay网络的核心封装技术
Overlay网络实现跨主机通信的关键是隧道封装。当源容器发送一个数据包到目标容器时,源宿主机上的Overlay代理(可以是内核模块、用户态进程或SDN控制器)会捕获该数据包,在原始数据包外层添加新的头部信息,包括隧道协议头、外层IP头等。封装后的数据包通过宿主机物理网卡发送到目标宿主机,目标宿主机的Overlay代理解封装,还原出原始数据包,并投递给目标容器的网络命名空间。
常见的隧道协议包括VXLAN、GRE、IPIP和Geneve。VXLAN(Virtual eXtensible Local Area Network)是目前容器Overlay网络中使用最广泛的协议,它将原始二层以太网帧封装在UDP报文中,使用24位VNI(VXLAN Network Identifier)标识不同的虚拟网络,理论上支持最多1600万个隔离网络。VXLAN报文格式为:外层IP头 + 外层UDP头 + VXLAN头 + 原始二层帧。由于采用UDP封装,VXLAN可以穿越大多数网络设备,且支持负载均衡。Flannel的VXLAN后端和Linux内核原生的VXLAN接口都基于这一协议。
IPIP(IP-in-IP)协议则更简单,它将原始IP包直接封装在另一个IP包中,协议号字段设置为4。IPIP不保留二层帧信息,因此只适用于三层网络,Calico的默认跨子网模式就采用IPIP。GRE(Generic Routing Encapsulation)是一种通用的隧道协议,可以封装任意三层协议,头部开销比VXLAN小,但穿越NAT和防火墙的能力不如UDP封装。每种协议在开销、性能、兼容性方面各有侧重,选择时需结合具体网络环境。
以下命令可以在Linux宿主机上手动创建一个VXLAN接口,用于演示Overlay隧道的基本配置:
# 创建VXLAN接口,指定VNI为100,本地IP为192.168.1.10,目标组播地址为239.1.1.1 ip link add vxlan100 type vxlan id 100 local 192.168.1.10 group 239.1.1.1 dstport 4789 dev eth0 ip link set vxlan100 up ip addr add 10.20.0.1/24 dev vxlan100
上述命令中,vxlan100接口创建后,发往10.20.0.0/24网段的数据包会被内核封装成VXLAN报文,通过eth0物理接口发送到组播组239.1.1.1,实现对端宿主机的解封装。实际容器网络方案通常会使用更复杂的控制平面来自动维护VTEP(VXLAN Tunnel Endpoint)映射,而不是依赖组播。
三、主流容器Overlay网络方案解析
Flannel是CoreOS(现为Red Hat)推出的简单易用的容器网络方案,其VXLAN后端是默认的跨主机模式。Flannel在每个宿主机上运行一个flanneld守护进程,从etcd中读取网络配置,为每个宿主机分配一个独立的子网(如10.244.1.0/24)。flanneld会在宿主机上创建VXLAN接口,并维护一个转发表,将目标容器IP所在子网映射到对应宿主机的VTEP IP。当容器数据包到达本机VXLAN接口时,内核根据转发表自动完成封装,发送到远端宿主机。
Calico是一个纯三层的网络方案,默认使用BGP协议进行路由同步,不依赖隧道。但Calico也支持IPIP模式,当集群节点跨子网部署时,可以启用IPIP隧道来封装容器流量。Calico的IPIP模式在每个节点上创建tunl0接口,将发往其他节点Pod网段的数据包封装在IPIP隧道中。与Flannel相比,Calico的路由控制更精细,支持网络策略,但复杂度和资源消耗也更高。Weave则采用自定义的加密隧道协议,支持跨数据中心组网,但性能相对较差。
下表对比了三种常见方案的特性:
| 方案 | 隧道协议 | 依赖组件 | 网络策略 | 主要优势 |
|---|---|---|---|---|
| Flannel VXLAN | VXLAN | etcd、flanneld | 不支持 | 简单、成熟 |
| Calico IPIP | IPIP | BIRD、Felix | 支持 | 高性能、策略丰富 |
| Weave | 自定义UDP隧道 | Weave Router | 支持 | 加密、跨云 |
选择方案时需要权衡性能、功能需求和运维复杂度。如果只需要基本的跨主机连通性且追求简单,Flannel是理想选择;如果需要网络隔离和策略控制,Calico更合适;如果部署环境跨越多个公有云或需要数据加密,Weave可能更贴合需求。
四、实践:使用Flannel搭建跨主机容器网络
下面以一个简单的实验环境为例,演示如何使用Flannel的VXLAN模式搭建跨主机容器网络。假设有两台宿主机,IP分别为192.168.1.10和192.168.1.20,系统为Ubuntu 22.04,已安装Docker。首先需要部署etcd作为Flannel的配置存储。在宿主机A上启动etcd:
# 在宿主机A上启动etcd(用于测试的单节点etcd) etcd --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls http://192.168.1.10:2379
然后在宿主机A上向etcd写入Flannel的网络配置,例如为整个集群分配10.244.0.0/16网段,使用VXLAN后端:
etcdctl --endpoints=http://192.168.1.10:2379 set /coreos.com/network/config '{"Network":"10.244.0.0/16","Backend":{"Type":"vxlan"}}'
接下来在两台宿主机上分别下载并启动flanneld。以宿主机A为例,指定etcd地址和本地网卡:
# 在宿主机A上启动flanneld flanneld -etcd-endpoints=http://192.168.1.10:2379 -iface=eth0
flanneld启动后会在宿主机上创建flannel.1的VXLAN接口,并分配一个子网(例如宿主机A获得10.244.1.0/24,宿主机B获得10.244.2.0/24)。接着需要配置Docker使用Flannel分配的子网。可以在启动Docker时指定bip和mtu参数:
# 在宿主机A上重启Docker,使用Flannel分配的子网和MTU(Flannel VXLAN默认MTU为1450) dockerd --bip=10.244.1.1/24 --mtu=1450
完成上述配置后,在宿主机A上启动一个容器,并在宿主机B上启动另一个容器。两个容器分别获得10.244.1.x和10.244.2.x的IP地址,它们之间可以互相ping通,数据包会经过VXLAN隧道封装后通过物理网络传输。可以通过在宿主机上抓包验证:
# 在宿主机A的eth0上抓取发往宿主机B的VXLAN报文 tcpdump -i eth0 udp port 4789 -nn
抓包结果中可以看到外层UDP目的端口为4789,内层封装了原始ICMP报文。这直观展示了Overlay网络的工作原理。
五、Overlay网络的性能与适用场景
Overlay网络引入的封装和解封装过程会带来额外的CPU开销和网络延迟。封装增加了报文头部(VXLAN约50字节),降低了有效载荷比例,还可能导致MTU问题,因为外层IP头占用了空间,如果容器内MTU仍然为1500,封装后报文超过物理接口MTU会被分片,进一步影响性能。因此,大多数Overlay方案建议将容器MTU设置为1450或更低。Flannel VXLAN模式默认MTU就是1450,Calico IPIP模式通常设置为1440。
从性能测试数据看,Underlay网络(如macvlan、host-gw)通常比Overlay网络有更高的吞吐量和更低的延迟,但差距正在缩小。现代CPU对VXLAN封装的硬件加速(如智能网卡)也有助于降低开销。对于大多数业务场景,Overlay网络带来的灵活性收益远大于性能损耗,尤其是容器数量众多、需要频繁调度的生产集群。
Overlay网络尤其适合以下场景:跨云或跨数据中心部署的容器集群、需要租户隔离的多用户平台、底层网络无法直接路由容器网段的环境。如果对网络性能有极致要求,且宿主机网络可控,可以考虑使用Underlay方案或混合模式(如Calico的BGP模式不加隧道)。理解Overlay网络的技术原理和适用边界,有助于在架构设计阶段做出更合理的决策。