提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
最近在使用 OpenStack 部署虚拟机时,我碰到了一些有意思的问题。先是我在虚拟机中用 DevStack 部署 OpenStack 后,居然可以再通过 OpenStack 创建虚拟机,这让我不禁好奇:既然 OpenStack 是跑在虚拟机上的,那它是怎么在虚拟机中再创建虚拟机的呢?于是,我查阅了一些资料,发现了一个叫 嵌套虚拟化 的概念。
什么是嵌套虚拟化?
嵌套虚拟化,就是在虚拟机里再运行虚拟机的技术。听起来有点像“虚拟机套娃”,但它确实是可以实现的。简单来说,宿主机通过支持虚拟化扩展(比如 Intel 的 VT-x 或 AMD 的 AMD-V),允许虚拟机像直接使用物理硬件一样,再创建出新的虚拟机。这样,即使你的 OpenStack 运行在虚拟机中,它依然能够创建更多虚拟机。
典型应用场景
开发测试:这特别适合在开发环境中,因为可以用较少的硬件资源来构建复杂的多层虚拟化环境。
生产环境:虽然嵌套虚拟化在开发中很有用,但生产环境一般不推荐使用,因为多层虚拟化会带来性能开销和管理复杂度。
为什么虚拟机里的 CPU 型号变了?
部署完虚拟机后,我用 OpenStack 提供的 cirros 默认镜像创建了一个虚拟机,却发现虚拟机里的 CPU 型号变成了 Intel Core i7 Nehalem,而不是宿主机(也是物理机)上的 Intel Xeon Gold 6240。这其实是因为虚拟化平台为了兼容性,给虚拟机分配了一个**“通用”**的 CPU 模型,而这个虚拟 CPU 并不代表真实的物理硬件性能。
解决方案
如果希望虚拟机能够显示与宿主机相同的 CPU 型号,可以在 libvirt 或者 nova.conf 文件中进行配置:
修改 Nova 配置: 你可以通过修改 nova.conf 文件来设置虚拟机的 CPU 模型,使其与物理 CPU 更接近。找到并编辑 /etc/nova/nova.conf 文件,添加以下配置:
[libvirt]
cpu_mode = host-passthrough
host-passthrough:表示虚拟机将直接使用宿主机的 CPU 指令集和特性。
重启 Nova 计算服务: 修改配置后,重启 Nova 计算服务以使配置生效:
sudo systemctl restart nova-compute
这样做之后,虚拟机应该会看到宿主机的实际 CPU 模型,而不再是 QEMU 模拟的通用 CPU 型号。
原理:
host-passthrough 模式允许虚拟机直接访问宿主机的 CPU 指令集、功能和特性。这意味着虚拟机的处理能力几乎等同于宿主机的 CPU 性能,因为它使用的不是虚拟化层模拟出来的通用 CPU 模型,而是宿主机的真实 CPU。
在默认情况下,虚拟化平台通常会给虚拟机分配一个通用的 CPU 模型(如 Intel Core i7 或 Nehalem),这种通用模型隐藏了宿主机 CPU 的实际特性,以确保虚拟机的跨平台迁移能力。
性能提升
通过 host-passthrough 模式,虚拟机能够直接访问物理 CPU 的全部指令集和扩展功能(如 AVX、SSE 等),理论上能够最大限度地利用宿主机 CPU 的性能。所以 虚拟机的性能与宿主机 CPU 的性能几乎一致,特别是在执行 CPU 密集型任务时,性能会更接近宿主机。
限制
迁移限制:使用 host-passthrough 后,由于虚拟机紧密依赖宿主机的实际 CPU 特性,跨物理机迁移(live migration)会变得困难或不可行,特别是在两台物理主机 CPU 不一致的情况下。
兼容性:有些旧版或特定场景下的虚拟化环境可能对 host-passthrough 支持不完全,或者在设置过程中需要特别的配置来启用这些特性。
实际效果
性能上,它确实能提高虚拟机的处理能力,尤其是在需要完全利用 CPU 特性的应用场景中(如加密运算、压缩、解压、编译等)。
但是,它不会超出宿主机 CPU 的性能上限。换句话说,如果宿主机使用的是 Intel Xeon Gold 6240,即使虚拟机显示的 CPU 名称是 Intel Core i7,它的实际处理能力还是受限于物理主机的 Intel Xeon Gold 规格。
性能问题
虽然虚拟机里显示的是 Intel i7,但它的性能并不会真的和 i7 一样强大。虚拟机的性能主要还是依赖于宿主机的物理资源,嵌套虚拟化环境下,虚拟机的性能可能还会受到额外的虚拟化层影响,导致一些性能损耗。
创建 Ubuntu 虚拟机时,磁盘为什么识别不了?
我还遇到过一个问题,在用 Ubuntu 20 ISO 镜像创建虚拟机时,安装过程中报错提示 “Block probing did not discover any disks”,导致无法安装系统。这通常意味着虚拟机无法识别到磁盘。
原因
我的 Ubuntu20 镜像是 ISO 格式,那么在 OpenStack 中使用 ISO 镜像来创建实例并不合适,因为 OpenStack 需要使用可以直接作为磁盘映像的格式(如 QCOW2 或 RAW)来创建实例。
解决方案
使用 已经安装好的 QCOW2 格式镜像,而不是 Ubuntu 的 ISO 安装镜像。Ubuntu 的官方提供了预装的 QCOW2 镜像,你可以从 Ubuntu Cloud Images CentOS Cloud Images 下载,比如:
wget https://cloud-images.ubuntu.com/releases/focal/release/ubuntu-20.04-server-cloudimg-amd64.img
将下载的 ubuntu-20.04-server-cloudimg-amd64.img 镜像上传到 OpenStack 并选择 qcow2 即可使用。
但是!!!!
启动之后我不知道账号密码呀,无法在控制台登录,所以得在创建实例的时候运行一个脚本去配置密码:
创建实例 → 配置 → 编辑 “定制化脚本” 框,写入如下内容
#!/bin/bash
passwd root<<EOF
12345
12345
EOF
然后创建实例,使用该密码登录即可登录。
上面这里不要参考了,验证过没用,还是老老实实ssh登吧
小结
嵌套虚拟化让我们可以在虚拟机上进一步运行虚拟机,特别适合开发和测试环境,但在生产环境中需要谨慎使用。另外,虽然虚拟机的 CPU 型号可以是虚拟化平台提供的“通用”模型,但这并不代表实际性能。最后,资源分配不足或磁盘配置问题也可能导致虚拟机创建过程中的卡顿和硬件探测失败。