逻辑交换机的运作方式
在物理交换机中,Mac-Address-Table 被用于 Ethernet 数据包的转发。然而,在逻辑交换机中,当两个虚拟机相互通信时,底层 vSphere Host 必须知道目标 VM 位于哪个 Host 上,然后通过 VXLAN 封装发送原始 Ethernet Frame。问题来了:Host 如何知道目标 VM 位于哪台 Host 上?
考虑一个有三个 vSphere 主机 A/B/C 的环境,VTEP 为 10.20.10.10/24、10.20.20.11/24、10.20.30.12/24。我们创建了一个逻辑交换机 VXLAN 5001,并在这个逻辑交换机上连接了两个虚拟机 VM1 / VM2。逻辑网段是 192.168.10.0/24,两个虚拟机的 IP 是 101/102,分别位于主机 A 和主机 B 上。
当 VM1 想与 VM2 进行流量传输时,Host A 如何知道 VM2 在哪个 Host 上?
首先我们需要知道的是,NSX 控制器为每个逻辑交换机维护三个表。VTEP 表/MAC 表/ARP 表,解释如下。
VTEP Table
当我们创建一个逻辑交换机时,我们将 VM "插入 "到该逻辑交换机上。简而言之,每个 vSphere Host 必须知道它有哪些 VM,以及 VM 位于哪个逻辑交换机上。当每个虚拟机所在的逻辑交换机发生变化时,vSphere Host 将立即通知 NSX Controller 哪个逻辑交换机连接到这个 Host。
也就是说,Host A 和 Host B 将分别向控制器报告它们有 VXLAN 5001 作为逻辑交换机。然而,Host C 不会发送这个消息,因为它没有任何位于 VXLAN 5001 的虚拟机。
Host C 在 VXLAN 5001 上没有任何 VM,所以在 Controller 的 VTEP 表中不会有 VTEP 10.20.30.12 信息。但要考虑两个条件:
如果在 Host C 上创建了一个新的 VM3 并添加了 VXLAN 5001,Host C 将告诉 Controller 他也有 VXLAN 5001,并且 Controller 上的 VNI 5001 VTEP 表将添加一个新的 10.20.30.12。
如果 VM 2 从 Host B 被 vMotion 到 Host C,Host C 将向 Controller 报告它有 VXLAN 5001,而 Host B 将向控制器报告它没有 VXLAN 5001,因为这个 Controller 上没有更多的虚拟机。
当 VTEP Table 被创建和更新时,Controller 会立即通知每个相关的 vSphere Hosts,因此不仅 Controller 本身,而且每个 vSphere Host 都有一份最新的 VTEP Table,以了解其上有哪些逻辑交换机,以及除了自己以外还有哪些主机也有这个逻辑交换机。主机 A/B 将知道 VXLAN 5001 上的主机包括主机A(10.20.10.10)和主机B(10.20.20.11)。
MAC Table
同样地,每个 vSphere Host 也必须知道它上面的 VM 的 MAC Address 是什么。因此,Host 也会通知 NSX Controller 哪些虚拟机(MAC Address)在它自己的哪个逻辑交换机中。Host A 会告诉 NSX Controller,它在 VXLAN 5001 中有一个 VM 硬件位置 MAC 1,而 Host B 也会告诉 Controller,它有一个 MAC 2。因此,NSX Controller 汇总了这些信息,可以为逻辑交换机 5001 创建 MAC 表。
当然,如果有虚拟机变化或 vMotion 等操作,受影响的主机也会通知 NSX 控制器进行相关更新。这个表只在 NSX 控制器中维护,不会被发送到主机上。
ARP Table
即使没有安装 VMTools,vSphere Host 可能仍然有办法知道每个虚拟机的 IP 地址,包括
如果这个 VM 发送了 DHCP Request,就会从 reply packet 中知道 IP 地址。
只要这个 VM 发送 ARP Request,请求的源 IP 将告诉这个 VM 的地址。
接下来,主机也会向 NSX 控制器发送一个消息,告知自己虚拟机的 MAC 地址和 IP 地址映射。因此,类似地,NSX 控制器会了解每个逻辑交换机上有哪些 IP 地址,以及相应的 MAC 地址。
从上面的讨论中,我们会发现 NSX 控制器实际上集中了每个逻辑交换机的拓扑信息,包括每个交换机建立在哪些主机上,这个交换机上有哪些虚拟机(MAC地址),以及它们对应的 IP 地址。主机 A 如何知道 VM2 在哪个主机上?
首先:VM1 不知道 VM2 的 MAC 地址,所以发出了一个 ARP 请求
此时,vSphere 主机收到这个 ARP 请求,并且不知道主机上缓存中的 VM2 的 MAC 地址,那么主机 A 将向 NSX 控制器发送一个 ARP 请求。然后,主机 A 向 VM1 发送一个 ARP 回复。
(另一种可能是,控制器上的 ARP 表还没有学到 VM2 的 IP 信息。这时,主机将直接使用本地 VTEP 表向 VNI 5001 VTEP 表中的所有服务器发送该 ARP 请求)
接下来,VM1 向 VM2 发送一个 Ethernet 数据包
当主机 A 收到这个数据包时,它将要求控制器查询 VXLAN 5001 的 MAC 表,得到 MAC2 对应的 VTEP 是 10.20.20.11。啊哈,目的地主机已经发现了。这一次,Host A 将在原以太网帧的前面加上 VXLAN 表头。
从底层硬件网络到主机 B 的正常 Hop-By-Hop 数据包传输后,VXLAN 被解包,VXLAN 为 5001,原始以太网帧通过正常的传输机制被发送到 5001 逻辑交换机中的 VM2(通过目的 MAC 地址)。
那么从 VM1 到 VM2 的以太网数据包呢?
因为在 ARP 请求和第一次数据包传输时,主机 A 已经有了相关的知识并放入了 Cache,后续传输同一网络流的数据包时不需要再询问 NSX 控制器,直接进行 VXLAN 封装和传输。
我希望以上步骤可以帮助你理解 NSX 中同一逻辑交换机中的数据包是如何通过底层硬件网络传递到目的地的。这也解释了为什么在 NSX 环境中,通常在 ping 时,第一个数据包的 Latency 会比较大。通常情况下,当 VM 在 NSX 环境中第一次相互通信时,Latency 可能会比较大。
原因是 Host 处理第一个数据包有更多的步骤,包括响应 ARP Request,和向 Controller 询问相关信息。但在第二个数据包之后,Host 的 Cache 已经存储了相关信息,那么随后的网络传输就非常快了。