惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

SecWiki News
SecWiki News
I
InfoQ
The Cloudflare Blog
人人都是产品经理
人人都是产品经理
博客园 - Franky
T
Tailwind CSS Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
博客园_首页
罗磊的独立博客
V
V2EX
李成银的技术随笔
大猫的无限游戏
大猫的无限游戏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
True Tiger Recordings
Vercel News
Vercel News
Cyberwarzone
Cyberwarzone
Cisco Talos Blog
Cisco Talos Blog
F
Fox-IT International blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
M
Microsoft Research Blog - Microsoft Research
Know Your Adversary
Know Your Adversary
爱范儿
爱范儿
The Register - Security
The Register - Security
G
Google Developers Blog
The Hacker News
The Hacker News
Malwarebytes
Malwarebytes
S
Securelist
博客园 - 三生石上(FineUI控件)
Jina AI
Jina AI
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
S
SegmentFault 最新的问题
博客园 - 叶小钗
F
Fortinet All Blogs
Apple Machine Learning Research
Apple Machine Learning Research
宝玉的分享
宝玉的分享
博客园 - 聂微东
T
Threatpost
博客园 - 【当耐特】
D
Docker
P
Privacy & Cybersecurity Law Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
G
GRAHAM CLULEY
V
Visual Studio Blog
C
Cisco Blogs
IT之家
IT之家
S
Security Archives - TechRepublic
Latest news
Latest news
阮一峰的网络日志
阮一峰的网络日志

蛮荆

如何获取更多的免费服务器 Kubernetes 调度器队列 - 设计与实现 Kubernetes 调度器 - 核心流程 Kubernetes Networking Model & CNI Kubernetes 控制器管理总结 Kubernetes CronJob 设计与实现 Kubernetes Job 设计与实现 Kubernetes HPA 设计与实现 Kubernetes Deployment 滚动更新实现原理 Kubernetes GC 设计与实现 Kubernetes Pod 驱逐 - 设计与实现 Kubernetes Daemonset 设计与实现 Kubernetes ReplicaSet 设计与实现 Kubernetes EndPoint 设计与实现 Kubernetes Informer 设计与实现 降本增效之应用优化 (三) 日志存储与检索 Kubernetes Pod 设计与实现 - 创建流程 Kubernetes 探针设计与实现 Unix 编程艺术名句摘录 Kubernetes - CRI 概述 Golang 编译速度为什么这么快? Kubernetes Pod 设计与实现 - Pause 容器 Kubernetes - kube-proxy 代理模式工程优化 Kubernetes 应用最佳实践 - 优雅关闭长连接 Kubernetes Service 类型和会话亲和性 Kubernetes 为什么需要 Ingress Kubernetes 架构 - 控制平面和数据平面 降本增效之应用优化 (二) 大报表 Go 语言如何获取 CPU 利用率 降本增效之应用优化 (一) Redis 业务规则引擎演变过程简述 微服务中的熔断算法 漏桶算法和令牌桶算法 jsonparser 为什么比标准库的 encoding/json 快 10 倍 ? zap 高性能设计与实现 HTTP Router 算法演进 布谷鸟过滤器 fastcache 高性能设计与实现 Web 常见的三个安全问题 ants Code Reading 布谷鸟过滤器 Go 线程安全 map 方案选型 布隆过滤器 死锁、活锁、饥饿、自旋锁 sync.Pool Code Reading Go 内存管理概述 Go netpoll Code Reading goroutine 泄漏与检测 time/Timer Code Reading GMP Scheduler Code Reading Go channel 的 15 条规则和底层实现 为什么 Linux “一切皆文件” context.Context Code Reading runtime/HACKING.md Goland 最佳实践 互联网开发与金庸武学 为什么 Redis 6.0 引入多线程模型? Kubernetes 应用最佳实践 - 金丝雀发布 容器中如何正确配置 GOMAXPROCS ? singleflight Code Reading sync.Map Code Reading sync.Cond Code Reading sync.WaitGroup Code Reading sync.RWMutex Code Reading sync.Mutex Code Reading sync.Once Code Reading Go 无锁编程 sync/atomic Code Reading goroutine 交替打印奇偶数 GODEBUG Go 并发模式 Go 汇编 UUID 通用技术选型 Kubernetes 应用最佳实践 - 水平自动伸缩 Go 高性能 Tips fasthttp 为什么比标准库 net/http 快 10 倍 ? 技术文章配图指南 ChatGPT 初体验 Docker 网络原理概览 iptables 的五表五链 Kubernetes 应用最佳实践 - 亲和性和污点容忍度 Go 的反射与三大定律 Docker 官方提供的最佳实践 Go 语言内置的设计模式 HTTP1 到 HTTP3 的工程优化 Kubernetes 应用最佳实践 - Sidecar 模式 Kubernetes 应用最佳实践 - init 容器和钩子函数 为什么 recover 必须在 defer 中调用? 为什么 defer 的执行顺序和注册顺序不同? Go map 设计与实现 Go 切片扩容底层实现 Go 语言中的零拷贝 Go Delve 云原生和边缘计算简介 Kubernetes Pod 服务质量等级 Kubernetes 应用最佳实践 - 探针 Kubernetes 应用最佳实践 - 资源请求和限制 CDN 原理 Kubernetes 应用最佳实践 - 开篇 缓存策略和模式
为什么需要 VXLAN 网络
2023-01-12 · via 蛮荆

