flannel使用的vxlan和calico使用的IPIP对比

简述

k8s常用的两大网络插件Flannel和Calico都支持隧道技术,其中Calico支持IPinIP和BGP两种模式,IPIP模式中用到了隧道技术。但是Flannel和Calico使用的隧道技术是有区别的,Flannel使用的是vxlan技术,这种封包技术是MACinUDP的方式,因此Vxlan报文比原始报文多出了50个字节(8个vxlan协议相关字节,8个UDP头部字节,20个IP头部和14个MAC头部字节),这降低了网络线路传输有效数据得的比例,特别是小包。而Calico的IPinIP的封装方法只是在原始报文上添加了新的IP Header只多了20个字节。因此同样是隧道模式但是Calico的IPIP比Flannel的vxlan的网络性能更好。
其实,flannal支持多种后端模式,推荐使用的有三种:VXLAN,host-gw(损耗较少,但因路由设置的原因只适合小型网络)和UDP(一般用于不支持vxlan的内核或者实验),另外还有实验后端例如AliVPC、Alloc等。这里仅介绍vxlanl模式。

flannel的vxlan模式

flannel网络架构

cni0是一个网桥,pod-veth-port on bridge cni0,跨节点通信通过路由到vtep设备flannel.1上,flannel.1给数据封包成vxlan报文,通过flannel.1设置的对外通信网卡(可指定,如果未指定的话是默认路由对应的网卡)把数据包发出去。vtep(VXLAN Tunnel EndPoint)是直接与终端连接的设备,负责原始以太报文的VXLAN封装和解封装.
其中flanneld的主要作用是:

  • UDP封包解包,之所以用UDP是因为该协议头包含5-Tuple(五元组即srcIP、dstIP、srcPort、dstPort和protocol)可用于交换机通信时的面对多条等价路由的HASH计算等因此不能用IP包封装。TCP可有五元组但它是面向连接的有三次握手不利于快速通信,而vxlan报文的可靠性可以通过上层应用来保证。
  • 节点上的路由表的动态更新

flannel网络通信实例

  1. 首先flannel插件管理的容器内部通过路由到达cni0(10.244.1.1/24,集群内每个cni0IP地址各不相同):
