k8s Flannel vxlan模式原理

本文详细解释了Kubernetes(k8s)使用Flannel在vxlan模式下的网络配置、cni0网桥、veth设备以及vtep设备的作用,涉及ARP缓存、UDP封装、路由转发等内容,确保POD间的通信可靠性和网络拓扑管理。
摘要由CSDN通过智能技术生成

k8s Flannel vxlan模式原理

1  k8s网络模型

Flannel 在每个节点上运行一个 flanneld 代理,并预先分配一个子网给主机节点 ,例如10.244.3.1给k8sworker1,Pod运行的前再分配这个子网的IP。Flannel 使用etcd来保存网络配置,已分配的子网,节点IP等。同时还要分配flannel1的 arp-地址解析协议永久缓存,cni0-网关, veth设备(veth设备是每一个POD在主机端有一个veth设备)等,具体作用在后面介绍。

例,arp缓存 ip neigh show dev flannel.1,每台主机都有同样一个flannel.1

10.244.4.0 lladdr a2:8d:f0:2e:58:ce PERMANENT

10.244.1.0 lladdr 06:7d:8a:1f:59:c2 PERMANENT

10.244.5.0 lladdr 0a:fb:71:0f:74:c0 PERMANENT

10.244.2.0 lladdr 5a:e4:c3:cc:13:c2 PERMANENT

10.244.0.0 lladdr 12:2a:47:be:1f:33 PERMANENT

2. 网络配置及cni0:

Flannel 网络配置:

[root@k8smaster1 flannel]# cat /var/run/flannel/subnet.env

FLANNEL_NETWORK=10.244.0.0/16

FLANNEL_SUBNET=10.244.0.1/24

FLANNEL_MTU=1450

FLANNEL_IPMASQ=true

   在我们这个集群中的实际分配状况如下:

[sdwfwd@k8sworker1 /]$ ifconfig