2023-01-12 计算机网络

概述

VXLAN (Virtual Extensible LAN) 是一种网络虚拟化技术,主要用于解决传统数据中心网络面临的可伸缩性和灵活性的问题。通过在已有网络基础上创建一个逻辑上的 Overlay 覆盖网络,实现了跨物理网络的虚拟局域网(VLAN)扩展。

解决了哪些问题 ?

突破 VLAN 数量限制

VLAN 标志符

传统的 VLAN 使用 12 位的标志符作为虚拟网络的区分标识,最多可以提供 2^12 = 4096 个虚拟网络,这对于大型数据中心和多租户需求来说是远远不够的。

VXLAN 标志符

VXLAN 使用 24 位的标志符作为虚拟网络的区分标识,最多可以提供 1600万+ (2^24 = 16777216) 个虚拟网络,极大地扩展了网络的规模。

虽然 VXLAN 可以提供更多的虚拟网络,但是它并不会完全取代 VLAN, 例如在大型数据中心,可能会同时使用这两种网络标准,使用 VXLAN 将租户进行隔离,同时单个租户可以基于其 VXLAN 创建内部的 VLAN。

提升网络虚拟化的可扩展性

VXLAN 将网络虚拟化推到三层网络,减少了二层网络中的广播风暴问题,提高了网络的可伸缩性,(当然这个功能使用 VLAN 也可以实现)。

跨子网通信

传统的 VLAN 基于二层网络通信,虚拟机无法跨越不同的子网通信,而 VXLAN 基于三层网络通信,可以将二层网络的数据封装之后进行传输,实现跨子网的虚拟机通信。

图片来源: https://info.support.huawei.com/info-finder/encyclopedia/zh/VXLAN.html

减少 MAC 表消耗

VXLAN 采用采用隧道传输机制,交换机 (一般位于机架顶部) 无须在 MAC 表中记录虚拟机的信息,这样可以使二层网络保持低资源消耗,避免交换机的 MAC 表溢出。

充分利用网络路径

STP (Spanning Tree Protocol) 是一种用于防止网络中发生环路的协议,但它的作用是通过选择一条活跃路径,而将其他冗余路径阻塞,从而确保网络拓扑是无环的。

图片来源: https://www.cisco.com/c/zh_cn/support/docs/lan-switching/spanning-tree-protocol/10556-16.html

传统的的基于 STP 的 VLAN 部署中可能遇到的一个问题: 如果每个 VLAN 都独立运行 STP,可能导致网络路径的浪费。这是因为 STP 对于整个交换网络来说是全局的,而不是基于单个 VLAN 的。 因此,STP 将会为整个交换网络选择一条活跃路径,并将其他冗余路径阻塞,而这种选择是基于整个网络而不是基于单个 VLAN。

VXLAN 的数据包是封装到 UDP 通过三层网络传输和转发的,可以有效使用所有的网络路径。

图片来源: https://www.cisco.com/c/zh_cn/support/docs/lan-switching/spanning-tree-protocol/10556-16.html