[root@cluster-master-2 ~]# kubectl exec -ti -n loki          dev-loki-distributed-gateway-5f8d7b854c-jzx8r ip r
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
default via 10.244.1.1 dev eth0 
10.244.0.0/18 via 10.244.1.1 dev eth0 
10.244.1.0/24 dev eth0 scope link  src 10.244.1.16 
[root@cluster-product-master-2 ~]# ifconfig cni0
cni0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        inet 10.244.1.1  netmask 255.255.255.0  broadcast 10.244.1.255
        inet6 fe80::44b8:4aff:fe7e:1ef9  prefixlen 64  scopeid 0x20<link>
        ether 46:b8:4a:7e:1e:f9  txqueuelen 1000  (Ethernet)
        RX packets 9582425  bytes 3767185084 (3.5 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 10170811  bytes 5053471265 (4.7 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

数据到达cni0后,转发到对应的端口,cni0是一个网桥,查看网桥上的各个端口:

[root@cluster-product-master-2 ~]# brctl show cni0
bridge name	bridge id		STP enabled	interfaces
cni0		8000.46b84a7e1ef9	no		veth3513b76c
							vethd987d8ce

那么哪一个是上面的dev-loki-distributed-gateway容器的端口呢?再次查看容器内部的网卡信息:

[root@cluster-master-2 ~]# kubectl exec -ti -n loki          dev-loki-distributed-gateway-5f8d7b854c-jzx8r ip a
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
4: eth0@if34: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue state UP 
    link/ether 1e:c5:51:e3:76:fd brd ff:ff:ff:ff:ff:ff
    inet 10.244.1.16/24 brd 10.244.1.255 scope global eth0
       valid_lft forever preferred_lft forever

可以看到容器内部的eth0对应主机的if34,两者是veth-pair,然后用命令ip link list找到前面序号是34:

34: vethd987d8ce@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master cni0 state UP mode DEFAULT group default 
    link/ether 26:6e:41:de:25:3a brd ff:ff:ff:ff:ff:ff link-netnsid 4

因此gateway容器对应主机上的端口就是vethd987d8ce.

如果是本机通信,直接在网桥cni0上完成端口数据转发。如果是跨主机的通信,vtep设备flannel.1把报文封装成vxlan后从local端口发送出去。如下图,vtep使用本机ens33网卡把数据包发送出去。

[root@k8s-master ~]# ip -d link show flannel.1
17: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN mode DEFAULT group default 
    link/ether 52:ae:16:30:c0:d1 brd ff:ff:ff:ff:ff:ff promiscuity 0 
    vxlan id 1 local 192.168.31.128 dev ens33 srcport 0 0 dstport 8472 nolearning ageing 300 udpcsum noudp6zerocsumtx noudp6zerocsumrx addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 

vxlan报文

在flannel.1上也能抓到报文,例如ping的话就是纯ICMP报文. 如下图,是截取本地网卡ens33的跨主机访问的vxlan报文。从最外面看是一个UDP的报文,里面是一个vxlan标准包,内容是一个二层MAC包。因此说vxlan是MACinUDP.vxlan报文要注意以下两点:

  • VNI (number): VXLAN Identifier (VNI) to be used. On Linux, defaults to 1. On Windows should be greater than or equal to 4096.
  • Port (number): UDP port to use for sending encapsulated packets. On Linux, defaults to kernel default, currently 8472, but on Windows, must be 4789. VTEP 设备监听UDP端口4789,以便在VXLAN网络中进行VTEP之间的VXLAN封装和解封装. VTEP绑定的本地物理网卡,例如ens33的作用是帧的接收、CRC错误检查、MAC地址过滤、数据包缓存、中断通知、DMA(直接内存访问)、传递给网络协议栈、协议栈处理。这里和VXLAN协议相关的就是协议类型判断,如果协议类型是 VXLAN,数据包将被传递给VXLAN模块进行解封装,提取出内部的原始数据包。本地网卡ens33还会查看vni,并把包给vni对应的vtep设备来解包。

vxlan的优缺点

优点

(1)极大的扩充了二层网段的数量:VXLAN技术的24位VVNI标识符提供了1600万个VXLAN网段,远比VLAN的4094个要多。可以满足数据中心多租户的网段分隔的需求。
(2)更大的灵活性:原来虚拟机的迁移只能在同网段的二层网络上进行,受到地理位置的严重限制。VXLAN通过隧道技术构建可以跨越多个三层网络的虚拟的二层网络,虚拟机可以在物理位置分散的数据
中心之间进行迁移,这使得虚拟机的部署更加灵活和方便。
(3)优化的网络操作:由于VXLAN在标准的第三层IP网络上运行,不再需要构建和管理庞大的第二层基础传输层。
(4)经济性:VXLAN由物理服务器内部的虚拟机管理程序来管理,对虚拟机和普通的网络设备(如物理交换机、路由器)等透明,不需要对现有的物理交换机和路由器进行硬件方面的升级和改造。

缺点

(1)与提供网络服务的传统物理设备通信存在较大问题:VXLAN是一种隧道技术,由于在隧道的两端之间直接建立隧道,那么它是无法与途经的一些物理设备(如传统防火墙、传统负载均衡器)通信的。
(2)影响报文转发效率:需要为每个报文封装与解封装隧道头,降低了报文的转发效率。
从上面的报文可以看出vxlan报文比原始报文多出了50个字节,包括8个字节的vxlan协议相关部分,8个字节的UDP头部,20个字节的IP头部和14个字节的MAC头部。这降低了网络了链路传输有效数据的比例,特别是对小包。

常见问题

  1. k8s flannel failed to set bridge addr: “cni0“ already has an IP address different from xx.xx.xx.xx
    这很可能是因此cni0上的地址和flannel给该节点配置的IP地址段不在一个段。也就是cni0地址和 /run/flannel/subnet.env里面配置的网段不一致。如果是这种情况,可以按如下步骤处理:
ifconfig cni0 down
brctl delbr cni0
ifconfig flannel.1 down
ip link delete flannel.1
kubectl delete pod -n kube-system     kube-flannel-ds-xxx

只删除cni0是不行的,另外如果不行重启下docker、kubelet试试,我尝试的重启docker和kubelet貌似没什么用。最后,如果删除cni0网桥死活删不掉,那就按照/run/flannel/subnet.env里面FLANNEL_SUBNET配置cni0地址。只是不知道这样ifconfig修改机器重启后是不是还是好的,欢迎您给我留言。

  1. 在一个k8s集群中有一个Fedora节点的flannel.1和别的节点flannel.1不通。确认以下内容:
  1. flannel configmap中的vxlan network配置是否和集群配置文件cat /etc/kubernetes/manifests/kube-controller-manager.yaml |grep cidr一致. --cluster-cidr 控制了 Pod IP 的 CIDR 网段; --service-cluster-ip-range=10.96.0.0/12 控制 Service ClusterIP 的网段范围.
  2. 该节点的/run/flannel/subnet.env配置和该节点的cni0属性已经flannel.1的属性(ifconfig查看地址,ip -d link show flannel.1查看flannel.1绑定的网卡以上图为例绑定eth0网卡)
  3. 本地路由
  4. 查看各节点上针对flannel网段下一跳网卡即各个flannel.1的MAC表项这一项往往容易被忽略,但很重要

参考文档

posted @ 2023-02-17 16:50  JaneySJ  阅读(919)  评论(0编辑  收藏  举报