注意 Calico 不会有任何网桥!!!
会为每一个容器创建一个Veth pair 设备,一端在容器内,一端设置到宿主机上
数据的转发,靠 Calico 维护的路由规则
| 模式 | 数据包封包 | 优点 | 缺点 |
|---|---|---|---|
| vxlan | 封包, 在vxlan设备上将pod发来的数据包源、目的mac替换为本机vxlan网卡和对端节点vxlan网卡的mac。外层udp目的ip地址根据路由和对端vxlan的mac查fdb表获取 | 只要k8s节点间三层互通, 可以跨网段, 对主机网关路由没有特殊要求。各个node节点通过vxlan设备实现基于三层的”二层”互通, 三层即vxlan包封装在udp数据包中, 要求udp在k8s节点间三层可达;二层即vxlan封包的源mac地址和目的mac地址是自己的vxlan设备mac和对端vxlan设备mac。 | 需要进行vxlan的数据包封包和解包会存在一定的性能损耗 |
| ipip | 封包,在tunl0设备上将pod发来的数据包的mac层去掉,留下ip层封包。 外层数据包目的ip地址根据路由得到。 | 只要k8s节点间三层互通, 可以跨网段, 对主机网关路由没有特殊要求。 | 需要进行ipip的数据包封包和解包会存在一定的性能损耗 |
| bgp | 不需要进行数据包封包 | 不用封包解包,通过bgp协议可实现pod网络在主机间的三层可达, k8s节点不跨网段时和flannel的host-gw相似; 支持跨网段, 满足复杂的网络架构 | 跨网段时,需要主机网关路由也充当BGP Speaker能够学习到pod子网路由并实现pod子网路由的转发 |
其中Vxlan模式和ipip模式都可以设置crosssubnet, 即在跨网段的k8s节点的pod间通信时才使用vxlan或ipip进行封包, 同一网段的8s节点的pod间通信则直接使用bgp模式。使用同网段内的k8s节点作为BGP Speaker全互联交换各自的pod子网路由实现互通, 避免封包。
| fannel三种模式 | 效率 | calico 模式 |
|---|---|---|
| UDP | 性能较差,封包解包涉及到多次用户态和内核态交互 | 类似 IPIP |
| VXLAN | 性能较好,封包解包在内核态实现,内核转发数据,flanneld负责动态配置ARP和FDB(转发数据库)表项更新 | 类似VXLAN |
| host-gw | 性能最好,不需要再次封包,正常发包,目的容器所在的主机充当网关 flanneld 负责主机上路由表的刷新 | 类似 BGP |

什么是VXLAN?
VXLAN,即Virtual Extensible LAN(虚拟可扩展局域网),是Linux本身支持的一网种网络虚拟化技术。VXLAN可以完全在内核态实现封装和解封装工作,从而通过“隧道”机制,构建出覆盖网络(Overlay Network)
VXLAN的设计思想是:
在现有的三层网络之上,“覆盖”一层虚拟的、由内核VXLAN模块负责维护的二层网络,使得连接在这个VXLAN二层网络上的“主机”(虚拟机或容器都可以),可以像在同一个局域网(LAN)里那样自由通信。
为了能够在二nfcu网络上打通“隧道”,VXLAN会在宿主机上设置一个特殊的网络设备作为“隧道”的两端,叫VTEP:VXLAN Tunnel End Point(虚拟隧道端点)
简而言之:
- 不需要关注 VTEP 与 VTEP 设备之间的通信(如何跨网段,如何进行三层网络的连通)
- 只需关注,将数据包传给当前 VTEP 设备后,如何获取目的 VTEP 的 MAC 地址,完成二层通信
三层 —— 指的是实际物理网络架构
”二层“通信 —— 指的是,需要维护「MAC 地址级别的信息」,即「虚拟IP」与「MAC 地址」的映射关系
基于三层的”二层“通信 —— 可实现跨网段的 Pod 通信
封包是「自顶向下的」,解包是「自底向上的」
简单描述封包:
简单描述解包(反着来):

