巧用guestfish工具修改kvm镜像

场景1: KVM 虚拟机启动后,如果想ssh这个虚拟机,但是却不知道不知道默认的用户名和密码,这时可以利用guestfish 工具把自己的public sshkey注入到目标虚拟机,从而实现通过sshkey登录的目的。

1 得到虚拟机启动盘的qcow2镜像的位置

virsh dumpxml <VMName>
<devices>
    <emulator>/usr/bin/qemu-system-s390x</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2' cache='writethrough' error_policy='report'/>
      <source file='/mnt/a87990be-26b2-41d0-bc6b-70e22300bcd6/bv-r134-2e867184-f647-486f-ab3f-0905bcf38d26.qcow2' index='3'/>

2 在host上安装guestfish工具包
apt install libguestfs-tools

3 通过一个交互式shell进入image
root@c4828v1:/home# guestfish --rw -a bv-r134-2e867184-f647-486f-ab3f-0905bcf38d26.qcow2
><fs> run
 100% ⟦▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒⟧ --:--
><fs> list-filesystems
/dev/sda1: ext4
><fs> mount /dev/sda1 /home/test
libguestfs: error: mount: mount: /home/test: mount point is not a directory //只能mount到/ 根目录下

><fs> mount /dev/sda1 /
><fs> ls /root/
.bash_history
.bashrc
.cache
.profile
.ssh
nftest
snap
><fs> ls /root/nftest //在源VM里面有nftest这个文件夹,这里可以看到源VM的/dev/sda1盘的内容
testdata
><fs>exit
当你使用guestfish shell找到可用文件系统类型之后,就可以进行挂载了。使用命令
mount /dev/sda1 / 来挂载第一个分区的内容。在guestfish中,你不能像在其他shell环境中一样操作目录。挂载的分区就是根目录,cd时所有的路径必须是完全限定路径,从根目录开始。
在guestfish shell当中可以使用像vi、ls、cat、more、download这样的命令,来查看和下载文件以及目录,输入help可以看到完整的命令信息。
在完整所有操作之后可以使用exit来关闭guestfish shell。

4 通过下面命令把key注入qcow2 image

image=bv-r134-2e867184-f647-486f-ab3f-0905bcf38d26.qcow2
ssh_public_key=test-public-key

root@c4828v1:/home# expect -c "
>   set timeout 12
>   spawn guestfish
>   expect \"><fs>\"
>   send \"add ${qcow2_image}\r\"
>   expect \"><fs>\"
>   send \"run\r\"
>   expect \"><fs>\"
>   send \"list-filesystems\r\"
>   expect \"><fs\"
>   send \"mount /dev/sda1 /\r\"
>   expect \"><fs>\r\"
>   send \"mkdir /root/.ssh \r\"
>   expect \"><fs>\r\"
>   send \"write '/root/.ssh/authorized_keys' '${ssh_public_key}' \r\"
>   expect \"><fs>\r\"
>   send \"quit\r\"
>   expect eof
> "
spawn guestfish

Welcome to guestfish, the guest filesystem shell for
editing virtual machine filesystems and disk images.

Type: ‘help’ for help on commands
      ‘man’ to read the manual
      ‘quit’ to quit the shell

><fs> add bv-r134-2e867184-f647-486f-ab3f-0905bcf38d26.qcow2
><fs> run
 100% ⟦▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒⟧ 00:00
><fs> list-filesystems
/dev/sda1: ext4
><fs> mount /dev/sda1 /
write '/root/.ssh/authorized_keys' 'test-public-key'
><fs> quit


验证是否成功:
root@c4828v1:/home# guestfish --rw -a bv-r134-2e867184-f647-486f-ab3f-0905bcf38d26.qcow2

Welcome to guestfish, the guest filesystem shell for
editing virtual machine filesystems and disk images.

Type: ‘help’ for help on commands
      ‘man’ to read the manual
      ‘quit’ to quit the shell

><fs> run
 100% ⟦▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒⟧ --:--
><fs> fs
fs: unknown command
><fs> list-filesystems
/dev/sda1: ext4
><fs> mount /dev/sda1 /
><fs> cat /root/.ssh/authorized_keys  //key已经注入qcow2 image
test-public-key


场景:2 KVM虚拟机网络连不上的情况下,如果想备份里面的文件,可以利用copy-in/copy-out 的功能

><fs> help copy-out
NAME
    copy-out - copy remote files or directories out of an image

DESCRIPTION
     copy-out remote [remote ...] localdir

    "copy-out" copies remote files or directories recursively out of the
    disk image, placing them on the host disk in a local directory called
    "localdir" (which must exist). This guestfish meta-command turns into a
    sequence of "download", "tar-out" and other commands as necessary.

    Multiple remote files and directories can be specified, but the last
    parameter must always be a local directory. To download to the current
    directory, use "." as in:

     copy-out /home .

    Wildcards cannot be used in the ordinary command, but you can use them
    with the help of "glob" like this:

     glob copy-out /home/* .


 通过copy-out把虚拟机image中的文件夹拷贝到host上的 /root/testguestfish
><fs> copy-out /root/nftest /root/testguestfish  
><fs> ls /root
.bash_history
.bashrc
.cache
.profile
.ssh
nftest
snap

查看结果:
local host:
root@c4828v1:~/testguestfish# pwd
/root/testguestfish
root@c4828v1:~/testguestfish# ls
nftest


通过copy-in 在host 创建文件夹,然后把host上的文件夹copy到虚拟机image内部
root@c4828v1:~# mkdir -p test-copy-in-from-host
root@c4828v1:~# cd test-copy-in-from-host/
root@c4828v1:~/test-copy-in-from-host# ls
root@c4828v1:~/test-copy-in-from-host# touch test-copy-in
root@c4828v1:~/test-copy-in-from-host# pwd
/root/test-copy-in-from-host


在image内部通过guestfish 进行查看
><fs> mkdir /root/tst/
><fs> copy-in /root/test-copy-in-from-host/ /root/tst/
><fs> ls /root/tst/
test-copy-in-from-host

对qcow2 修改后,可以重新启动虚拟机,这时会发现修改都已经能生效
posted @ 2024-08-14 13:58  快乐的橙子  阅读(33)  评论(0编辑  收藏  举报