在 Hyper-V 上运行 Linux 云镜像虚拟机
一些 Linux 发行版提供了云镜像,云镜像通常有更小的体积,可以更方便初始化配置,相较于传统的镜像更适合运行在虚拟机或虚拟化平台上,Debian、Fedora、Ubuntu、Alma Linux 等都提供了云镜像。
大多数的云镜像都是使用 cloud-init 进行初始化。下面将介绍如何在 Hyper-V 上运行 Debian 12 云镜像。
要解决的问题
镜像格式:Debian 并未提供 VHDX 格式的镜像,所以需使用 qemu-img
将 qcow2 镜像转换为 VHDX 才可用于 Hyper-V。
向虚拟机提供配置:可选择的方式很多,这里用文件系统的方式提供配置。后文将描述如何创建一个含有配置的 ISO 镜像。
将 qcow2 格式镜像转换为 VHDX 镜像
# 如果没有将 qemu 添加到环境变量中,可为其设置别名
Set-Alias qemu-img $env:ProgramFiles\qemu\qemu-img.exe
$cloudImage = 'C:\debian-12-genericcloud-amd64.qcow2'
qemu-img convert -f qcow2 $cloudImage -O vhdx C:\debian.1.vhdx
qume-img
转换出来的 VHDX 在文件系统中存储是松散的,通过命令 fsutil file layout C:\debian.1.vhdx
可知。Hyper-V 要求虚拟磁盘是非松散的,将该 VHDX 用于 Hyper-V 则会报错。最简单的解决方法是再复制一次:
cp C:\debian.1.vhdx C:\debian.vhdx
rm C:\debian.1.vhdx
创建配置提供者
cloud-init 有多种方法可以提供配置,其中一些配置只在首次初始化有效,有些则可以动态更新。这里将创建 ISO 文件来提供配置,创建一个分区名为 CIDATA 的 FAT32 分区也是可行的。
在 Windows 上创建 ISO 可以使用 libarchive 或 Oscdimg。Oscdimg 需要先安装 Windows ADK,这里主要使用 libarchive。其实 libarchive 的 bsdtar
也已经预制在 Windows 中了,现有的 tar
命令就是这个。不过由于系统的版本可能比较陈旧不一定支持。
bsdtar
的命令行使用请参考 FreeBSD 的文档,和广为人知的 GNU Tar 不完全兼容。
在 cidata
目录中创建两个文件 meta-data
和 user-data
:
mkdir cidata
ni cidata\meta-data, cidata\user-data
然后分别写入如下内容(行尾最好使用 LF,未测试 CRLF 是否可行):
meta-data
:
instance-id: instance-0 # 实例 ID
local-hostname: food.example.com # 主机名
user-data
:
#cloud-config
user:
name: foair
password: xR0V3MyFybfWiEeDyTub
chpasswd:
expire: false
ssh:
emit_keys_to_console: false
ssh_authorized_keys:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEIwVXsuc2+oIoNtelRjlGXB5OSdKrBv488BXqt/RCUG
ssh_genkeytypes: [ed25519]
timezone: Asia/Shanghai
使用工具将两个文件封装在一个 ISO 镜像中,后续将用于虚拟机:
$metaDataIso = 'C:\metadata.iso'
# 设置别名避免使用 %SystemRoot%\System32\tar.exe
Set-Alias tar C:\libarchive\bin\bsdtar.exe
tar -C cidata --options volume-id=CIDATA -caf $metaDataIso --no-acls --no-fflags *
# oscdimg cidata $metaDataIso -j2 -lCIDATA
创建虚拟机
下面会使用 PowerShell 来创建虚拟机,也可以考虑在「Hyper-V 管理器」中用鼠标点点点。
# 虚拟机名称、已有的虚拟交换机名称
$VMName = 'Debian'
$virtualSwitchName = 'Default Switch'
# 新建一个虚拟机
New-VM $VMName -MemoryStartupBytes 8GB -VHDPath $vhdx -Generation 2 -SwitchName $virtualSwitchName
# 添加 cloud-init 配置 ISO
Add-VMDvdDrive -VMName $VMName -Path $metaDataIso
# 设置 UEFI 安全启动
Set-VMFirmware -VMName $VMName -SecureBootTemplate MicrosoftUEFICertificateAuthority
# 设置处理器数量
Set-VM -VMName $VMName -ProcessorCount 4
连接虚拟机
Start-VM $VMName
vmconnect localhost $VMName
参考资料
Re: qemu-img - vhdx compatibility with Hyper-V
https://www.mail-archive.com/qemu-discuss@nongnu.org/msg04963.html
MicrosoftDocs/Virtualization-Documentation
https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/main/hyperv-samples/benarm-powershell/Ubuntu-VM-Build/BaseUbuntuBuild.ps1