房屋出租网站模板,wordpress 无法登陆 后台,搜索引擎营销的案例有哪些,html表格的完整代码文章目录 前言一、了解overlay、underlay容器网络二、网络通信1.分类2.网络虚拟设备对2.1、什么是网络虚拟设备对veth pair?2.2、如何查看容器的网卡与主机的哪个veth设备对是成对的关系? 3、vxlan和vtep3.1、vtep3.2、vxlan相关概念 三、Flannel网络模式剖析0、flannel的作用… 文章目录 前言一、了解overlay、underlay容器网络二、网络通信1.分类2.网络虚拟设备对2.1、什么是网络虚拟设备对veth pair?2.2、如何查看容器的网卡与主机的哪个veth设备对是成对的关系? 3、vxlan和vtep3.1、vtep3.2、vxlan相关概念 三、Flannel网络模式剖析0、flannel的作用1、flannel三种网络模式2、通过UDP网络模式剖析奠定后续基础2.1、跨主机容器通信示例2.2、当container-1发起对container-2的访问请求时数据包的通信过程如下2.3、路由规则和 TUN 设备2.4、子网概念和 Etcd 存储2.5、UDP 封装和解封装过程2.6、UDP 模式的性能问题分析 3、VXLAN网络模式剖析3.1、二层网络封装过程3.2、ARP 记录和 MAC 地址获取3.3、内部数据帧和外部数据帧3.4、FDB 转发数据库3.4.1、工作原理3.4.2、FDB工作流程3.4.3、优缺点 4、VXLAN模式下完整的网络通信过程 四、UDP模式和VXLAN模式对比总结五、Flannel部署1、官方部署文档(高版本0.26.1)2、自身环境现使用(低版本0.13) 总结 前言
在传统的单机环境下容器之间的网络通信相对简单通常通过Docker默认的网桥模式就可以实现。然而将容器部署到分布式的集群环境中时跨主机的容器网络通信就成为了一个亟待解决的问题。因为在Docker的默认配置下不同宿主机上的容器是无法直接通过IP地址进行互相访问的。这是因为每个宿主机上的Docker网络都是独立的它们各自管理着自己的私有网段。这种隔离虽然在安全性方面有所裨益但也阻碍了容器之间的直接通信。
因此为了解决这个跨主通信的难题容器社区提出了多种网络方案。这些方案的核心目标是在不同宿主机上的容器之间建立一个虚拟的网络使得它们能够像在同一个局域网内一样进行通信。这就是所谓的覆盖网络Overlay Network技术。 一、了解overlay、underlay容器网络
underlay容器网络 代表承载容器的虚拟机或者物理机网络环境能够识别、转发容器ip。开源网络插件方案如Flannel的host-gw模式、calico的bgp模式。容器网络可以不通过隧道封装,依托于网络插件组件功能(增加路由表)和网络要求(k8s管理的节点在同一子网,不跨三层网络)overlay容器网络 代表承载容器的虚拟机或者物理机网络环境能够识别、转发容器ip。需要通过每个虚拟机上的封包、解包处理后在转发给容器。开源网络插件方案如Flannel的vxlan模式、calico的ipip模式.容器网络通过节点隧道封装后基于承载网络转发只要求kubernetes管理的节点三层网络可达二、网络通信
1.分类
1容器间通信:同一个pod内的多个容器间的通信通过lo即可实现;
2pod之间的通信:同一节点的pod之间通过cni网桥转发数据包。不同节点的pod之间的通信需要网络插件支持。
3pod和service通信:通过iptables或ipvs实现通信ipvs取代不了iptables因为ipvs只能做负载均衡而做不了nat转换。
4pod和外网通信:iptables的MASQUERADE。
5Service与集群外部客户端的通信:ingress、nodeport、loadbalancer...2.网络虚拟设备对
2.1、什么是网络虚拟设备对veth pair? veth是虚拟以太网卡的缩写。veth设备总是成对的,因此称为veth pair.一端发送数据,另一端接收数据,常被用于跨网络空间的通信。
但如果仅有veth pair设备,容器是无法访问外部网络的,因为从容器发出的数据包实际上进入了veth pair设备对的协议栈,如果容器需要访问网络还需要
使用网桥bridge等技术将veth pair设备接收的数据包通过某种方式转发出去。以下是veth pair的基本工作原理2.2、如何查看容器的网卡与主机的哪个veth设备对是成对的关系?
方法一在容器查看该文件中的值 cat /sys/class/net/eth0/iflink在主机查看 /sys/class/net下面的所有的子目录ifindex的值和容器里查出来的值进行对比,一样的话就是一个设备对
方法二在容器执行 ip link show eth0,如下所示116: eth0if117: xxxx从这个可以看出116是eth0接口的index,117是和它成对的veth的index在主机上执行 ip link show | grep 117即可查看设备对3、vxlan和vtep
3.1、vtep
VTEP设备是Flannel VXLAN模式的核心组件它通过在物理网络之上构建虚拟覆盖网络实现了高效、灵活的容器跨主机通信。
为了能够在二层网络上打通“隧道”VXLAN 会在宿主机上设置一个特殊的网络设备作为“隧道”的两端。
这个设备就叫作 VTEP,即VXLAN Tunnel End Point虚拟隧道端点作用
VTEP设备在每个宿主机上都会被创建,通常命名为flannel.1。这个设备既有IP地址,也有MAC地址,可以被视为一个虚拟的网络接口。
VTEP设备的主要作用:是执行VXLAN封装和解封装操作使得容器可以在不同宿主机之间进行通信.注意事项:它进行封装和解封装的对象,是二层数据帧Ethernet frame,而且这个工作的执行流程,全部是在内核里完成的因为 VXLAN 本身就是 Linux 内核中的一个模块当在k8s宿主机上查看网络设备时可以看到flannel.1设备的存在
[rootk8s-master~]# ip addr show flannel.1
4: flannel.1: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1450 qdisc noqueue state UNKNOWN link/ether c6:58:f3:29:cb:d8 brd ff:ff:ff:ff:ff:ffinet 10.244.1.0/32 brd 10.244.1.0 scope global flannel.1valid_lft forever preferred_lft foreverinet6 fe80::c458:f3ff:fe29:cbd8/64 scope link valid_lft forever preferred_lft forever从上述输出中我们可以看到flannel.1设备的MAC地址和IP地址。这些信息在VXLAN网络中用于标识不同的VTEP设备优点
VTEP设备的引入使得Flannel能够在现有的三层网络上构建一个虚拟的二层网络。
这种方式不仅保证了容器网络的隔离性还提供了良好的可扩展性。与UDP模式相比VXLAN模式的VTEP设备能够在内核态完成封装和解封装操作大大减少了用户态和内核态之间的切换从而提高了网络性能。此外VTEP设备还支持多播和广播这使得ARP请求和DHCP等基于广播的协议能够在VXLAN网络中正常工作。这一特性进一步增强了VXLAN网络的灵活性和兼容性3.2、vxlan相关概念
vxlan作用
VXLAN (Virtual Extensible LAN) 是一种覆盖网络技术,全称是虚拟可扩展的局域网。
1、它主要用于解决传统 VLAN 技术的一些限制,如 VLAN ID 数量限制只有4096个。VXLAN 可以支持高达1600万个虚拟网络极大地扩展了网络的规模和灵活性。2、提供封装与隧道技术VXLAN 通过封装原始的以太网帧Layer 2到 UDP 数据包Layer 3中来工作。这意味着它可以跨越不同的网络和子网实现跨网络边界的通信。3、提供VXLAN 网络标识符 (VNI)每个 VXLAN 网络都有一个唯一的标识符,称为 VNIVXLAN Network Identifier,它提供了地址隔离确保各个 VXLAN 网络之间的数据包不会互相干扰4、提供VTEPVXLAN Tunnel EndpointVTEP 是 VXLAN 架构中的端点设备负责封装和解封装数据包,且这个工作的执行流程,全部是在内核里完成的。每个通过 VXLAN 通信的网络设备都有一个或多个 VTEPvxlan通信流程---啰嗦版
1、每台设备上已经有了VTEP设备和相应的路由规则源容器发出请求后数据包包含了源容器ip和目的容器ip这个原始数据包首先会通过虚拟网卡对出现在docker0网桥上然后根据路由规则到达VTEP设备且要发往的网关地址为目的VTEP设备的ip然后VTEP会从ARP表里获取到对应的MAC地址并进行二层封包得到一个二层数据帧我们把它称为“内部数据帧”。2、 接下来Linux 内核会在“内部数据帧”前面加上一个特殊的 VXLAN 头用来表示这实际上是一个 VXLAN 要使用的数据帧而这个 VXLAN 头里有一个重要的标志叫作 VNI它是 VTEP 设备识别某个数据帧是不是应该归自己处理的重要标识而在 Flannel 中VNI 的默认值是 13、然后Linux 内核会从FDB数据库里读取到对应的目的宿主机ip把“内部数据帧”和目的宿主机ip封装进一个 UDP 包里我们把它称为“外部数据帧”这个“外部数据帧”里包含了源节点ip和目的节点ip然后Linux内核会在这个“外部数据帧”前面加上目的宿主机的MAC地址这样封包工作就宣告完成了。4、接下来源宿主机上的 flannel.1 设备就可以把这个数据帧从源宿主机的 eth0 网卡发出去数据帧会经过宿主机网络来到目的宿主机的 eth0 网卡。这时候目的宿主机的内核网络栈会发现这个数据帧里有 VXLAN Header并且 VNI1。所以 Linux 内核会对它进行拆包拿到里面的内部数据帧然后根据 VNI 的值把它交给 flannel.1 设备。而 flannel.1 设备则会进一步拆包取出“原始 IP 包”然后根据路由规则将它交给docker0网桥经过虚拟网卡对就进入到了目的容器里。vxlan通信流程---精简版
1、首先当一个容器发送数据包到另一个宿主机上的容器时这个数据包会被路由到本机的VTEP设备。2、然后VTEP设备会对这个原始数据包进行VXLAN封装。封装过程中VTEP会在原始数据包外层添加VXLAN头部、UDP头部、IP头部和以太网头部。这个过程将原始的二层数据帧封装成一个可以在物理网络中传输的UDP数据包。3、接下来封装后的数据包会通过物理网络发送到目标宿主机。4、在目标宿主机上该主机的VTEP设备会接收到这个封装后的数据包并进行解封装操作。解封装过程会移除外层的头部信息还原出原始的数据包。5、最后解封装后的原始数据包会被转发到目标容器。上述vxlan通信过程可以使用下方图进行一个描述
三、Flannel网络模式剖析
0、flannel的作用
1、协助k8s,给每一个Node上的Docker容器分配互相不冲突的IP地址。2、建立一个覆盖网络(overlay network),通过这个覆盖网络,将数据包原封不动的传递到目标容器。覆盖网络是建立在另一个网络之上并由其基础设施支持的虚拟网络。覆盖网络通过将一个分组封装在另一个分组内来将网络服务与底层基础设施分离,在将封装的数据包转发到端点后,将其解封装。3、创建一个新的虚拟网卡Flannel0接收docker网桥的数据,通过维护路由表,对接受到的数据进行封包和转发。4、etcd保证了所有node上flanneld所看到的配置是一致的。同时每个node上的flanned监听etcd上的数据变化,实时感知集群中node的变化1、flannel三种网络模式
udp网络模式
UDP 模式是 Flannel 最早支持的一种实现方式。
它通过在用户态将容器间通信的数据包封装在 UDP 包中进行传输。
虽然实现简单直观但由于涉及频繁的用户态与内核态切换以及数据的多次拷贝导致性能较差。因此UDP 模式目前已被弃用。host-gw网络模式
host-gwhost gateway模式是一种直接利用宿主机作为网关的实现方式。
它通过在各个宿主机上添加路由规则将目标容器所在宿主机的 IP 地址设置为网关从而实现容器跨主机通信。
这种模式性能较高但要求所有宿主机都在同一个二层网络内【工作原理】当容器需要与其他宿主机上的容器通信时数据包会先发送到本机的网桥设备。然后根据路由表数据包会被转发到目标容器所在的宿主机。目标宿主机接收到数据包后再将其转发给目标容器。【优点】性能高由于不需要额外的封装和解封装过程host-gw模式的性能接近于原生网络。配置简单不需要额外的网络设备或协议支持。【缺点】要求所有宿主机在同一个二层网络这限制了其在跨数据中心或云环境中的应用。路由表膨胀随着节点数量的增加每个节点上的路由表会变得很大。vxlan网络模式
VXLANVirtual Extensible LAN是 Linux 内核原生支持的网络虚拟化技术。
它通过在现有的三层网络上覆盖一层虚拟的二层网络实现了跨主机的容器通信。
VXLAN 模式能够在内核态完成封装和解封装工作因此性能较好逐渐成为了主流的容器网络方案。【工作原理】当容器需要与其他宿主机上的容器通信时,数据包会被路由到本机的VTEP设备然后,VTEP设备会对这个原始数据包在内核进行VXLAN封装,将原始的二层数据帧封装成一个可以在物理网络中传输的UDP数据包封装后的数据包会通过物理网络发送到目标宿主机。在目标宿主机上该主机的VTEP设备会接收到这个封装后的数据包并进行解封装操作。解封装过程会移除外层的头部信息还原出原始的数据包。【优点】性能高在内核态完成封装和解封装工作覆盖和底层网络是完全独立的因此如果底层网络拓扑发生变化覆盖网络不会受到影响 2、通过UDP网络模式剖析奠定后续基础
2.1、跨主机容器通信示例 为了理解Flannel的UDP模式工作原理,来看一个具体的跨主机容器通信示例。
假设有两台宿主机Node 1和Node 2其中:在Node 1上我们有一个名为container-1的容器其IP地址为10.244.0.13。对应的docker0网桥地址是10.244.0.1/24。在Node 2上我们有另一个名为container-2的容器其IP地址为10.244.1.14。对应的docker0网桥地址是10.244.1.1/24。需求:现在让container-1能够访问container-2。2.2、当container-1发起对container-2的访问请求时数据包的通信过程如下
1、container-1发出一个IP包源地址为10.244.0.13目的地址为10.244.1.14。2、这个IP包首先到达Node 1的docker0网桥。由于目的地址10.244.1.14不在docker0网桥的网段内所以这个IP包会被转发给默认路由。3、根据Node 1上的路由规则这个IP包会被送往一个名为flannel0的设备。flannel0是一个TUN设备它在三层网络上工作。4、flannel0设备会将这个IP包交给用户态的flanneld进程处理。5、flanneld进程通过查询Etcd得知目的IP地址10.244.1.14所在的子网对应的宿主机是Node 2其IP地址为11.101.1.3。6、flanneld将原始的IP包封装在一个UDP包里然后发送给Node 2的8285端口flanneld默认监听的端口。7、当这个UDP包到达Node 2后会被Node 2上的flanneld进程接收和解包还原出原始的IP包。8、Node 2的flanneld将还原出的IP包交给本机的flannel0设备。9、flannel0设备将IP包转发给docker0网桥。10、docker0网桥根据目的IP地址将包转发给container-2。对上述通信流程的总结:通过这个过程Flannel在不同宿主机上的两个容器之间建立了一个隧道使得它们可以直接使用IP地址进行通信而无需关心容器和宿主机的具体分布情况。这种UDP封装的方式虽然实现了跨主机的容器通信但由于涉及多次用户态与内核态的切换以及数据的多次拷贝因此性能较差。这也是为什么UDP模式后来被VXLAN等更高效的模式所取代的原因。2.3、路由规则和 TUN 设备
在上述通信过程中反复提到了路由规则和TUN设备,在此对二者进行详细说明
在Flannel的UDP模式中路由规则和TUN设备扮演着关键角色它们共同构建了容器跨主机通信的基础架构。首先查看Flannel在宿主机上创建的路由规则。
以Node 2为例,如上图所示凡是发往 10.244.2.0/24 网段的 IP 包都需要经过 flannel.1 设备发出并且它最后被发往的网关地址是10.244.2.0。10.244.2.0 正是 Node 2 上的 VTEP 设备也就是 flannel.1 设备的 IP 地址,如上图所示当容器发出的数据包到达宿主机时Linux内核会根据这些路由规则决定数据包的下一步去向。
对于跨主机通信的情况数据包会被路由到flannel0设备。注意事项:1、flannel0是一个TUN设备它是Linux内核提供的一种虚拟网络设备2、每台宿主机上的 flanneld 进程会负责维护相关的路由规则3、TUN设备的特殊之处在于它工作在网络层第三层主要用于处理IP数据包4、当一个IP数据包被发送到TUN设备时它不会被转发到物理网络而是被递交给创建该设备的用户空间程序flannel0(TUN)设备与用户空间的flanneld进程工作流程
1、当一个数据包被路由到flannel0设备时,linux内核将这个数据包从内核空间传递到用户态空间的flanned进程中2、flanneld进程接收到这个IP数据包后会根据数据包的目的IP地址查询Etcd确定目标容器所在的宿主机3、然后flanneld将原始的IP数据包封装在一个UDP包中并将这个UDP包发送到目标宿主机4、在目标宿主机上flanneld进程接收到UDP包后解封装出原始的IP数据包并将其写入本机的flannel0设备5、目标宿主机的Linux内核接收到这个IP数据包然后根据本机的路由规则将其转发到正确的容器总结
这种设计允许Flannel在不修改Linux内核的情况下实现了跨主机的容器通信。
TUN设备(flannel0)充当了用户空间和内核空间之间的桥梁使得flanneld可以接管容器间通信的路由过程。然而这种设计也带来了性能上的开销。
每个数据包都需要经过三次用户空间和内核空间的切换以及多次数据拷贝这inevitably会影响网络性能。
分别是以下三次用户态和内核态的切换:1第一次用户态的容器进程发出的 IP 包经过 docker0 网桥进入内核态2第二次IP 包根据路由表进入 TUNflannel0设备从而回到用户态的 flanneld 进程3第三次flanneld 进行 UDP 封包之后重新进入内核态将 UDP 包通过宿主机的 eth0 发出去。
这也是为什么Flannel的UDP模式虽然实现简单但在实际生产环境中较少使用的原因2.4、子网概念和 Etcd 存储
子网概念
在Flannel的网络架构中子网Subnet是一个核心概念。每台宿主机都被分配一个独立的子网该子网内的所有容器都属于这个子网。这种设计使得容器网络的管理变得更加简单和高效。在上述例子中Node 1的子网是10.244.1.0/24而Node 2的子网是10.244.2.0/24。
这意味着Node 1上的所有容器都会获得10.244.1.0/24网段内的IP地址而Node 2上的所有容器则会获得10.244.2.0/24网段内的IP地址。etcd存储
Flannel使用Etcd作为分布式存储系统来保存这些子网信息。1、Etcd是一个高可用的键值存储系统它在Flannel的网络方案中扮演着重要角色。2、Flannel将子网与宿主机的对应关系存储在Etcd中这样集群中的所有节点都可以获取到这些信息3、Flannel的flanneld进程会定期从Etcd中读取这些信息并据此更新本机的路由表和ARP表。
当一个容器需要与另一个宿主机上的容器通信时flanneld就可以根据这些信息来确定目标容器所在的宿主机并正确地封装和转发数据包基于Etcd的子网管理方式有几个显著的优点:动态性: 当新的宿主机加入集群或现有宿主机离开集群时子网分配信息可以动态更新。一致性: 所有节点都可以从Etcd获取到一致的网络拓扑信息确保了整个集群网络配置的一致性。可扩展性: 这种方式可以轻松支持大规模集群因为Etcd本身就是为高可用和大规模设计的。灵活性: 通过修改Etcd中的数据可以灵活地调整网络配置而无需重启整个集群。然而这种设计也带来了一些挑战。最主要的是Etcd成为了整个网络的一个关键依赖。
如果Etcd集群出现问题可能会影响到整个容器网络的正常运行。
因此在生产环境中通常需要部署高可用的Etcd集群并定期进行备份。总的来说Flannel通过Etcd存储子网信息的方式巧妙地解决了容器跨主机通信时的寻址问题。
这为实现高效的容器网络奠定了基础也为后续的VXLAN等更高效的网络模式提供了必要的支持2.5、UDP 封装和解封装过程
在Flannel的UDP模式中封装和解封装过程是实现容器跨主机通信的核心。这个过程涉及到数据包在不同网络层之间的转换
以及在宿主机之间的传输。理解UDP模式的封装和解封装过程对于理解容器网络的工作原理非常有帮助。
它为我们展示了容器网络方案需要解决的核心问题以及解决这些问题的基本思路。
这为理解更高效的网络方案如VXLAN模式奠定了基础。让我们详细探讨UDP模式中封装和解封装过程的过程。拆解UDP封装过程
首先当源容器例如container-1发送一个数据包到目标容器例如container-2时这个原始的IP数据包会经过docker0网桥
然后根据路由规则被转发到flannel0设备。flannel0作为一个TUN设备会将这个数据包从内核空间传递到用户空间的flanneld进程。flanneld进程接收到这个原始IP数据包后会进行UDP封装。
封装过程包括以下步骤:1、flanneld首先检查数据包的目的IP地址确定目标容器所在的宿主机。2、flanneld然后创建一个新的UDP数据包。这个UDP数据包的源IP地址是当前宿主机的IP地址目的IP地址是目标容器所在宿主机的IP地址。UDP端口通常是8285。3、原始的IP数据包被放入这个UDP数据包的负载部分。4、flanneld将封装好的UDP数据包交给宿主机的网络栈由宿主机的网络栈负责将这个UDP包发送出去。拆解UDP解封装过程
当封装好的UDP包到达目标宿主机后解封装过程开始。
这个过程基本上是封装过程的逆操作:1、目标宿主机的网络栈接收到UDP包发现目的端口是8285于是将这个包交给监听在8285端口的flanneld进程。2、flanneld进程接收到UDP包后从UDP包的负载中提取出原始的IP数据包。3、flanneld将提取出的原始IP包写入本机的flannel0设备。4、Linux内核接收到这个IP包根据路由规则将其转发给docker0网桥。5、docker0网桥根据IP包的目的地址将包转发给目标容器。2.6、UDP 模式的性能问题分析 UDP模式的主要性能问题来自于频繁的用户态和内核态切换.这种频繁的状态切换会带来显著的性能开销。
即:1第一次用户态的容器进程发出的 IP 包经过 docker0 网桥进入内核态2第二次IP 包根据路由表进入 TUNflannel0设备从而回到用户态的 flanneld 进程3第三次flanneld 进行 UDP 封包之后重新进入内核态将 UDP 包通过宿主机的 eth0 发出去。从上述流程图中我们可以清楚地看到一个简单的数据包发送过程涉及多次用户态和内核态的切换以及多次数据拷贝UDP网络模式性能问题在实际应用中的表现可能如下:1、较高的网络延迟: 由于每个数据包都需要经过多次处理和状态切换网络延迟会显著增加。2、CPU使用率升高: 频繁的状态切换和数据拷贝会消耗大量的CPU资源。3、吞吐量受限: 由于单个flanneld进程需要处理所有流量在高并发情况下可能会成为瓶颈。4、内存带宽压力: 多次数据拷贝会增加内存带宽的使用。5、网络效率降低: UDP封装增加了数据包大小降低了网络的有效载荷比例。正是由于这些性能问题UDP模式在实际生产环境中很少被使用。
相比之下VXLAN模式通过在内核态实现封装和解封装大大减少了用户态和内核态的切换同时也减少了数据拷贝的次数因此能够提供更好的性能UDP网络模式分析完毕,接着在此基础上引出vxlan网络模式
3、VXLAN网络模式剖析
在上述中已经对vtep、vxlan、封包有个基本了解,因此分析vxlan模式时从二层网络封装过程开始着手
3.1、二层网络封装过程
VXLAN的二层网络封装过程,不仅展示了如何在现有的IP网络上构建虚拟的二层网络,还为我们提供了一个优化网络性能的思路。
在Flannel的VXLAN模式中,二层网络封装过程是实现容器跨主机通信的核心机制。
这个过程涉及到将原始的二层数据帧封装到一个新的UDP数据包中以便在三层网络上传输。封装过程
首先当源容器发送一个数据包到目标容器时这个原始的二层数据帧会经过docker0网桥然后根据路由规则被转发到flannel.1设备。
flannel.1是一个VXLAN设备也被称为VTEPVXLAN Tunnel End PointVTEP设备接收到这个原始的二层数据帧后会进行VXLAN封装。
这个封装过程的关键在于它将原始的二层数据帧封装在一个UDP包中使得这个数据帧可以在三层网络IP网络中传输。
这就好像在现有的IP网络之上创建了一个虚拟的二层网络。封装过程包括以下步骤:1、VTEP设备首先检查数据帧的目的MAC地址确定目标容器所在的宿主机。这个信息是通过ARP表和FDBForwarding Database获得的。2、VTEP设备然后创建一个新的UDP数据包。这个UDP数据包的源IP地址是当前宿主机的IP地址目的IP地址是目标容器所在宿主机的IP地址。UDP端口通常是4789VXLAN的标准端口。3、在UDP数据包的负载部分VTEP设备会添加一个VXLAN头。这个VXLAN头包含一个24位的VNIVXLAN Network Identifier用于标识不同的VXLAN网络。4、原始的二层数据帧被放在VXLAN头之后构成UDP数据包的完整负载。5、VTEP设备将封装好的UDP数据包交给宿主机的网络栈由宿主机的网络栈负责将这个UDP包发送出去优点
它允许不同宿主机上的容器直接使用二层地址MAC地址进行通信就好像它们在同一个局域网内。封装过程完全在内核态完成避免了频繁的用户态和内核态切换提高了性能。VXLAN封装增加的开销相对较小对网络性能的影响较小。这种方式可以很好地与现有的网络基础设施集成不需要对底层网络做特殊配置。然而这种封装方式也带来了一些挑战。它增加了网络包的大小可能会导致MTUMaximum Transmission Unit问题。
此外VXLAN封装也增加了一定的处理复杂度可能会对网络延迟产生轻微影响3.2、ARP 记录和 MAC 地址获取
在Flannel的VXLAN模式中ARP记录和MAC地址的获取是实现容器跨主机通信的关键环节。
这个过程涉及到如何在虚拟的二层网络中定位和识别不同的VTEP设备。首先我们需要理解在VXLAN网络中每个VTEP设备即flannel.1设备都有自己的IP地址和MAC地址。这些地址信息是VXLAN网络内部使用的与宿主机的实际网络地址是不同的。当一个VTEP设备需要向另一个VTEP设备发送数据时它需要知道目标VTEP设备的MAC地址。在传统的二层网络中我们通常使用ARP地址解析协议来获取IP地址对应的MAC地址。
然而在Flannel的VXLAN网络中这个过程被稍微简化了。Flannel采用了一种更直接的方式来维护ARP记录。当一个新的节点加入Flannel网络时该节点上的flanneld进程会将自己VTEP设备的IP地址和MAC地址信息广播到整个集群。
集群中的其他节点接收到这个信息后会在本地创建相应的ARP记录。这个过程是自动完成的无需实际的ARP请求和响应可以通过以下命令查看本地的ARP记录
这里的每一行都代表一个ARP记录其中10.244.1.0和10.244.2.0是VTEP设备的IP地址而后面的MAC地址则是对应的VTEP设备的MAC地址。值得注意的是这些ARP记录被标记为PERMANENT这意味着它们是静态的不会因为超时而被删除。这种设计可以减少网络中的ARP流量提高网络效率。当一个VTEP设备需要向另一个VTEP设备发送数据时它会首先查找本地的ARP表。
如果找到了目标IP对应的MAC地址它就可以直接构造二层数据帧将原始的IP包封装其中。如果出现了ARP表中没有记录的情况这种情况在正常运行的集群中应该很少发生Flannel会尝试重新获取ARP信息。
这可能涉及到与etcd的通信或者触发一次集群范围的ARP更新。这种ARP记录和MAC地址获取的机制有几个明显的优点
1、减少了网络中的ARP请求和响应流量提高了网络效率。2、加快了数据包的封装过程因为不需要在发送每个数据包时都进行ARP解析。3、简化了网络故障排查因为ARP记录是静态的易于查看和理解。然而这种机制也带来了一些挑战:1、如果集群中的节点频繁变动可能需要更频繁地更新ARP记录。2、如果ARP记录出现错误可能会导致网络通信问题。3.3、内部数据帧和外部数据帧
在Flannel的VXLAN模式中内部数据帧和外部数据帧是两个关键概念它们共同构成了VXLAN封装的核心 内部数据帧组成
内部数据帧是指原始的、由容器发出的数据帧。
当容器需要与其他宿主机上的容器通信时它会生成一个普通的以太网数据帧。
这个数据帧包含了源容器的MAC地址、目标容器的MAC地址以及IP层的信息。
然而这个数据帧无法直接在宿主机网络中传输因为宿主机网络并不知道如何处理容器的MAC地址外部数据帧组成
外部数据帧的结构比内部数据帧要复杂得多。
从外到内它包括以下几个部分:1、外部以太网头: 包含源宿主机和目标宿主机的MAC地址。2、外部IP头: 包含源宿主机和目标宿主机的IP地址。3、外部UDP头: VXLAN使用UDP作为传输协议默认端口是4789。4、VXLAN头: 包含一个24位的VXLAN网络标识符VNI。5、内部数据帧: 原始的、由容器发出的完整以太网帧。这种封装和解封装的过程使得容器网络可以跨越物理网络的限制实现跨主机通信。
内部数据帧保持了容器网络的独立性而外部数据帧则利用了现有的物理网络基础设施。当外部数据帧到达目标宿主机后会经历一个解封装的过程。目标宿主机会依次剥离外部以太网头、IP头、UDP头和VXLAN头最终得到原始的内部数据帧。
然后这个内部数据帧会被转发到目标容器3.4、FDB 转发数据库
在VXLAN模式中FDBForwarding Database转发数据库是一个关键组件它在Flannel网络中扮演着类似于二层交换机的角色。
FDB主要负责维护VTEP设备的MAC地址与对应宿主机IP地址之间的映射关系这对于VXLAN网络中的数据包转发至关重要。3.4.1、工作原理
FDB的工作原理类似于传统以太网交换机中的MAC地址表。
当一个VTEP设备需要向另一个VTEP设备发送数据时它会查询FDB以获取目标VTEP的MAC地址对应的宿主机IP地址。
这个过程确保了VXLAN封装的数据包能够正确地发送到目标宿主机。FDB记录由flanneld进程负责维护。当一个新的节点加入Flannel网络时flanneld会自动更新所有节点的FDB记录。可以通过bridge fdb命令来查看FDB的内容 上述fdb记录的含义是MAC地址为xxxx的VTEP设备位于IP地址为10.xxx的宿主机上。permanent标志表示这是一个静态记录不会自动过期
3.4.2、FDB工作流程 1、当容器1需要向容器2发送数据时数据包首先到达容器1所在宿主机的VTEP设备。
2、VTEP设备会查询FDB获取目标容器所在VTEP设备的MAC地址对应的宿主机IP地址。
3、然后VTEP设备会使用这个IP地址作为外层IP头的目的地址将原始数据帧封装在VXLAN包中发送出去。3.4.3、优缺点
优点:FDB的使用大大提高了VXLAN网络的效率。通过维护VTEP设备的MAC地址与宿主机IP地址的映射关系FDB避免了在VXLAN网络中进行广播查找的需求从而减少了网络开销提高了转发效率
缺点:1、在大规模集群中FDB表可能会变得相当大这可能会对内存使用和查找性能产生影响。2、当节点频繁加入或离开集群时FDB表的更新也可能成为一个潜在的性能瓶颈。4、VXLAN模式下完整的网络通信过程 背景: 跨节点的 容器AIP10.244.0.2需要向容器BIP10.244.1.3发送数据时封包过程
1、容器A生成原始IP包,源地址为10.244.1.2,目的地址为10.244.2.3。2、这个IP包通过容器的虚拟网卡发送出去,到达宿主机的docker0网桥。3、docker0网桥根据路由规则,将这个包转发给flannel.1设备VTEP设备。4、flannel.1设备接收到这个IP包后,开始VXLAN封装过程。它首先需要知道目的容器所在的VTEP设备的MAC地址。为此,它会查询本地的ARP表。5、获得目的VTEP的MAC地址后,flannel.1设备会构造一个内部以太网帧,将原始IP包封装其中。6、接下来,flannel.1设备需要知道目的VTEP设备所在的宿主机IP地址。它会查询FDB转发数据库来获取这个信息。7、得到目的宿主机的IP地址后,flannel.1设备会构造一个VXLAN头,其中包含VNIVXLAN Network Identifier等信息。8、然后它会将内部以太网帧和VXLAN头封装在一个UDP包中。UDP的目的端口通常是4789。9、最后这个UDP包会被进一步封装在一个IP包中,源地址是本机IP,目的地址是目标宿主机IP。这个IP包再被封装在一个外部以太网帧中。10、这个完整封装的外部数据帧通过宿主机的物理网卡发送出去。跨节点的 容器AIP10.244.0.2需要向容器BIP10.244.1.3发送数据时解封包过程
当封装后的数据帧到达目标宿主机时会经历以下步骤:1、目标宿主机的物理网卡接收到数据帧发现是一个UDP包目的端口是4789。2、Linux内核识别出这是一个VXLAN包将其转交给对应的VTEP设备flannel.1处理。3、flannel.1设备接收到这个VXLAN包首先会解析VXLAN头检查VNI是否匹配。4、确认VNI匹配后flannel.1设备会解封装出内部以太网帧。5、flannel.1设备查看内部以太网帧的目的MAC地址确认是否是发给自己的。6、如果是发给自己的flannel.1设备会进一步解封装出原始的IP包。7、flannel.1设备将这个IP包转发给docker0网桥。8、docker0网桥根据IP包的目的地址将其转发给对应的容器。9、目标容器B接收到这个IP包完成整个通信过程。vxlan模式下网络数据流向面试说法
1. pod1向pod2发送ping查找pod1路由表,运用veth-pair技术把数据包发送到cni0(10.244.0.1)
2. cni0查找node1路由,把数据包转发到flannel.1
3. flannel.1虚拟网卡设备对,收到报文后将按照vtep的配置进行封包,首先通过etcd得知pod2属于Node2,并得到node2ip地址,然后通过节点A中的转发表得到节点B对应的vtep的MAC地址,且这个MAC地址不是通过组播学习的,而是通过Api server处watch Node发现的,根据flannel1.1设备创建时的设置参数(VNI、local、IP、PORT)进行封包。
4. 通过node1与node2直接的网络连接,vxlan包到达node2的eth1接口
5. 通过UDP端口8472传输VXLAN数据包给vtep设备flannel.1进行解包
6. 解封装后的IP包匹配node2中的路由表,内核将IP包转发给cni0
7. cni0网桥再把数据包转发给pod2四、UDP模式和VXLAN模式对比总结
对比udp模式vxlan模式性能对比UDP模式的主要性能瓶颈来自于频繁的用户态和内核态切换以及多次数据拷贝。每个数据包都需要经过用户态的flanneld进程处理这不可避免地引入了额外的延迟和CPU开销。特别是在高吞吐量的场景下这种开销会变得相当显著VXLAN模式的大部分操作都在内核态完成。数据包的封装和解封装过程由Linux内核直接处理避免了频繁的状态切换和数据拷贝。这使得VXLAN模式能够提供更低的延迟和更高的吞吐量可扩展性UDP模式中所有的网络流量都需要经过用户态的flanneld进程处理。这意味着flanneld进程可能成为性能瓶颈特别是在大规模集群中。随着节点数量的增加这个问题会变得更加明显。VXLAN模式则不存在这个问题。由于数据包的处理都在内核态完成它能够更好地利用现代多核处理器的能力。此外VXLAN的设计本身就考虑了大规模网络的需求它支持高达16777216个虚拟网络远远超过了大多数实际场景的需求网络隔离UDP模式的网络隔离能力相对有限。虽然它也可以通过配置实现一定程度的网络隔离但灵活性和可扩展性都不如VXLAN模式VXLAN模式提供了更好的支持。VXLAN使用VNIVXLAN Network Identifier来标识不同的虚拟网络这使得在同一物理网络上可以轻松创建多个相互隔离的虚拟网络兼容性UDP模式的优势在于它的简单性。它只需要普通的IP网络就可以工作不需要特殊的网络设备支持VXLAN模式则需要网络设备对VXLAN协议的支持
五、Flannel部署
1、官方部署文档(高版本0.26.1)
https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml2、自身环境现使用(低版本0.13)
k8s集群是1.18版本的
---kube-flannel-ds.yml
apiVersion: v1
items:
- apiVersion: apps/v1kind: DaemonSetmetadata:labels:app: flanneltier: nodename: kube-flannel-dsnamespace: kube-systemspec:selector:matchLabels:app: flanneltemplate:metadata:labels:app: flanneltier: nodespec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/osoperator: Invalues:- linuxcontainers:- args:- --ip-masq- --kube-subnet-mgrcommand:- /opt/bin/flanneldenv:- name: POD_NAMEvalueFrom:fieldRef:apiVersion: v1fieldPath: metadata.name- name: POD_NAMESPACEvalueFrom:fieldRef:apiVersion: v1fieldPath: metadata.namespaceimage: quay.io/coreos/flannel:v0.13.1-rc1imagePullPolicy: IfNotPresentname: kube-flannelresources:limits:cpu: 200mmemory: 400Mirequests:cpu: 100mmemory: 200MisecurityContext:capabilities:add:- NET_ADMIN- NET_RAWprivileged: falsevolumeMounts:- mountPath: /run/flannelname: run- mountPath: /etc/kube-flannel/name: flannel-cfgdnsPolicy: ClusterFirsthostNetwork: trueinitContainers:- args:- -f- /etc/kube-flannel/cni-conf.json- /etc/cni/net.d/10-flannel.conflistcommand:- cpimage: quay.io/coreos/flannel:v0.13.1-rc1imagePullPolicy: IfNotPresentname: install-cnivolumeMounts:- mountPath: /etc/cni/net.dname: cni- mountPath: /etc/kube-flannel/name: flannel-cfgpriorityClassName: system-node-criticalrestartPolicy: AlwaysschedulerName: default-schedulersecurityContext: {}serviceAccount: flannelserviceAccountName: flannelterminationGracePeriodSeconds: 30tolerations:- effect: NoScheduleoperator: Existsvolumes:- hostPath:path: /run/flanneltype: name: run- hostPath:path: /etc/cni/net.dtype: name: cni- configMap:defaultMode: 420name: kube-flannel-cfgname: flannel-cfgupdateStrategy:rollingUpdate:maxUnavailable: 1type: RollingUpdate---kube-flannel-cfg
apiVersion: v1
data:cni-conf.json: |{name: cbr0,cniVersion: 0.3.1,plugins: [{type: flannel,delegate: {hairpinMode: true,isDefaultGateway: true}},{type: portmap,capabilities: {portMappings: true}}]}net-conf.json: |{Network: 10.244.0.0/16,Backend: {Type: vxlan}}
kind: ConfigMap
metadata:labels:app: flanneltier: nodename: kube-flannel-cfgnamespace: kube-system---clusterrole-flannel
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: flannel
rules:
- apiGroups:- extensionsresourceNames:- psp.flannel.unprivilegedresources:- podsecuritypoliciesverbs:- use
- apiGroups:- resources:- podsverbs:- get
- apiGroups:- resources:- nodesverbs:- list- watch
- apiGroups:- resources:- nodes/statusverbs:- patch---ClusterRoleBinding-flannel
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: flannel
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: flannel
subjects:
- kind: ServiceAccountname: flannelnamespace: kube-flannel--- serviceAccount
apiVersion: v1
kind: ServiceAccount
metadata:name: flannelnamespace: kube-flannel
secrets:
- name: flannel-token-hclt9---PodSecurityPolicy-flannel
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:name: psp.flannel.unprivilegedannotations:seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/defaultseccomp.security.alpha.kubernetes.io/defaultProfileName: docker/defaultapparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/defaultapparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
spec:allowPrivilegeEscalation: falseallowedCapabilities:- NET_ADMIN- NET_RAWallowedHostPaths:- pathPrefix: /etc/cni/net.d- pathPrefix: /etc/kube-flannel- pathPrefix: /run/flanneldefaultAllowPrivilegeEscalation: falsefsGroup:rule: RunAsAnyhostNetwork: truehostPorts:- max: 65535min: 0runAsUser:rule: RunAsAnyseLinux:rule: RunAsAnysupplementalGroups:rule: RunAsAnyvolumes:- configMap- secret- emptyDir- hostPath总结
本文主要分析了 Flannel 这一流行的容器网络方案的 UDP 和 VXLAN 两种主要工作模式的原理和实现。从容器网络通信的挑战出发介绍了 Flannel 的设计思路和核心概念包括子网分配、封包解包过程、ARP 记录管理等。通过对比 UDP 和 VXLAN 模式的性能和复杂度理解了 VXLAN 模式在实际生产环境中更受欢迎的原因以及UDP没落的原因