首页 > 代码库 > 挂载KVM Guest操作系统磁盘
挂载KVM Guest操作系统磁盘
使用虚拟机时, 发现想要修改虚拟机中的文件非常麻烦, 需要启动虚拟机, 然后再登录进去修改.
对于已经关闭的虚拟机, 为了修改一个文件而启动, 非常耽误时间.
对于一个无法启动的虚拟机(比如启动文件损坏), 则束手无策.
因此, 掌握在主机中挂载 Guest 的操作系统磁盘, 并修改其中的内容的方法在某些时候会非常有用.
1. 挂载 Guest 操作系统磁盘的方法
挂载 Guest 操作系统磁盘的方法主要有以下3种:
- guestfish : 支持lvm, 速度较慢
- lomount : 不支持lvm, 速度快
- kpartx : 支持lvm, 速度快
使用上述3种工具之前, 我先安装了2个 kvm 虚拟机, 都是debian7.6 x86_64, 一个是普通分区, 一个是LVM分区.
2个系统的磁盘在默认路径中
root@debian-113:~# ll /var/lib/libvirt/imagestotal 16777320-rw------- 1 root root 8589934592 Sep 18 12:48 debian7.6.img-rw------- 1 root root 8589934592 Sep 18 13:08 debian7.6-lvm.img
2. 方法1 - guestfish
2.1 使用 guestfish 对 普通Guest的磁盘进行一些基本的操作
root@debian-113:~# apt-get install guestfish <-- 安装 guestfish 工具包, 中途跳出一个选择画面, 选择noroot@debian-113:~# guestfish <-- 进入 guestfishWelcome to guestfish, the libguestfs filesystem interactive shell forediting virtual machine filesystems.Type: ‘help‘ for help on commands ‘man‘ to read the manual ‘quit‘ to quit the shell><fs> add /var/lib/libvirt/images/debian7.6.img <-- 挂载 debian7.6的系统磁盘(非LVM分区)><fs> launch <-- 启动Guest, 这里会慢一些, 如果有错误, 参见下面的 *注1* 100% ?------------------? 00:00><fs> list-devices <-- 查看 Guest 中的磁盘/dev/vda><fs> sfdisk-l /dev/vda <-- 查看 Guest 中的磁盘分区Disk /dev/vda: 16644 cylinders, 16 heads, 63 sectors/trackUnits = cylinders of 516096 bytes, blocks of 1024 bytes, counting from 0 Device Boot Start End #cyls #blocks Id System/dev/vda1 * 2+ 5115- 5114- 2577408 83 Linux <-- 这个应该是根分区 //dev/vda2 5117+ 16642- 11525- 5808129 5 Extended/dev/vda3 0 - 0 0 0 Empty/dev/vda4 0 - 0 0 0 Empty/dev/vda5 5117+ 5741- 624- 314368 82 Linux swap / Solaris/dev/vda6 5743+ 16642- 10899- 5492736 83 Linux <-- 这个应该是home分区 /home><fs> mount /dev/vda6 / <-- 挂载 Guest 操作系统磁盘><fs> ls / <-- 显示挂载的内容, 就是Guest的 /homelost+foundwangyubin# Guest磁盘上新建文件><fs> touch /wangyubin/guestfish <-- Guest的磁盘上新建一个文件><fs> vi /wangyubin/guestfish <-- 编辑这个文件, 输入 test guestfish# 将Host上的hostname文件上传到Guest的 /home/wangyubin/from-host><fs> upload /etc/hostname /wangyubin/from-host# 卸载 Guest 的/home分区, 重新挂载Guest的 / 分区><fs> mounts/dev/vda6><fs> umount /dev/vda6><fs> mount /dev/vda1 /><fs> ls /binbootdevetchomeinitrd.imgliblib64lost+foundmediamntoptprocrootrunsbinselinuxsrvsystmpusrvarvmlinuz# 将 Guest上的 hostname 文件下载到 Host的 /home/from-guest><fs> download /etc/hostname /home/from-guest# 卸载Guest磁盘, 退出 guestfish><fs> mounts /dev/vda1><fs> umount /dev/vda1 ><fs> quit
*注1* guestfish中, launch时出现错误的解决方法:
><fs> launch febootstrap-supermin-helper: ext2: parent directory not found: /lib: File not found by ext2_lookuplibguestfs: error: external command failed, see earlier error messages><fs> quitroot@debian:~# update-guestfs-appliance
2.2 验证 guestfish 对普通磁盘的修改结果
1. HOST - 验证是否有 Guest的hostname文件, 并且内容正确?
root@debian-113:~# cat /home/from-guest <-- 内容正确, 参见下面cat出的Guest上的hostnamedebianroot@debian-113:~# cat /etc/hostname <-- Host的hostname内容, 用于验证 from-host的内容debian-113
2. GUEST - 验证是否有新建的文件? 是否有 Host的hostname文件, 并且内容正确?
# virt-manager 启动 guest之后, 登录进去执行以下命令root@debian:~# ls /home/wangyubin/ <-- 新建的文件和upload的文件都在from-host guestfishroot@debian:~# cat /home/wangyubin/from-host <-- 内容正确, 参见上面cat出的Host上的hostnamedebian-113root@debian:~# cat /home/wangyubin/guestfish <-- 新建的文件内容正确test guestfishroot@debian:~# cat /etc/hostname <-- Guest的hostname内容, 用于验证 from-guest的内容debian
2.3 使用 guestfish 对 LVM分区的Guest磁盘进行一些基本的操作
root@debian-113:~# guestfish Welcome to guestfish, the libguestfs filesystem interactive shell forediting virtual machine filesystems.Type: ‘help‘ for help on commands ‘man‘ to read the manual ‘quit‘ to quit the shell><fs> add /var/lib/libvirt/images/debian7.6-lvm.img><fs> launch ><fs> list-devices /dev/vda><fs> sfdisk-l /dev/vdaDisk /dev/vda: 16644 cylinders, 16 heads, 63 sectors/trackUnits = cylinders of 516096 bytes, blocks of 1024 bytes, counting from 0 Device Boot Start End #cyls #blocks Id System/dev/vda1 * 2+ 495- 494- 248832 83 Linux/dev/vda2 497+ 16642- 16145- 8136705 5 Extended/dev/vda3 0 - 0 0 0 Empty/dev/vda4 0 - 0 0 0 Empty/dev/vda5 497+ 16642- 16145- 8136704 8e Linux LVM <-- 这里看出是LVM><fs> lvs <-- 查看LVM的逻辑卷/dev/debian/home/dev/debian/root/dev/debian/swap_1><fs> mount /dev/debian/home / <-- 挂载 /home 对应的LVM逻辑卷><fs> ls /lost+foundwangyubin# Guest磁盘上新建文件 - 步骤同上面普通磁盘><fs> touch /wangyubin/guestfish-lvm <-- Guest的磁盘上新建一个文件><fs> vi /wangyubin/guestfish-lvm <-- 编辑这个文件, 输入 test guestfish lvm# 将Host上的hostname文件上传到Guest的 /home/wangyubin/from-host-lvm><fs> upload /etc/hostname /wangyubin/from-host-lvm# 卸载 Guest 的/home分区, 重新挂载Guest的 / 分区 都是LVM格式><fs> mounts/dev/debian/home><fs> umount /dev/debian/home ><fs> lvs/dev/debian/home/dev/debian/root/dev/debian/swap_1><fs> mount /dev/debian/root /><fs> ls /binbootdevetchomeinitrd.imgliblib64lost+foundmediamntoptprocrootrunsbinselinuxsrvsystmpusrvarvmlinuz# 将 Guest上的 hostname 文件下载到 Host的 /home/from-guest-lvm><fs> download /etc/hostname /home/from-guest-lvm# 卸载Guest磁盘, 退出 guestfish><fs> mounts /dev/debian/root><fs> umount /dev/debian/root ><fs> quit
2.4 验证 guestfish 对LVM磁盘的修改结果
1. HOST - 验证是否有 Guest的hostname文件, 并且内容正确?
root@debian-113:~# cat /home/from-guest-lvm <-- 内容正确, 参见下面cat出的Guest上的hostnamedebianroot@debian-113:~# cat /etc/hostname <-- Host的hostname内容, 用于验证 from-host的内容debian-113
2. GUEST - 验证是否有新建的文件? 是否有 Host的hostname文件, 并且内容正确?
# virt-manager 启动 guest之后, 登录进去执行以下命令root@debian:~# ls /home/wangyubin/ <-- 新建的文件和upload的文件都在from-host-lvm guestfish-lvmroot@debian:~# cat /home/wangyubin/from-host-lvm <-- 内容正确, 参见上面cat出的Host上的hostnamedebian-113root@debian:~# cat /home/wangyubin/guestfish-lvm <-- 新建的文件内容正确test guestfish lvmroot@debian:~# cat /etc/hostname <-- Guest的hostname内容, 用于验证 from-guest的内容debian
3. 方法2 - lomount
lomount是Xen环境下的工具, 挂载Guest的操作系统磁盘时比guestfish要快很多, 但是不支持lvm.
由于没有Xen的环境, 这里就不尝试了.
4. 方法3 - kpartx
首先, 安装 kaprtx
root@debian-113:~# apt-get install kpartx
4.1 使用 kpartx 对 普通分区的Guest磁盘进行一些基本的操作
root@debian-113:~# kpartx -av /var/lib/libvirt/images/debian7.6.img add map loop0p1 (254:0): 0 5154816 linear /dev/loop0 2048 <-- 这个是根分区 /add map loop0p2 (254:1): 0 11616258 linear /dev/loop0 5158910add map loop0p5 : 0 628736 linear 254:1 2add map loop0p6 : 0 10985472 linear 254:1 630786 <-- 这个是分区 /home# 挂载磁盘root@debian-113:~# mount /dev/mapper/loop0p1 /mnt/ <-- *注2*root@debian-113:~# ll /mnt/total 96drwxr-xr-x 2 root root 4096 Sep 18 12:38 bindrwxr-xr-x 3 root root 4096 Sep 18 12:40 bootdrwxr-xr-x 3 root root 4096 Sep 18 11:26 devdrwxr-xr-x 72 root root 4096 Sep 18 19:50 etcdrwxr-xr-x 2 root root 4096 Sep 18 11:23 homelrwxrwxrwx 1 root root 30 Sep 18 11:27 initrd.img -> /boot/initrd.img-3.2.0-4-amd64drwxr-xr-x 13 root root 4096 Sep 18 12:31 libdrwxr-xr-x 2 root root 4096 Sep 18 12:30 lib64drwx------ 2 root root 16384 Sep 18 11:23 lost+founddrwxr-xr-x 3 root root 4096 Sep 18 11:23 mediadrwxr-xr-x 2 root root 4096 Jun 12 05:07 mntdrwxr-xr-x 2 root root 4096 Sep 18 11:23 optdrwxr-xr-x 2 root root 4096 Jun 12 05:07 procdrwx------ 3 root root 4096 Sep 18 12:46 rootdrwxr-xr-x 2 root root 4096 Sep 18 12:45 rundrwxr-xr-x 2 root root 4096 Sep 18 12:45 sbindrwxr-xr-x 2 root root 4096 Jun 10 2012 selinuxdrwxr-xr-x 2 root root 4096 Sep 18 11:23 srvdrwxr-xr-x 2 root root 4096 Jul 15 2013 sysdrwxrwxrwt 2 root root 4096 Sep 18 19:52 tmpdrwxr-xr-x 10 root root 4096 Sep 18 11:23 usrdrwxr-xr-x 11 root root 4096 Sep 18 11:23 varlrwxrwxrwx 1 root root 26 Sep 18 11:27 vmlinuz -> boot/vmlinuz-3.2.0-4-amd64# 卸载磁盘root@debian-113:~# umount /mnt
*注2* kpartx 可以将Guest的磁盘挂载到主机的某个目录下 (比如上述例子就是 /mnt),
不像 guestfish 只能将Guest的磁盘挂载到 /
因此, 对于 kpartx 来说, 不需要 download 和 upload 命令, 操作 Guest 磁盘中的文件就和挂载了U盘一样.
4.2 使用 kpartx 对 LVM分区的Guest磁盘进行一些基本的操作
root@debian-113:~# kpartx -av /var/lib/libvirt/images/debian7.6-lvm.img add map loop1p1 (254:4): 0 497664 linear /dev/loop1 2048add map loop1p2 (254:5): 0 16273410 linear /dev/loop1 501758add map loop1p5 : 0 16273408 linear 254:5 2 <-- 这是 lvm 分区root@debian-113:~# vgscan <-- 通过 lvm 相关命令查看 lvm分区信息 Reading all physical volumes. This may take a while... Found volume group "debian" using metadata type lvm2root@debian-113:~# vgs <-- 通过 lvm 相关命令查看 lvm分区信息 VG #PV #LV #SN Attr VSize VFree debian 1 3 0 wz--n- 7.76g 0 root@debian-113:~# lvs <-- 通过 lvm 相关命令查看 lvm分区信息 LV VG Attr LSize Pool Origin Data% Move Log Copy% Convert home debian -wi----- 5.06g root debian -wi----- 2.40g swap_1 debian -wi----- 300.00m root@debian-113:~# vgchange -ay debian <-- 激活lvm分区 3 logical volume(s) in volume group "debian" now activeroot@debian-113:~# mount /dev/debian/root /mnt/ <-- 挂载 lvm中的根分区 /root@debian-113:~# ll /mnt/total 96drwxr-xr-x 2 root root 4096 Sep 18 12:53 bindrwxr-xr-x 2 root root 4096 Sep 18 11:28 bootdrwxr-xr-x 3 root root 4096 Sep 18 11:31 devdrwxr-xr-x 73 root root 4096 Sep 18 20:54 etcdrwxr-xr-x 2 root root 4096 Sep 18 11:28 homelrwxrwxrwx 1 root root 30 Sep 18 11:32 initrd.img -> /boot/initrd.img-3.2.0-4-amd64drwxr-xr-x 13 root root 4096 Sep 18 12:43 libdrwxr-xr-x 2 root root 4096 Sep 18 12:42 lib64drwx------ 2 root root 16384 Sep 18 11:28 lost+founddrwxr-xr-x 3 root root 4096 Sep 18 11:28 mediadrwxr-xr-x 2 root root 4096 Jun 12 05:07 mntdrwxr-xr-x 2 root root 4096 Sep 18 11:28 optdrwxr-xr-x 2 root root 4096 Jun 12 05:07 procdrwx------ 3 root root 4096 Sep 18 13:08 rootdrwxr-xr-x 2 root root 4096 Sep 18 13:06 rundrwxr-xr-x 2 root root 4096 Sep 18 13:06 sbindrwxr-xr-x 2 root root 4096 Jun 10 2012 selinuxdrwxr-xr-x 2 root root 4096 Sep 18 11:28 srvdrwxr-xr-x 2 root root 4096 Jul 15 2013 sysdrwxrwxrwt 2 root root 4096 Sep 18 20:17 tmpdrwxr-xr-x 10 root root 4096 Sep 18 11:28 usrdrwxr-xr-x 11 root root 4096 Sep 18 11:28 varlrwxrwxrwx 1 root root 26 Sep 18 11:32 vmlinuz -> boot/vmlinuz-3.2.0-4-amd64root@debian-113:~# umount /mnt <-- 卸载分区
5. 总结
lomount 由于没有环境, 没有实验.
对于 guestfish 和 kpartx来说, 感觉无论是速度还是易用性上, 都是 kpartx 胜出.
挂载KVM Guest操作系统磁盘