此文已由作者刘超授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
创建了一个虚拟机,不知道为什么挂了,重启也启动不了,VNC也登不上去,强行关机后再也启动不起来了,开机一大堆错误,可是里面还有很重要的数据啊,怎么办,怎么办,谁能救救我!
下面分析几个解救的方法。
方法零:谁让你把重要数据放在系统盘里面了,请使用云盘,也即块存储,虚拟机挂了,盘可以轻松的关联到新的机器上,而且块存储系统如Ceph多是三备份,数据丢不了,下次请牢记。
您肯定会骂我,这次咋办,下面分享真正解救的办法。
1. 方法一:使用qemu的工具Network Block Device
网络块设备是通过NBD Server将虚拟块设备通过TCP/IP export出来,可以远程访问。
NBD Server通常是qemu-nbd
1.1 使用方法一:可以提供unix socket
qemu-nbd -t -k /home/openstack/images/ubuntutest-nbd ubuntutest.img
连接这个unix socket
qemu-system-x86_64 -enable-kvm -name ubuntutest -m 2048 -hda nbd:unix:/home/openstack/images/ubuntutest-nbd -vnc :19 -net nic,model=virtio -net tap,ifname=tap0,script=no,downscript=n -monitor stdio
1.2 使用方法二:普通的socket连接
qemu-nbd -t -p 1088 ubuntutest.qcow2
qemu-system-x86_64 -enable-kvm -name ubuntutest -m 2048 -hda nbd:16.158.166.150:1088 -vnc :19 -net nic,model=virtio -net tap,ifname=tap0,script=no,downscript=n -monitor stdio
1.3 使用方法三:将镜像 mount到一个network block device
竟然可以这样做,咱们镜像里面的内容有救了。
查看内核是否编译进去NBD
#grep NBD /boot/config-XXXX-generic
CONFIG_BLK_DEV_NBD=m
查看内核模块信息modinfo nbd
查看内核模块是否加载lsmod | grep nbd
如果没有加载modprobe nbd,也可以指定最多的partition: modprobe nbd max_part=16
加载后出现16个NBD
查看哪个nbd device被使用:cat /proc/partitions
将image付给一个network block device
qemu-nbd -c /dev/nbd0 ubuntutest.img
可以看到这个image里面有三个partition
Mount其中一个partition
可以看到里面的文件啦!!!!!
修改结束后
umount ubuntutestnbd0p1
qemu-nbd -d /dev/nbd0
2. 方法二:如果镜像里面是LVM
有LVM的情况相对复杂
qemu-nbd -c /dev/nbd0 centos-5.8.new.qcow2
发现里面有LVM,当然LVM不能作为整体访问,因为里面有Logic volume,都是单独成文件系统的
查看LVM的信息
Import这个volume group
vgimport VolGroup00
将这个volume group设为active
vgchange -ay VolGroup00
Mount其中一个LV
mount /dev/VolGroup00/LogVol00 ubuntutestnbd0p1/
可以拿到这个Logic Volume里面的文件啦!!!!!
修改结束后
umount ubuntutestnbd0p1/
vgchange -an VolGroup00
vgexport VolGroup00
qemu-nbd -d /dev/nbd0
3. 方法三:使用libguestfs
这个工具十分强大,Libguestfs可以在不启动虚拟机的情况下,编辑Image
安装:apt-get install libguestfs-tools
编辑一个Image:
guestfish -a trusty-server-cloudimg-amd64-disk1.img
接着运行run,则一个虚拟机启动了
查看所有的文件系统
list-filesystems
Mount这个文件系统
mount /dev/sda1 /
3.1 libguestfs的架构和原理,知其然知其所以然
guestfish -a trusty-server-cloudimg-amd64-disk1.img启动的进程,也即那个交互命令行是main program
运行run的时候,会创建一个child process,在child process中,qemu运行一个称为appliance的小的虚拟机。创建子进程是由guestfs_launch函数完成的
在appliance中,运行了linux kernel和一系列用户空间的工具(LVM, ext2等),以及一个后台进程guestfsd
main process中的libguestfs和这个guestfd通过RPC进行交互。
由child process的kernel来操作disk image
libguestfs是一个C的library,你可以写一个C的程序,将这个类库加载进去,调用它的API
文档http://libguestfs.org/guestfs.3.html就描述了这些C的API
而guestfish是一个交互命令行,可以通过执行命令,他来调用C类库的API,帮我们完成操作
文档http://libguestfs.org/guestfish.1.html描述了这些命令,几乎所有的API,都有对应的命令
3.2 Libguestfs appliance的启动过程,更详细的了解它
如果我们想看这个appliance启动的详细过程,则需要export LIBGUESTFS_DEBUG=1
然后运行guestfish -a trusty-server-cloudimg-amd64-disk1.img
然后运行run,打印出很多的东西
(1) 启动guestfish
(2) 运行supermin
(3) 选择kernel
(4) 选择initrd, root images, 创建appliance
(5) 检测qemu
(6) 启动qemu appliance
(7)启动initrd
更多网易技术、产品、运营经验分享请点击。