虚拟机迁移

传统的 VLAN 中的虚拟机在迁移之前,需要在目标子网上面重新配置 VLAN,而 VXLAN 允许虚拟网络横跨物理网络的子网,避免虚拟机跨越三层网络,使得虚拟机可以在不同的 IP 子网中移动而不受限制,减少了迁移复杂性。

例如,当虚拟机所在宿主机因为故障或其他原因需要停机维护时,就需要将虚拟机迁移到其他宿主机中,为了保证业务的可持续性服务,迁移过程中虚拟机的 IP 地址不能发生变化, VXLAN 保证只要虚拟机迁移后仍然处于同一个二层网络,就不需要改变 IP 地址。

多租户环境增强

VXLAN 支持多租户环境,使得不同租户的数据可以在同一物理网络基础上独立传输,并允许 IP 地址空间重叠,避免了流量数据泄露和潜在的安全隐患,此外还可以使用差异化的服务质量 (QoS) 策略和服务级别协议 (SLA) 配置网段。


实现原理

本质上就是参考了 OSI 网络模型的设计中数据封装和转发,VxLAN 使用虚拟隧道端点(Virtual Tunnel End Point、VTEP)设备对服务器发出和收到的数据包进行二次封装和拆包,将原本在二层网络传输的 以太帧 封装到网络四层的 UDP 数据包中,同时加入自定义的 VXLAN 协议 Header 首部。这样就可以在已有的网络基础上跨越各类设备通信,包括防火墙和路由器。

传输协议

VXLAN 使用网络层的 IP 协议 + 传输层的 UDP 协议完成传输,通过定义一个数据封装格式,在原始的二层网络数据包之前加上 VXLAN Header, 然后放入 UDP 和 IP 数据包中, 这样就完成了基于三层网络建立的二层网络隧道。

头部格式

VXLAN 头部格式

由 8 个字节组成,包括标志位、VNI 标志符和其他控制信息,这种紧凑的头部设计有助于降低额外的网络开销。

  • 标志位 (Flags): 8 比特,用于标识 VXLAN 头部的特性,目前只使用了最低位(bit 0),该位为 “I” 比特,表示 VXLAN 包是否包含附加的 VXLAN 标头
  • 保留位 (Reserved): 24 比特,保留用于将来扩展协议时使用
  • VXLAN 网络标识符 (VNI - VXLAN Network Identifier): 24 比特,用于标识 VXLAN 网络的唯一标识符,每个 VXLAN 网络都应该有一个唯一的 VNI (也就是用一个数字标识一个虚拟网络)
  • 原始以太网帧 (Original L2 Frame): 用于携带实际的网络数据包,也就是封装在 VXLAN 头部中的原始以太网帧

VXLAN 头部设置完成之后,会被层层封装: UDP -> IP -> MAC, 如图所示,最终形成的数据包会通过三层网络发出。

  • Outer UDP Header: 封装 原始二层以太帧 + VXLAN Header, 源 VXLAN 端口号通常是动态随机分配的,目的 VXLAN 端口号通常固定为 4789
  • Outer IP Header: 封装 IP Header, 由 VTEP 设备完成,也就是 源 IP 地址 (VTEP 的 IP 地址)目的 IP 地址 (对端 VTEP 的 IP 地址)
  • Outer MAC Header: 封装 MAC Header, 由 VTEP 设备完成,也就是 源 MAC 地址 (VTEP 的 MAC 地址)目的 MAC 地址 (下一跳的网络(路由)设备 MAC 地址)

VTEP

图片来源: https://blogs.salleurl.edu/en/data-center-interconnect

VTEP (VXLAN Tunnel Endpoint) 是 VXLAN 的关键组件,负责将 VXLAN 虚拟网络数据包进行封装和解封装,VTEP 既可以是网络物理设备 (交换机) 也可以是虚拟设备 (普通服务器通过软件实现的,例如 KVM)

每个 VTEP 设备都会被分配一个独立的 IP 地址和一个 VNI 标志,用于标识该设备在物理网络中的位置,这个 IP 地址通常是在 VTEP 设备的物理接口或逻辑接口上配置的。 该 IP 地址在 VXLAN 报文头部中被使用,便于在数据包封装和解封的过程中识别出 源 VTEP 和目标 VTEP。两个 VTEP 设备之间会创建无状态隧道用于传输数据。

