背景
Flannel 是专为 Kubernetes 设计的一种用于容器的网络结构插件,用于在 Kubernetes 集群中构建 3 层网络,实现跨宿主机 Pod 之间在 3 层网络相互通信。
Flannel 支持的三种模式:
- UDP:通过 TUN + 用户空间 Flannel 进程实现,由于存在多次用户空间和内核空间之间的 COPY,性能比较差,基本不再使用。
- HOST-GW:纯三层解决方案,把 HOST 作为网关,需要宿主机二层互通,性能比较好,但是存在一定局限。
- VXLAN:在 VLAN 基础上进行扩展,通过构建 Tunnel 实现二层互通。
名词
- VXLAN(Virtual Extensible LAN 虚拟可扩展局域网)
- VTEP(VXLAN Tunnel Endpoints,VXLAN 隧道端点)
- VNI(VXLAN Network Identifier,VXLAN 网络标识符)
原理
同 Pod 通信
Pod 内部容器通过 pause 容器共享一个网络。
同 Node 跨 Pod
通过 veth pair 设备和 cni0(docker0) 网桥实现通信。
跨 Node
首先数据包从pod1内的eth0出来到达cni0网桥,cni0网桥接收到数据包后发现目的IP跟自己不在一个网段,那么自然需要转发出去,而Linux Bridge有个特殊规则: 网桥不会将这个数据包转发给任何设备,而是直接转交给主机的三层协议栈进行处理, 因此通过本机的route得知,目的地址为10.224.1.0段的数据包都将转到flannel.1。
[node1]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.224.0.0 0.0.0.0 255.255.255.0 U 0 0 0 cni0
10.224.1.0 10.224.1.0 255.255.255.0 UG 0 0 0 flannel.1
flannel 为overlay
的容器网络,是个大二层互通的解决方案, 但最终网络包还是要借助物理网卡出去。**任何一个VXLAN设备创建时都会指定一个三层物理网络设备作为VTEP,**flannel.1也不例外,可通过以下命令进行查看:
ip -d link show flannel.1
# 在输出中可看到flannel.1是基于eth0上
当数据包到达flannel.1后, 它如果要将这个包转到目的节点上去,它需要对vxlan报文进行填充
。
在源节点上flannel填充这些信息的过程就叫封包,在目标节点上解开这些信息就叫解包。
VXLAN 报文形式:
右边的为原始报文,左边的即为vxlan封装报文。
Original Ethernet Frame
Original Ethernet Frame 是原始的报文,也就是 pod1 访问 pod2 的报文,因为是个正常网络报文,包含 IP header、Ethernet header、及 payload。
VXLAN Header
VXLAN Header 需要关注 VNI,在目标 Node 的 flannel.1 会对 VNI 字段检查,与当前一致时才会进行处理。
UDP Header
Outer IP Header
HOST IP Header。
Outer MAC Header
HOST MAC Header。
解包
当数据包到达 Node2 的 8472 端口后(实际上就是 VXLAN 模块),VXLAN 模块就会比较这个VXLAN Header 中的 VNI 和本机的 VTEP(VXLAN Tunnel End Point,就是flannel.1)的 VNI 是否一致,然后比较 Inner Ethernet Header 中的目的 MAC 地址与本机的 flannel.1 是否一致,都一致后,则去掉数据包的 VXLAN Header 和 Inner Ethernet Header,然后把数据包从 flannel.1 网卡进行发送。
然后,在 Node2 上会有如下的路由(由 flanneld 维护),根据路由判断要把数据包发送到 cni0 网卡上
[node2 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
...
10.224.2.0 0.0.0.0 255.255.255.0 U 0 0 0 cni0
最后通过 inner ip header 中的 IP 知道需要由 10.224.2.2 的 pod 进行响应。
vxlan 在内核中进行封装、解封装的过程,致使 flannel vxlan 的性能有所下降。