我的虚拟机挂了!怎么把镜像里面的数据找回来? (1)

叁叁肆2018-11-06 14:42

此文已由作者刘超授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。


创建了一个虚拟机,不知道为什么挂了,重启也启动不了,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


免费体验云安全(易盾)内容安全、验证码等服务

更多网易技术、产品、运营经验分享请点击