VXLAN 独立于底层的物理网络拓扑,反过来,两个 VTEP 之间的底层 IP 网络也独立于 VXLAN。

由于 VXLAN 封装在 UDP 数据包内,因此它们可以在任何能够传输 UDP 数据包的网络上运行,只需要保证 UDP 数据报可以从封装 VTEP 转发到解封装 VTEP 即可,底层网络节点之间的物理布局和地理距离并不重要。

封装和解封装过程

图片来源: https://blogs.salleurl.edu/en/data-center-interconnect

发送端封装

当一个主机 (物理主机或虚拟机) 要发送数据包到另一个主机时,VTEP 设备负责将原始的以太网帧封装到 VXLAN 数据报文中,封装的过程包括在原始帧上加上 VXLAN Header, 其中包含 VXLAN 网络标识符 (VNI),以及 源 VTEP 和目标 VTEP 的 IP 地址信息,这样原始帧就变为一个 VXLAN 帧。

接收端解封装

接收端的目标 VTEP 通过解析 VXLAN Header,识别出 VXLAN 网络标识符 (VNI),并将原始帧从 VXLAN 封装报文中解析出来。 然后目标 VTEP 将原始帧发送到目标主机 (物理主机或虚拟机) ,这个解封装的过程允许跨物理网络的虚拟机进行通信,因为基于三层网络的 VXLAN 提供了一种逻辑隔离和扩展机制。

通过数据包封装和解封装,底层网络所做的转换工作对于通信的双方来说是透明的


通信过程

转载声明:本小节内容主要来源于 这篇文章, 笔者在自己理解的基础之上对排版和文字进行部分修改。

网络拓扑结构

图片来源: https://support.huawei.com/enterprise/zh/doc/EDOC1100087027/f10c6c1d

如图所示,虚拟机 (VM_A)、虚拟机 (VM_B) 、虚拟机 (VM_C) 同属一个子网: 10.1.1.0/24, 并且同属一个 VNI/5000,此时 VM_A 想与 VM_C 进行通信, 这中间的通信过程是什么样的呢?下面跟着流程图一起看来下。

为了方便展示和联系上下文,下文中的设备名称和地址等直接使用简写,例如

  • VM_A 表示虚拟机 A
  • MAC_B 表示虚拟机 B 的 MAC 地址
  • IP_C 表示虚拟机 C 的 IP 地址
  • VTEP_1 表示编号为 1 的 VTEP 设备

ARP 请求报文转发流程

由于是首次进行通信,VM_A 上没有 VM_C 的 MAC 地址,所以会发送 ARP 广播请求 VM_C 的 MAC 地址。

图片来源: https://support.huawei.com/enterprise/zh/doc/EDOC1100087027/f10c6c1d

1. VM_A 发送 ARP 广播请求报文

源 MAC 地址 MAC_A
目的 MAC 地址 FF:FF:FF:FF:FF:FF
源 IP 地址 IP_A
目的 IP 地址 IP_C

2. VTEP_1 封装 ARP 请求报文

VTEP_1 收到 ARP 请求报文之后,会依次进行如下工作:

  • 根据二层子接口上的配置判断请求报文需要进入 VXLAN 隧道
  • 确定请求报文所属广播域,也就确定了报文所属 VNI
  • 学习 VM_A 的 MAC_A + VNI + Port (二层子接口对应的物理接口) 的映射关系,并记录在 MAC 表中
  • 对请求报文进行封装,封装之后的报文如下
源 MAC 地址 VTEP_1 的 MAC 地址
目的 MAC 地址 网络中下一跳设备的 MAC 地址
源 IP 地址 VTEP_1 的 IP 地址
目的 IP 地址 对端 VTEP 设备的 IP 地址 (也就是 VTEP_2, VTEP_3 的 IP 地址)

需要注意的是: 实际场景中,对端 VTEP 设备可能有 N 个,那么就会发出 N 个封装后的报文请求。

3. ARP 请求报文解封装