对比之下,可以看出:
外层以太网头(就是源、目的MAC地址)—— 相同 —— UDP 也具有,这里没画出来而已
外层 IP 头 —— 都具有
UDP 头 —— 都具有
因此不同的就是后面几部分 「VXLAN头,内侧以太网头、内层 IP 头、负载」,「UDP数据」
用 UDP 协议理解就是, 「VXLAN头,内侧以太网头、内层 IP 头、负载」 —— 相当于「UDP数据」
所以可以简单认为 「VXLAN协议相比于 UDP 多了更多控制功能,毕竟相当于将 UDP数据 分了 四层」
那么这么分配的原因是为了什么呢?
原因就是:宿主机的「虚拟IP」(如 Pod IP,容器IP等)无法利用「基础物理网络」进行「跨网段通信」
这四部分的作用是什么呢?


我们结合这个 VXLAN 数据包结构进行讲解
下文基于这样讲解
- 简单将 「VXLAN头,内侧以太网头、内层 IP 头、负载」 称为 「VXLAN 数据包」

上面的「目的容器 IP 」,在这用「目的 Pod IP」这个概念
因为在 k8s 中,Pod 是最基础的运行单元,Pod 封装了容器,你可以把 「目的 Pod IP」近似看做「目的容器 IP 」
通过「目的 Pod IP」—— 得知「目的 VTEP 设备的 MAC 地址」 —— 「源 VTEP 设备」根据得到的信息构建 Vxlan 数据包
如何得知呢?
calico 会维护 「目的 Pod IP 网段」 —— 「目的 VTEP 设备的 MAC 地址」的路由条目,因此进行匹配后便可得知
fannel 会维护一个数据库,存储着 「目的 Pod IP 网段」 —— 「目的 VTEP 设备的 MAC 地址」的信息,因此也可以得知
因为这个过程我们需要管理,但需要「维护 Pod IP 与 VTEPS 设备 MAC 地址 的映射关系」,也就类似二层通信中的 ARP 广播
所以我们称之为 —— ”二层“通信
之后「源 VTEP 设备」 —— 会将此「 Vxlan 数据包」进行「UDP封装」,其中「 Vxlan 数据包」会视为「UDP数据包的基础数据信息」
封装 UDP 数据包 —— 用于三层网络通信,即跨网段 —— 也就是 VTEP 设备间的通信
可以把 VTEP 设备封装的 「 Vxlan 数据包」看做为 「UDP封包中的基础数据单元,或 UDP 的负载」
之后就属于传统网络的 UDP 发包过程,从「一台主机的VTEP 设备」发送到「另一台主机的 VTEP 设备」
这个过程我们不需要管理,仿佛直接将「 Vxlan 包 」直接传递到了「目标 VTEP 设备」,没有感知且不需要维护中间复杂的流程(UDP封包、拆包等),因此称之为 ——「 Vxlan 隧道」
实际上的 UDP 包发送和接收需要走「三层网络」—— 因此称之为 —— 三层通信
到此我们就全部理解了 —— 基于三层的”二层“通信
之后此封装好的「UDP数据包」,将会通过三层网络,到达目的容器所在的主机的「目的VTEP设备」
目的容器所在的主机的「VTEP设备」会进行解包,根据「 Vxlan 数据包」的内容及相应的路由规则,发送给对应的Pod 或容器
将「 Vxlan 包 」从「一个 VTEP 设备」传到「另一个 VTEP 设备」,利用 UDP 协议进行三层网络传输 —— 不要考虑封包解包
仿佛直接将「 Vxlan 包 」直接传递到了「目标 VTEP 设备」,没有感知且不需要维护中间复杂的流程(UDP封包、拆包等),因此称之为 ——「 Vxlan 隧道」




fannel-hostgw 只支持二层网络,不支持三层网络,因为路由器中不存在 【Pod IP】—— 【宿主机MAC地址】的映射信息
Calico BGP 解决了此问题,支持 BGP 的路由器中也会存储着 【Pod IP】—— 【宿主机MAC地址】的映射信息
- 因此知道该如何转发
- 这个信息的分发和维护,是BGP的内在机制 (好像是 Brid 组件)
