剖析 Flannel VXLAN 模式工作原理
最近学习研究了一下容器网络 Flannel。Flannel 是相对比较完整的、相对简单点的、可用于生产环境的容器网络框架。
什么是 VXLAN
VXLAN(Virtual eXtensible Local Area Network)是一种虚拟化隧道技术,通过 Overlay 技术在三层网络上构建二层虚拟网络。VXLAN 的逻辑架构如下图所示:
在 VXLAN 网络中,最重要的就是 VTEP(VXLAN Tunnel Endpoints,VXLAN 隧道端点)。VTEP 作为隧道端点,负责对原始二层网络包进行封包跟解包处理,即将原始二层网络包通过 UDP 协议在底层物理网络进行传输。VTEP 可以是一台物理交换机,也可以是在 Linux 宿主机内核态的一个 VXLAN 虚拟设备。
了解了 VXLAN 的逻辑架构跟 VTEP,下面让我们来看看 VXLAN 协议:
VXLAN 协议中最重要的便是 VXLAN Header,VTEP 在给原始二层网络包加上 VXLAN Header 之后便通过 UDP 协议发送出去。VXLAN Header 也比较简单:
VXLAN Header 中最重要的便是 VNI(VXLAN Network Identifier)。VXLAN 的一个主要设计就是为了支持多租户,VNI 就是租户 ID。VNI 有 24 位,最多可以支持 2^24=16777216 个租户,而传统的 VLAN 只支持 4096 个租户,远远多于 VLAN。
Flannel 整体架构
Flannel 最主要的两个组件便是 flanneld 跟 flannel.1:
flanneld:控制面,运行在用户态,负责为宿主机分配子网,并监听 etcd,维护宿主机的 FDB/ARP 跟路由表
flannel.1:数据面,运行在内核态,作为 VTEP,VXLAN 数据包的封包跟解包
了解了 Flannel 的整体架构,下面就让我们在实践中一步一步剖析 Flannel 的工作原理。
实践环境
Docker Desktop 4.6.1(开启 Docker Desktop 自带的 Kubernetes)
kind(Kubernetes in Docker)
使用如下 kind 配置搭建一个本地 Kubernetes 集群(1 个 master 节点,2 个 worker 节点,禁用 kind 自带的 CNI):
Kubernetes 初始化状态
使用 kind 创建集群后,集群的状态如下图所示:
我们主要关注工作节点的 FDB 表、ARP 表跟路由表。
备注
查看 FDB 表:bridge fdb show
查看 ARP 表:arp
查看路由表:route -n
安装完 Flannel,集群状态
使用如下命令安装 Flannel:
安装完后集群的状态如下所示:
FDB 表、ARP 表、路由表中红色的条目即安装 Flannel 过程中新增的。可以看出:
路由表则新增了容器子网与 VTEP IP 的解析关系
ARP 表新增了 VTEP IP 到 VTEP MAC 的解析关系
FDB 表保存的是 VTEP MAC 到 VTEP 所在宿主机 IP 的解析关系
这三张表是容器网络路由的关键,后面会再介绍具体的路由过程。下面先让我们来看看子网的分配流程。
子网分配流程
Flannel 是一台物理机对应一个子网的网络模型,物理机上容器的 IP 都在物理机分配到的子网里分配。因此一个物理机上的容器可以理解为在同一个局域网中,不同物理机上的容器即位于不同的局域网中。
部署完容器,集群状态
接下来我们部署两个容器,让他们分别运行在两个 Worker 节点上,YAML 为:
使用 kubectl apply 后集群状态如下所示:
可以看出:
部署容器并不会改变宿主机的路由表,宿主机在转发数据包的时候只需要关心子网就好
ARP 表增加了一个容器自身 IP 跟 MAC 的解析记录
FDB 表则增加了一个容器自身 MAC 跟对应网络接口的记录
数据处理流程
我们进到 WebServer1,并通过 curl 10.244.2.3 请求另一个宿主机上的容器 WebServer2,使用 tcpdump 抓取各个网络接口的包记录如下(tcpdump -n -e -tttt -A -enn -i eth0 udp):
发送方的数据处理流程:
WebServer1 容器会先将数据包通过 eth0 网络接口给到 cni0(Linux Bridget)
cni0 查找宿主机路由表,发现到 10.244.2.3 要通过 10.244.2.0,通过 ARP 表解析到 10.244.2.0 的 MAC 地址后就将数据包交给 flannel.1
flannel.1 用数据包的 Dest MAC 查看 FDB 表,发现数据包要发到宿主机 172.18.0.3;flannel.1 加上 VXLAN 包头后即通过 UDP 发送出去
接收方的数据处理流程:
WebServer2 所在的宿主机在收到数据包后剥离 UDP 包头后交给 flannel.1
flannel.1 收到数据包后查看 Src IP,发现目标 IP 是 10.244.2.3,然后 flannel.1 查看 ARP 表,发现要给 cni0,最后将传给 cni0 处理
cni0 收到数据包后根据 DEST MAC 转交给相应的容器处理
版权声明: 本文为 InfoQ 作者【Chank】的原创文章。
原文链接:【http://xie.infoq.cn/article/cc4d7525be875292ad3aa298d】。文章转载请联系作者。
评论