背景
虚拟化嵌套
今天在ESXi
的虚拟化平台下,通过虚拟机搭建了一台Linux KVM
的虚拟化服务器,
然后在KVM
服务器中又再次虚拟安装了一台CentOS8
的GuestOS
ESXi ---虚拟---> Linux KVM ---虚拟---> CentOS8 Guest
架构如下:
问题
KVM 内部的二层虚拟机与外部 Lan 网络无法通信
从网络架构上来说KVM
和最里面Guest OS
的网卡都是桥接模式,理论上应该能与ESXi
所接入的物理LAN网络之间正常通讯,且应该可以通过物理网络中的防火墙正常访问Internet
才对。
但是实际情况是二次虚拟的CentOS8
能ping
通Linux KVM
的IP
但无法与同网段的其他任何IP通讯;
确定CentOS8
发出的数据包出不了KVM
的范围,也就是到不了ESXi
外面的网络,在物理Lan的防火墙上抓包也看不到任何从CentOS8
发出的数据包;
尝试开启了Linux KVM
的net.ipv4.ip_forward
转发也不行
分析CentOS8
能正常与它的宿主KVM
的IP通讯,说明CentOS8
的网络配置和KVM
的桥接设定都是没有问题的;
那么应该只有一种可能,就是 ESXi 阻止了KVM
对外发送数据包的传输;
这里有一个概念,在ESXi
的视角Linux KVM
是他内部的一个普通Guest
主机,那么ESXi
会通过虚拟交换机vSwitch0
或者是端口组来管理这个Guest
主机所发出的数据帧,且默认规则是Guest主机的一个虚拟网卡有且也只能允许用一个固定的MAC
地址来发送自己的数据包,这是一个接入网络的普通终端所应该具有的正常行为;
但是我们在ESXi
内部虚拟的这台Linux KVM
它不是一台普通接入的终端,它的虚拟网卡(KVM
系统内部的eth0
网卡)实际是与KVM
内部二次虚拟的CentOS8
的虚拟网卡进行桥接的,当CentOS8
要对外部网络发送数据时,Linux KVM
需要通过自己的eth0网卡作为网桥来进行二层的桢转发,此时数据帧的源MAC地址会封装成CentOS8
的网卡MAC,这种行为在ESXi
的vSwitch0
看来,就是MAC地址伪造,它的Guest
主机(Linux KVM
)的网卡在用其他的MAC
(CentOS8的虚拟网卡MAC地址)地址发出数据帧,这种情况默认ESXi
是禁止的,数据帧会被vSwitch0
直接丢弃,自然外部网络就收不到任何来自CetnOS8
发出的数据包了;
解决方案
配置ESXi
上的vSwitch
虚拟交换机,将安全设置中的混杂模式
和伪传输
这两项设置为允许即可,如下图:
不过修改vSwitch
的设置会影响到所有连接到这个交换机的虚拟机,
如果只希望针对个别的虚拟机开启混杂模式
和伪传输
,可以为这些虚拟机单独建立一个端口组portgroups
,然后在该端口组的安全设置中开启混杂模式
和伪传输
,设置如下:
经过测试验证,混杂模式
和伪传输
这两项要同时允许才可以恢复通讯,
而MAC地址更改
选项似乎对这个问题并没有影响,建议保持默认不启用;