请求报文到达 VTEP_2, VTEP_3 之后,两者会依次进行如下工作:

  • 对报文进行解封装,得到 VM_A 的原始 ARP 请求报文
  • 学习 VM_A 的 MAC_A + VNI + 对端 VTEP_1 IP 地址 的映射关系,并记录在各自的 MAC 表中
  • 根据二层子接口上的配置对报文进行处理,并在各自对应的二层域内进行广播
  • VM_B 和 VM_C 接收到 VM_A 的原始 ARP 请求报文之后,比较目的 IP 地址是否为自己的 IP 地址
  • VM_B 发现目的 IP 地址不是自己,直接将请求报文丢弃,没有后文了 …
  • VM_C 发现目的 IP 地址是自己,学习 VM_A 的 MAC_A + IP 并记录在 ARP 缓存表中,并且对 VM_A 的 ARP 请求做出应答

从 VM_A 上发出的原始 ARP 请求报文经过层层封装和转发,终于到达了目的地 VM_C,这中间经过了一次广播 (或多播, 取决于具体的配置),因为 VTEP 设备有自动学习的能力, 所以请求沿途经过和到达的 VTEP 设备都将各自需要的映射信息记录在各自的 MAC 表中。

接下来,我们看看 VM_C 是如何应答 VM_A 的 ARP 请求的。

ARP 响应报文转发流程

图片来源: https://support.huawei.com/enterprise/zh/doc/EDOC1100087027/f10c6c1d

1. VM_C 发出应答报文

因为 VM_C 已经学习了 VM_A 的 MAC + IP 记录,所以 ARP 应答报文为单播

源 MAC 地址 MAC_C
目的 MAC 地址 MAC_A
源 IP 地址 IP_C
目的 IP 地址 IP_A

通过报文我们可以看到,VM_C 的应答报文 和 VM_A 的请求报文正好反过来。

2. VTEP_3 封装 ARP 应答报文

VTEP_3 收到 ARP 应答报文之后,会依次进行如下工作:

  • 根据二层子接口上的配置判断请求报文需要进入 VXLAN 隧道,识别报文所属 VNI
  • 学习 VM_C 的 MAC_A + VNI + Port (二层子接口对应的物理接口) 的映射关系,并记录在 MAC 表中
  • 对应答报文进行封装,封装之后的报文如下
源 MAC 地址 VTEP_3 的 MAC 地址
目的 MAC 地址 网络中下一跳设备的 MAC 地址
源 IP 地址 VTEP_3 的 IP 地址
目的 IP 地址 VTEP_1 的 IP 地址

3. ARP 应答报文解封装

ARP 应答报文到达 VTEP_1 之后,会依次进行如下工作:

  • 对报文进行解封装,得到 VM_C 的原始 ARP 应答报文
  • 学习 VM_C 的 MAC_C + VNI + 对端 VTEP_3 IP 地址 的映射关系,并记录在 MAC 表中
  • VTEP_1 将应答报文发送给 VM_A
  • VM_A 学习 VM_C 的 MAC_A + IP 并记录在 ARP 缓存表中

到了这里,从 VM_A 发起的 ARP 请求到应答通信过程就结束了,因为 VM_A 和 VM_C 都学习到了对方的 MAC + IP 地址,后续两者之间的通信会直接采用单播。

小结

在 VM_A 和 VM_C 的整个通信过程中,只有发出一次广播 (或多播, 取决于具体的配置),得益于 VTEP 设备的自动学习能力,后续的报文都是通过单播直接发送的。 可以想象,如果 VTEP 设备没有自动学习能力的话,在 VTEP 数量很多的情况下,依然会产生 ARP 广播风暴问题。 除了本文提到的广播 (多播) 学习模式外,还可以通过 SDN 模式的分布式控制中心来管理整个 VXLAN 网络,限于笔者工作经验和篇幅,本文不再展开,感兴趣的读者可以自行查找相关资料。

限于篇幅,本文只介绍同一子网内 VXLAN 的通信过程,对于不同子网 VXLAN 的通信过程,本质上就是在不同的 VTEP 设备之间加入了网关,以及不同子网使用不同的 VNI, 报文的封装、转发、解封装、MAC 学习等机制和同一子网内通信机制是类似的,相信读者可以在前文的基础上理解具体的差异。

Reference