Flannel由CoreOS开发,是k8s最成熟的开源CNI插件之一。它提供了一个开箱即用的网络模型,旨在实现更好的容器和主机间的网络。
Flannel使用K8S集群的现有etcd集群来使用API存储其状态信息,不需要单独配置数据存储。
Flannel通过配置一个3层的IPv4 Overlay
网络来运行。该网络是一个跨越集群中每个节点的大型内部网络,在此Overlay网络中,每个节点都有一个子网,用于在内部分配IP地址。
每个节点会运行一个flanneld的进程,负责子网租赁和管理。
在配置Pod时,每个节点上的网桥接口都会为每个新容器分配一个地址。
- 同一主机中的Pod可以使用网桥进行通信,
- 不同主机上的Pod会使用
flanneld
配置的后端其流量封装在UDP数据包中,以便路由到适当的目标。
Flannel有几种不同类型的后端可用于封装和路由。默认和推荐使用VXLAN
,因为VXLAN
性能更良好并且需要的手动干预更少。
1. Flannel的后端
Flannel通过在每一个节点上启动一个叫flanneld
的进程,负责每一个节点上的子网划分,并将相关配置信息(如各节点的子网网段、外部IP等)保存到etcd中,而具体的网络报文转发交给后端实现。flanneld
启动时通过配置文件指定不同的后端进行网络通信,目前比较成熟的后端有UDP
、VxLAN
(Virtual Extensible Lan)和host-gateway
三种。
backend实现方式 | 适用场景 | 优点 | 限制 | 基于哪一层 | 实现方式 |
---|---|---|---|---|---|
VxLAN | 普遍适用,官方推荐 | 性能良好,手动干预少(易部署) | 与部分内核不兼容 | 三层网络层 | 使用设备flannel.0进行封包解包,不是内核原生支持,上下文切换较大,性能非常差 |
UDP | 测试、在比较老的不支持VXLAN的Linux内核部署 | 简单、兼容性好 | 性能差 | 三层网络层 | 使用flannel.1进行封包解包,内核原生支持 |
host-gateway | 网络性能要求比较高的场景 | 网络性能高 | 对基础网络架构有要求 | 二层网络 | 无需flannel.1这样的中间设备,直接宿主机当作子网的下一跳地址,性能最强 |
1.1 VxLan模式详解
VXLAN Overlay(L2 in UDP): 采用内置在Linux内核里的标准协议,因此虽然它的封包结构比UDP模式复杂,但由于所有数据装、解包过程均在内核中完成,实际的传输速度要比UDP模式快许多。
| HostMac | HostIP | UDP | vxlan | RealMac | RealIP | Data |
flanneld服务为无状态服务,在每个节点启动一个flanneld服务,监听端口为8472
(VXLAN),其它节点会用一个随机端口连接到目标主机的8472端口,采用UDP协议进行发布。
如下面一条抓包数据所示:
源 192.168.1.1节点的pod[10.42.1.2] 中去ping 目的 192.168.1.2节点的pod[10.42.2.6],抓取源主机 192.168.1.1 的enp0s3
设备的udp
包:
|
|
192.168.1.1.39338 > 192.168.1.2.8472
: UDP 数据包的源 IP 地址是 192.168.1.1,源端口号是 39338,目标 IP 地址是 192.168.1.2,目标端口号是 8472
以太网帧信息:
f2:60:ca:96:7f:1f > 4a:02:36:26:f9:c1
:源 MAC 地址是 f2:60:ca:96:7f:1f[192.168.1.1 enp0s3],目标 MAC 地址是 4a:02:36:26:f9:c1[192.168.1.2 enp0s3]。ethertype IPv4 (0x0800)
:以太网帧的类型为 IPv4。length 98
:数据包的总长度为 98 字节。
最后是 IPv4 报文的信息:
10.42.1.2.10384 > 10.42.2.6.443
:TCP数据包的源IP地址是10.42.1.2
,源端口号是10384
,目标IP地址是10.42.2.6
,目标端口号是443
Flags [S]
:TCP 数据包的标志字段,其中 [S] 表示该数据包是一个 TCP 连接的初始 SYN 数据包。cksum 0x1589 (incorrect -> 0x6701)
:TCP 数据包的校验和字段,当前显示的是错误的校验和。seq 1841703998
:TCP 数据包的序列号。win 64240
:TCP 数据包的窗口大小。
1.2 UDP模式
UDP Overlay(IP in UDP): 使用了Flannel自定义的一种包头协议,数据是在Linux的用户态进行封包\解包,因此当数据进入主机后,需要经历两次内核态到用户态的转换。
| HostMac | HostIP | UDP | RealIP | Data |
1.3 host-gateway模式
与前两种模式(覆盖网络)不同,host-gw采取的是主机路由的方案
这种方案的思路是,既然在无法进行路由是因为网络中的节点之间没有路由信息,但Flannel是知道这个信息的,Flannel把这个信息告诉网络上的节点
| RealIP | Data |
Flannel通过在各个节点上的Agent进程,将容器网络的路由信息刷到主机的路由表上,这样一来所有的主机就都有整个容器网络的路由数据了。
Host-Gateway的方式没有引入像Overlay中的额外装包解包操作,完全是普通的网络路由机制,它的效率与虚拟机直接的通信相差无几。
然而,由于Flannel只能够修改各个主机的路由表,一旦主机直接隔了个其他路由设备,比如三层路由器,这个包就会在路由设备上被丢掉。
这样一来,Host-Gateway的模式就只能用于二层直接可达的网络,由于广播风暴的问题,这种网络通常是比较小规模的,但近年来也出现了一些专门的设备能够构建出大规模的二层网络(就是我们经常听到的“大二层”网络)。
2. 封装流量加密
默认情况下,封装的流量是不加密的。Flannel 提供了两种加密方案,可以在 Kubernetes 集群的工作节点之间建立加密隧道:
- IPSec:使用 strongSwan 在 Kubernetes worker 之间建立加密的 IPSec 隧道。它是加密的实验性后端。
- WireGuard:比 strongSwan 更快的替代方案。
3. 总结
Flannel 以其简单而有效的网络模型而闻名,这对于初学者来说是一个巨大的优势。以下是 Flannel 的主要亮点:
简单有效的网络模型
Flannel 提供了一个简单但高效的网络模型,特别适合那些希望迅速入门k8s网络的初学者。它使用了一种称为VXLAN(Virtual Extensible LAN)的技术,
将容器放置在一个逻辑二层(L2)网络中,无需分配路由。这使得容器之间的通信变得非常容易管理,而无需复杂的配置。流量传输的无缝控制
Flannel 的网络模型允许在主机之间实现无缝的流量传输。这对于集群管理员来说是一个关键的优势,因为它可以确保容器之间的通信顺畅,同时不会引入额外的延迟或瓶颈。
Flannel 将网络控制平面信息交换成轻量级的 UDP 包,从而实现了对 MAC 地址的访问控制,确保了通信的安全性。集成和易用性
Flannel 是一个广泛使用的 CNI 插件,因此它与各种 Kubernetes 部署环境和工具集成良好。对于初学者来说,这使得部署和管理k8s集群变得更加容易。
而且,Flannel 不仅易于使用,还易于配置,这对于初学者来说是一个额外的好处。
总之,对于想要入门k8s网络的初学者,Flannel 提供了一个出色的起点。其简单而高效的网络模型以及与k8s生态系统的广泛集成,使其成为学习和掌握容器网络基础的理想选择。
通过Flannel,你可以在不陷入复杂性的情况下,快速搭建起稳定的k8s网络基础,为你的容器化应用提供可靠的网络通信支持。