我不太确定如何表述这个问题(因此标题不太好),所以让我举一个例子来说明我正在尝试做的事情。
在我的(旧)Xen 主机上,我能够将 LVM 文件系统直接呈现给每个客户机。这些文件系统实际上是在主机上创建和格式化的,并直接传递。例如,对于我的一台使用单独的 tmp 和 swap 分区的主机,我定义存储如下:
磁盘 = [
'phy:/dev/vg1/guest1-swap,sda1,w',
'phy:/dev/vg1/guest1-disk,sda2,w',
'phy:/dev/vg1/guest1-tmp,sda3,w',
]
因此,guest1-swap 被格式化为交换分区,guest1-disk 和 guest1-tmp 被格式化为 ext4,并且从客户机的角度来看,它只是将它们视为 /dev/sda 下的三个格式化分区。
(这听起来可能很麻烦,但有一些配置脚本,例如xen工具,几乎实现了一切的自动化)。
这提供了一些非常有用的功能,其中两个我特别感兴趣的是 KVM 的功能:
从主机操作系统挂载客户机文件系统。我可以随时对任何客户机文件系统进行只读挂载,即使在客户机运行时也是如此。这还有一个好处,就是允许我在客户机运行时创建任何现有卷的 LVM 快照。这样,我就能够在运行时从主机集中备份我的所有客户机。
在线调整卷大小。因为这些卷包含标准 Linux 文件系统,所以我可以结合使用 lvextend 和 resize2fs 来扩大我的客户文件系统,同样是在它们在线时。
我目前正在设置一个 KVM 主机来替换 Xen 主机。与 Xen 设置类似,我利用 LVM 提供直接文件系统访问,但 KVM/qemu 的行为有所不同,因为它总是为客户机创建映像文件,即使在 LVM 卷上也是如此。从客户机的角度来看,它将其视为未分区的磁盘,客户机需要应用分区标签,然后创建分区和文件系统。
从客户的角度来看,这很好,但从服务器/管理的角度来看,它似乎远不如我描述的 Xen 设置灵活。我对 KVM 还不熟悉,所以我可能(希望)错过了一些东西。
我在尝试在 KVM 主机上重新实施以前的备份解决方案时遇到了这个问题,当我尝试挂载其中一个客户机的文件系统时,挂载命令被阻塞。因此,解决这个问题是我目前关心的问题,但它也让我担心调整大小的问题,因为我确信这个问题在某个时候也会出现。
因此,我的问题是:
有没有办法让 kvm/qemu 直接使用 LVM 卷文件系统,就像我在 Xen 设置中描述的那样?如果这有区别的话,我使用 libvirt 进行管理。
如果没有,我该怎么做才能在 KVM 下获得类似的挂载/备份功能?我见过关于使用 libguestfs 和 FUSE 来执行此操作的讨论,但这真的是最好的选择吗?如果可能的话,我宁愿坚持使用本机文件系统挂载。
另外,如果没有,是否可以在 KVM 下进行在线文件系统大小调整?我找到了几个关于此问题的讨论/操作指南,但答案似乎到处都是,没有明确的,当然也没有直接的解决方案。
抱歉发了这么长的帖子,只是想确保内容清楚。如果我可以提供任何其他有用的信息,请告诉我。期待讨论。:-)
答案1
- qemu-kvm 可以使用 LV 作为虚拟磁盘而不是文件。这实际上是一种相当常见的用例。
- libguestfs(只需寻找一组
virt-*
工具)可以以比直接重新挂载到主机的任何东西更干净的方式提供对客户文件系统的访问,尽管两者都是可能的。 - 在线 FS 大小调整不是 kvm 的功能,但客户操作系统应该能够实现。
resize2fs
在虚拟机中和在物理硬件上一样好用,唯一的问题是客户重新检测大小变化。尝试virt-resize
作为标准工具,但lvresize
也qemu-img
可以轻松使用(尽管在离线模式下,通常需要重新启动客户)。
我认为lvresize
无需resize2fs
重启客户机即可使用,但我还没有尝试过
答案2
我使用 qemu-kvm+libvirt,其配置与你询问的完全相同,原因如你所述,但另外因为我得到了很多在没有 KVM 主机的文件系统层的情况下,性能会更好。如果您在 virt-manager 中将 VG 添加为“存储池”,则可以使用其用户友好的向导创建此类 VM。(但这些天我只是使用现有 VM 作为模板手动编写 XML)。
以下是我的一位客人的“virsh dumpxml”的净化输出:
<domain type='kvm'>
<name>somevm</name>
<uuid>f173d3b5-704c-909e-b597-c5a823ad48c9</uuid>
<description>Windows Server 2008 R2</description>
<memory unit='KiB'>4194304</memory>
<currentMemory unit='KiB'>4194304</currentMemory>
<vcpu placement='static'>2</vcpu>
<os>
<type arch='x86_64' machine='pc-1.1'>hvm</type>
<boot dev='hd'/>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<cpu mode='custom' match='exact'>
<model fallback='allow'>Nehalem</model>
<vendor>Intel</vendor>
<feature policy='require' name='tm2'/>
<feature policy='require' name='est'/>
<feature policy='require' name='monitor'/>
<feature policy='require' name='smx'/>
<feature policy='require' name='ss'/>
<feature policy='require' name='vme'/>
<feature policy='require' name='dtes64'/>
<feature policy='require' name='rdtscp'/>
<feature policy='require' name='ht'/>
<feature policy='require' name='ds'/>
<feature policy='require' name='pbe'/>
<feature policy='require' name='tm'/>
<feature policy='require' name='pdcm'/>
<feature policy='require' name='vmx'/>
<feature policy='require' name='ds_cpl'/>
<feature policy='require' name='xtpr'/>
<feature policy='require' name='acpi'/>
</cpu>
<clock offset='localtime'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices>
<emulator>/usr/bin/kvm</emulator>
<disk type='block' device='disk'>
<driver name='qemu' type='raw'/>
<source dev='/dev/vg1/somevm'/>
<target dev='hda' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
</disk>
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/>
<target dev='hdc' bus='ide'/>
<readonly/>
<address type='drive' controller='0' bus='1' target='0' unit='0'/>
</disk>
<controller type='usb' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
</controller>
<controller type='ide' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
<interface type='bridge'>
<mac address='00:00:00:00:00:00'/>
<source bridge='br0'/>
<model type='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</interface>
<serial type='pty'>
<target port='0'/>
</serial>
<console type='pty'>
<target type='serial' port='0'/>
</console>
<input type='tablet' bus='usb'/>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<graphics type='vnc' port='-1' autoport='yes'/>
<video>
<model type='vga' vram='9216' heads='1'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</memballoon>
</devices>
<seclabel type='none' model='none'/>
</domain>
另一个想法(与您的问题无关,但可能会有所帮助):如果可以,请确保您使用的是“半虚拟化”网络、块、随机、时钟等驱动程序 - 它们比完全虚拟化的驱动程序快得多。这是上面的“model=virtio”内容。您必须将驱动程序模块加载到主机的内核中,例如 virtio_net。
以下是“virsh pool-dumpxml vg1”的输出:
<pool type='logical'>
<name>vg1</name>
<uuid>9e26648e-64bc-9221-835f-140f6def0556</uuid>
<capacity unit='bytes'>3000613470208</capacity>
<allocation unit='bytes'>1824287358976</allocation>
<available unit='bytes'>1176326111232</available>
<source>
<device path='/dev/md1'/>
<name>vg1</name>
<format type='lvm2'/>
</source>
<target>
<path>/dev/vg1</path>
<permissions>
<mode>0700</mode>
</permissions>
</target>
</pool>
答案3
我不知道有哪种方法可以准确复制您描述的 Xen 行为。但是,您可以使用它将kpartx
包含整个磁盘映像的 LV 中的分区公开为主机上的块设备,然后您可以挂载这些块设备,等等。
答案4
请参阅我对这个问题的回答KVM 启动非镜像内核和现有分区简而言之,只需对 guest /etc/fstab 进行轻微修改,即可让 virt-install 创建配置,非常简单。