树袋熊|十分钟漫谈容器网络方案01—Flannel( 二 )


树袋熊|十分钟漫谈容器网络方案01—FlannelUDP模式工作模式图
UDP模式使用了Flannel自定义的一种包头协议 , 实现三层网络Overlay网络处理跨主通信的问题 。 但是由于数据在内核和用户态经过了多次拷贝:容器是用户态 , docker0和flannel0是内核态 , flanneld是用户态 , 最终又要通过内核将数据发到外部网络 , 因此性能损耗较大 , 对于有数据传输有要求的在线业务并不适用 。
树袋熊|十分钟漫谈容器网络方案01—FlannelUDP模式数据包的传递过程
— Flannel数据转发模式之VXLAN —
如果要进行性能优化 , 就需要减少用户态与内核态之间的数据拷贝 , 这就是VXLAN模式解决的问题 。 VXLAN的核心在于在三层网络的基础上构建了二层网络 , 使分布在不同节点上的所有容器在这个虚拟二层网络下自由通信 。 二层虚拟网络通过VXLAN在宿主机上创建的VTEP设备(flannel.1)实现 , flannel.1和flanneld一样负责封包解包工作 , 不同的是flannel.1的封解包对象是二层数据帧 , 在内核中完成 。
VXLAN的转发过程为:Node1的容器container-1发出的数据包经过docker0 , 路由给VTEP设备 。 每个在flannel网络中的节点 , 都会由flanneld维护一张路由表 , 指明发往目标容器网段的包应该经过的VTEP设备IP地址 。 Node1的VTEP会获得数据包应该发向Node2的VTEP设备的IP , 并通过本地的ARP表知道目的VTEP设备的MAC地址 , 然后封装在数据包头部构成二层数据帧并再加上VXLAN头 , 标识是由VTEP设备处理的数据帧 。 另外 , flannel会维护转发数据库FDB , 记录目标VTEP的MAC地址应该发往的宿主机(也就是Node2) , 宿主机网卡将封装为外部网络传输的包转发到Node2 。 数据帧在Node2上解封后 , 宿主机会识别VXLAN头部 , 直接在内核拆包 , 然后转发到目标VTEP设备并转到对应容器 。
树袋熊|十分钟漫谈容器网络方案01—FlannelVXLAN模式工作模式图
作为Flannel中最被普遍采用的方案 , VXLAN采用的是内置在Linux内核里的标准协议 , 因此虽然封包结构比UDP模式复杂 , 但装包和解包过程均在内核中完成 , 实际的传输速度要比UDP模式快许多 。 较快的传输速度和对底层网络的可兼容性也使得VXLAN适用性较其他模式更高 , 成为业务环境下的主流选择 。
— Flannel数据转发模式之Host-gw —
除去上述两种模式外 , Flannel还提供了一种纯三层网络模式host-gw 。 顾名思义 , host-gw是一种主机网关模式 , 每个主机会维护一张路由表 , 记录发往某目标容器子网的数据包的下一跳IP地址(也就是子网所在宿主机的IP) 。 宿主机将下一跳目的主机的MAC地址作为目的地址 , 通过二层网络把包发往目的主机 。 目的主机收到后 , 会直接转发给对应容器 。 所以host-gw模式下 , 数据包直接以容器IP包的形式在网络中传递 , 每个宿主机就是通信链路中的网关 。
树袋熊|十分钟漫谈容器网络方案01—FlannelHost-Gateway模式工作模式图
和其他两种模式相比 , host-gw模式少了额外的封包和拆包过程 , 效率与虚拟机直接的通信相差无几 。 但是 , 该模式要求所有节点都在物理二层网络中联通 , 且每个主机都需要维护路由表 , 节点规模较大时有较大的维护压力 , 因此不适用复杂网络 。