场景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 修改后,可以重新启动虚拟机,这时会发现修改都已经能生效