写点什么

剖析 Flannel VXLAN 模式工作原理

作者:Chank
  • 2023-01-15
    广东
  • 本文字数:1819 字

    阅读完需:约 6 分钟

最近学习研究了一下容器网络 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):

kind: ClusterapiVersion: kind.x-k8s.io/v1alpha4nodes:- role: control-plane- role: worker- role: workernetworking:  # the default CNI will not be installed  disableDefaultCNI: true
复制代码

Kubernetes 初始化状态

使用 kind 创建集群后,集群的状态如下图所示:

我们主要关注工作节点的 FDB 表、ARP 表跟路由表。


备注

查看 FDB 表:bridge fdb show

查看 ARP 表:arp

查看路由表:route -n

安装完 Flannel,集群状态

使用如下命令安装 Flannel:

kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
复制代码


安装完后集群的状态如下所示:

FDB 表、ARP 表、路由表中红色的条目即安装 Flannel 过程中新增的。可以看出:

  • 路由表则新增了容器子网与 VTEP IP 的解析关系

  • ARP 表新增了 VTEP IP 到 VTEP MAC 的解析关系

  • FDB 表保存的是 VTEP MAC 到 VTEP 所在宿主机 IP 的解析关系

这三张表是容器网络路由的关键,后面会再介绍具体的路由过程。下面先让我们来看看子网的分配流程。

子网分配流程


Flannel 是一台物理机对应一个子网的网络模型,物理机上容器的 IP 都在物理机分配到的子网里分配。因此一个物理机上的容器可以理解为在同一个局域网中,不同物理机上的容器即位于不同的局域网中。

部署完容器,集群状态

接下来我们部署两个容器,让他们分别运行在两个 Worker 节点上,YAML 为:

apiVersion: v1kind: Podmetadata:  name: pod-httpd  labels:    app: apache_webserverspec:  containers:    - name: cntr-httpd      image: httpd:latest      ports:        - containerPort: 80
复制代码

使用 kubectl apply 后集群状态如下所示:

可以看出:

  • 部署容器并不会改变宿主机的路由表,宿主机在转发数据包的时候只需要关心子网就好

  • ARP 表增加了一个容器自身 IP 跟 MAC 的解析记录

  • FDB 表则增加了一个容器自身 MAC 跟对应网络接口的记录


数据处理流程

我们进到 WebServer1,并通过 curl 10.244.2.3 请求另一个宿主机上的容器 WebServer2,使用 tcpdump 抓取各个网络接口的包记录如下(tcpdump -n -e -tttt -A -enn -i eth0 udp):


发送方的数据处理流程:

  1. WebServer1 容器会先将数据包通过 eth0 网络接口给到 cni0(Linux Bridget)

  2. cni0 查找宿主机路由表,发现到 10.244.2.3 要通过 10.244.2.0,通过 ARP 表解析到 10.244.2.0 的 MAC 地址后就将数据包交给 flannel.1

  3. flannel.1 用数据包的 Dest MAC 查看 FDB 表,发现数据包要发到宿主机 172.18.0.3;flannel.1 加上 VXLAN 包头后即通过 UDP 发送出去

接收方的数据处理流程:

  1. WebServer2 所在的宿主机在收到数据包后剥离 UDP 包头后交给 flannel.1

  2. flannel.1 收到数据包后查看 Src IP,发现目标 IP 是 10.244.2.3,然后 flannel.1 查看 ARP 表,发现要给 cni0,最后将传给 cni0 处理

  3. cni0 收到数据包后根据 DEST MAC 转交给相应的容器处理


发布于: 刚刚阅读数: 10
用户头像

Chank

关注

还未添加个人签名 2019-02-06 加入

邮箱:fangliquan@qq.com

评论

发布
暂无评论
剖析Flannel VXLAN模式工作原理_flannel_Chank_InfoQ写作社区