cni0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450

        inet 10.244.3.1  netmask 255.255.255.0  broadcast 10.244.3.255

        inet6 fe80::140b:57ff:fe5c:77ce  prefixlen 64  scopeid 0x20<link>

        ether 16:0b:57:5c:77:ce  txqueuelen 1000  (Ethernet)

        RX packets 146292640  bytes 52132921571 (48.5 GiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 143861695  bytes 82973332387 (77.2 GiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450

        inet 10.244.3.0  netmask 255.255.255.255  broadcast 0.0.0.0

        inet6 fe80::a011:55ff:fe0b:9855  prefixlen 64  scopeid 0x20<link>

        ether a2:11:55:0b:98:55  txqueuelen 0  (Ethernet)

        RX packets 119234264  bytes 37483182903 (34.9 GiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 104687050  bytes 33146619706 (30.8 GiB)

        TX errors 0  dropped 8 overruns 0  carrier 0  collisions 0

veth43438514: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450

        inet6 fe80::60a3:9ff:fe7e:b5f0  prefixlen 64  scopeid 0x20<link>

        ether 62:a3:09:7e:b5:f0  txqueuelen 0  (Ethernet)

        RX packets 415692  bytes 28769309 (27.4 MiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 722618  bytes 49979675 (47.6 MiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[sdfsdf@k8sworker1 /]$ ethtool -i cni0

driver: bridge

version: 2.3

firmware-version: N/A

expansion-rom-version:

bus-info: N/A

supports-statistics: no

supports-test: no

supports-eeprom-access: no

supports-register-dump: no

supports-priv-flags: no

这里的cni0,是一种网桥类型的设备,是一个工作在第二层网络的设备以MAC地址作为目的地进行帧转发,可以看成一个交换机,只负责局域网内部转发。这样就能保证同一主机内的POD的通信。

同一台主机的POD之间是如何通信的:

 不同网络命名空间的设备是可以通过veth这样的设备去连接的,可以用 ifconfig看到,veth是成对出现的,不同的POD属于不同的命令空间的他们是不能通信的,所以需要建立 veth pair的设备,连接到两端的网络命名空间去通信。

但是只有veth是设备是不够的,因为一旦有很多的POD,要让POD之间都联通就必须得两两的去建立这种veth设备,这样veth设备会随时POD的增多而极速增长,而网桥cni0的出现,就会让个拓扑图变得简单,veth pair的一端连接POD,别一个端连接网桥cni0,所以veth看起来更像网线,网桥就将同一台主机上所有POD连接在一起,所以网桥更像一个交换机,工作在第二层,这样就让同一台主机各POD能够进行通信。

3. Flannel.1 介绍

这里的flannel.1是一种 vxlan类型的设备

Vxlan:VxLAN是一种UDP封装协议,它使属于同一网络的主机能够通过L3路由基础设施进行通信

[sdfssfd@k8sworker1 /]$ ethtool -i flannel.1

driver: vxlan

version: 0.1

firmware-version:

expansion-rom-version:

bus-info:

supports-statistics: no

supports-test: no

supports-eeprom-access: no

supports-register-dump: no

supports-priv-flags: no

准备的说法是,flannel.1是一个vtep-vxlan tunnel endpoint设备,在vxlan模式下,这个vtep设备的功能就是封包解包。为什么要封包解包,因为在vxlan模式下,要把发往目标的IP的数据包会用UDP的格式封装起来,最后通过物理网卡和协议栈去发往对端的,

从POD内部发往本地主机物理网卡时,首先要通过cni0网桥的,网桥再将这个数据包转发到flannel.1的,下面介绍一下这种转发的规则及POD和网桥的通信规则:

同一台主机的转发,在上面已经讲讲了。

但如何让POD与外部或公网通信的? 因为网桥还有一个帧转发的功能,它需要把数据帧转发到第三层网络协议栈上去,而网桥只有在数据帧MAC地址为网桥自身MAC地址时,网桥就认为该数据包是要发往主机的,表明该帧是要访问外部网络,此时它才进行转发。如果实现网络数据帧的MAC地址是网桥自身MAC地址的呢,详细的可以看POD里面:

K8sworker1 pod:

[root@ldsfsd-deployment-85b94bb6c-6wsmv tmp]# route -n

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

0.0.0.0         10.244.3.1      0.0.0.0         UG    0      0        0 eth0

10.244.0.0      10.244.3.1      255.255.0.0     UG    0      0        0 eth0

10.244.3.0      0.0.0.0         255.255.255.0   U     0      0        0 eth0

可以看到只要发往10.244.0.0 这个网段的数据时,就会把网桥 10.244.3.1作为网关(IP通信中转站), 那么k8sworker1 的pod发出去的数据包就指定到达10.244.3.1这个ip上,所以mac地址就是10.244.3.1对应的mac地址,即cni0的mac地址。正是由于这个原因,触发了cni0网桥的转发到主机上的三层网络协议栈的这个机制,而到达k8sworker1主机后,通过ip要看具体转发到哪张网卡是看主机的路由信息的,所以,先看下k8sworker1的路由信息。

[sfdfed@k8sworker1 /]$ route -n

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

0.0.0.0         192.168.3.1     0.0.0.0         UG    100    0        0 enp0s3

10.244.0.0      10.244.0.0      255.255.255.0   UG    0      0        0 flannel.1

10.244.1.0      10.244.1.0      255.255.255.0   UG    0      0        0 flannel.1

10.244.2.0      10.244.2.0      255.255.255.0   UG    0      0        0 flannel.1

10.244.3.0      0.0.0.0         255.255.255.0   U     0      0        0 cni0

10.244.4.0      10.244.4.0      255.255.255.0   UG    0      0        0 flannel.1

10.244.5.0      10.244.5.0      255.255.255.0   UG    0      0        0 flannel.1

172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0

192.168.3.0     0.0.0.0         255.255.255.0   U     100    0        0 enp0s3

 如果此时要把k8sworker1数据包发往k8s worker3的 POD :10.244.5.103

查看k8sworker1的路由信息,通过路由信息,看到属于10.244.5.0/24这个网段的数据包都会经过 flannel.1发出,网关是10.244.5.0 ,这个ip也就是对端vtep设备的ip地址

[sinbdfl@k8sworker1 /]$ route -n

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

0.0.0.0         192.168.3.1     0.0.0.0         UG    100    0        0 enp0s3

10.244.0.0      10.244.0.0      255.255.255.0   UG    0      0        0 flannel.1

10.244.1.0      10.244.1.0      255.255.255.0   UG    0      0        0 flannel.1

10.244.2.0      10.244.2.0      255.255.255.0   UG    0      0        0 flannel.1

10.244.3.0      0.0.0.0         255.255.255.0   U     0      0        0 cni0

10.244.4.0      10.244.4.0      255.255.255.0   UG    0      0        0 flannel.1

10.244.5.0      10.244.5.0      255.255.255.0   UG    0      0        0 flannel.1

172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0

192.168.3.0     0.0.0.0         255.255.255.0   U     100    0        0 enp0s3

可以看到它需要匹配的路由信息。

10.244.5.0 其实就是对端的一个vtep设备的IP地址,vtep就是一个封包解包的设备,封解的都是UDP包,封包完成后发往主机节点,由主机节点发送这个UDP包,达到k8sworker3这个设备的物理网卡上面。但是在发往k8sworker3主机节点网卡前,flanne.1要进行一加工处理,只有这样才能让内核认识这是一个vxlan模式的数据包,以便内核能够对它进行特殊的处理,处理的时候会在包的前面加上对端vtep设备的MAC地址 ,那么怎么得到的MAC地址呢,这就要看flanneld这个进程,因为flanneld这个进程会在节点上运行,并在arp缓存中写入了mac地址,且永不过期。

在k8sworker1.

[sisdfe@k8sworker1 /]$ ip neigh show dev flannel.1

10.244.4.0 lladdr a2:8d:f0:2e:58:ce PERMANENT

10.244.1.0 lladdr 06:7d:8a:1f:59:c2 PERMANENT

10.244.5.0 lladdr 0a:fb:71:0f:74:c0 PERMANENT

10.244.2.0 lladdr 5a:e4:c3:cc:13:c2 PERMANENT

10.244.0.0 lladdr 12:2a:47:be:1f:33 PERMANENT

除了加上mac地址,还会加上 vxlan头部信息,来表明这是一个vxlan帧,这样方便对端知道这是一个vxlan帧并进行相应的解包操作。同时头部信息中还包含一个vni的信息,只有vni相同的网络设备才有解包的资格。Flannel.1在对这个包封装完后,还要用UDP格式把这个数据包再包裹一次,这时需要知道要发往的对端的IP,这时flannel.1会查询本机的一个fdb的转发数据库获取目的节点主机的IP。

K8sworker1:

[sidnsdfw@k8sworker1 /]$ bridge fdb show flannel.1 |grep 0a:fb:71:0f:74:c0

0a:fb:71:0f:74:c0 dev flannel.1 dst 192.168.3.225 self permanent

这个IP就是k8sworker3的主机IP,

fdb配置表和前面提到的ARP缓存,都是由 flanneld进程完成的。

k8sworker3 的接收过程:

收到数据包后通过vxlan头部信息,VNI标记,把包给flannel.1进行解包,发现要发送的IP为10.244.5.103,然后查询本机路由信息

[root@k8sworker3 ~]# route -n

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

0.0.0.0         192.168.3.1     0.0.0.0         UG    100    0        0 enp0s3

10.244.0.0      10.244.0.0      255.255.255.0   UG    0      0        0 flannel.1

10.244.1.0      10.244.1.0      255.255.255.0   UG    0      0        0 flannel.1

10.244.2.0      10.244.2.0      255.255.255.0   UG    0      0        0 flannel.1

10.244.3.0      10.244.3.0      255.255.255.0   UG    0      0        0 flannel.1

10.244.4.0      10.244.4.0      255.255.255.0   UG    0      0        0 flannel.1

10.244.5.0      0.0.0.0         255.255.255.0   U     0      0        0 cni0

172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0

192.168.3.0     0.0.0.0         255.255.255.0   U     100    0        0 enp0s3

发现的匹配规则为本地cni0网桥的,然后把数据发送到网桥上,网桥是连接所有的子网,网桥发现10.244.5.103是子网的IP,则把数据包发往这个IP.

UDP是可以丢包的,那个上面的UDP封包并传输是可靠的吗?

不用考虑可靠性。这里的UDP封装的IP包实际上是充当了第二层链路层的工作,传输的可靠性是靠传输层实现的,传输层靠的是对应POD所在网络命令空间中的TCP的重传来保证的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值