使用libguestf访问和修改虚拟机磁盘镜像

时间:2020-03-21 11:42:34  来源:igfitidea点击:

libguestfs是C库和该库上的工具集合,用于在Linux中创建,查看,访问和修改虚拟机磁盘镜像。
我们可以在磁盘镜像内查看,修改它们包含的文件,从头开始创建它们,调整它们大小,并更多。
它不需要libvirt或者kvm,也不需要root权限。
Red Hat赞助Libguestfs的发展。
它支持许多Linux发行版和UNIX变体,如Mac OS。

libguestfs与几乎所有Linux文件系统(ext2/3/4,xfs,btrfs等),Windows文件系统(VFAT和NTFS),Mac OS和BSD文件系统,LVM2卷,MBR和GPT磁盘分区,原始磁盘,qcow2,VirtualBox VDI,VMware VMDK和Hyper-V VHD/VHDX。
它甚至可以访问CD和DVD ISOS,SD卡等本地文件和本地设备,或者通过FTP,HTTP,SSH,iSCSI,NBD,Glusterfs,Ceph,Sheepdog等远程访问。

在Linux上安装libguestfs

运行以下命令以在Debian,Ubuntu上安装LibGuestfs:

$sudo apt install libguestfs-tools

在CentOS,Rhel:

$sudo dnf install libguestfs-tools

安装后,使用命令查看Wurpherfish的版本:

$guestfish --version
guestfish 1.40.2

使用libguestf访问和修改虚拟机磁盘镜像

确保guest计算机已关闭。
我们不能出于任何原因修改实时镜像。
它可能会导致永久磁盘损坏和数据丢失。
始终在进行任何更改之前备份磁盘镜像。

1.Guestfish shell

GuestFish,是Guest Filesystem shell的缩写,是一个交互式shell,用于编辑虚拟机文件系统和磁盘镜像。

1.1. 手动访问现有磁盘镜像和挂载客户文件系统

首先,让我们加载现有的磁盘镜像进行检查。

运行以下命令将进入urerturfish交互式shell:

$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>

其中> <fs>表示urerturfish提示。

..然后使用命令添加磁盘镜像:

><fs> add ~/CentOS_8_Server.img

接下来,运行以下命令启动库并附上(启动)磁盘镜像:

><fs> run

第一次需要几秒钟。
随后的开始将更快地完成。

现在我们需要手动列出和登录客户端文件系统。

要查看磁盘中的文件系统列表,请从HotelFish提示运行此命令:

><fs> list-filesystems

示例输出:

/dev/sda1: ext4
/dev/cl/root: xfs
/dev/cl/swap: swap

安装文件系统:

><fs> mount /dev/cl/root /

显示挂载点:

><fs> mountpoints 
/dev/cl/root: /

同样,安装其他文件系统。

1.2. 自动访问现有磁盘镜像和挂载客户文件系统

而不是手动列出和安装Guest文件系统,我们可以让ureroutFish自动检查镜像和挂载文件系统,如下面的-i标志。

$guestfish -a CentOS_8_Server.img -i

其中

  • -a(--add)参数将自动检测磁盘镜像格式。要覆盖此功能并指定特定格式,请使用--format选项。
  • -i(--inspector) - 检查磁盘并安装文件系统。
  • centos_8_server.img - 磁盘镜像的名称。我在当前目录中有此镜像。

此命令将加载给定的镜像,挂载客户文件系统。

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
Operating system: CentOS Linux release 8.2.2004 (Core) 
/dev/cl/root mounted on /
/dev/sda1 mounted on /boot
><fs>

如果使用"-i"参数,则不必手动列出和guest文件系统。
文件系统将自动安装。
此外,我们不需要启动库并自己添加磁盘镜像。
Guestfish本身会完成。

1.3. 访问虚拟机而不是只是磁盘镜像

Guestfish有一个选项可访问虚拟机(域)而不是磁盘镜像。

首先,使用命令获取虚拟机的名称:

$virsh list --all
 Id   Name            State
-------------------------------
 -    centos8-uefi    shut off
 -    nginx_centos8   shut off

要访问名为"centos8-uefi"的VM,请使用下面的-d或者--domain选项。

$guestfish -d centos8-uefi -i

1.4. 查看和修改磁盘镜像的内容

Guestfish支持数百个命令我们可以根据我们查看和修改磁盘镜像。
如果查看全部手册,会让人头疼,
所以让我们看看如何只查看需要的手册

列出所有命令

如果我们不知道从其中开始,只需使用命令启动帮助部分:

><fs> help

要列出所有可用命令以及简要说明,请运行:

><fs> help -l

获取特定命令的帮助

获取任何命令的帮助,例如mkdir,运行:

<fs> help mkdir

示例

现在让我们看到一些例子。

列出块设备

要列出镜像中的所有块设备,请运行:

><fs> list-devices 
/dev/sda

列出分区

要列出所有块设备上检测到的所有分区,请运行:

><fs> list-partitions 
/dev/sda1
/dev/sda2

列表目录内容

要列出给定目录中的文件,请运行:

><fs> ls /root
.bash_history
.bash_logout
.bash_profile
.bashrc
.cshrc
.tcshrc

查看文件内容

要显示文件的内容,请运行:

><fs> cat /etc/fstab 
## /etc/fstab
# Created by anaconda on Thu Nov  6 06:43:28 2016
## Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
## After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#/dev/mapper/cl-root   /                   xfs     defaults        0 0
UUID=5e675dd6-7f64-46cd-8535-3617f3cf870b /boot                   ext4    defaults        1 2
/dev/mapper/cl-swap     swap                    swap    defaults        0 0

创建目录

以下命令将在客户系统中创建名为"OniTorad"的目录。

><fs> mkdir /root/theitroad

创建空文件

要在Guest Machine内创建一个空文件,请执行以下操作:

><fs> touch /root/theitroad/file.txt

验证文件是否已创建:

><fs> ls /root/theitroad/
file.txt

使用内容创建文件

要其中创建具有某些内容的文件,请使用write命令:

><fs> write /root/theitroad/file2.txt https://theitroad.com

上面的命令将在/root/onitad /目录中创建file2.txt中,并其中写"https://theitroad.com"。

我们可以使用"cat"命令验证它:

><fs> cat /root/theitroad/file2.txt 
https://theitroad.com

将内容添加到现有文件

要在已创建的文件末尾添加新内容,请使用"write-append"命令:

<fs> write-append /root/theitroad/file2.txt /about

上面的命令将在File1.txt内容的末尾添加"/关于"。

验证该行是否已添加,请使用cat命令:

><fs> cat /root/theitroad/file2.txt 
https:/theitroad.com/about

编辑文件

要在Guest机上编辑文件,请使用"编辑"命令:

><fs> edit /root/theitroad/file.txt

给定的文件将在默认编辑器中打开。

删除文件和目录

要从Guest机中删除文件:

><fs> rm /root/theitroad/file2.txt 
><fs> rm /root/theitroad/file.txt

要删除目录,请使用"rmdir"命令:

><fs> rmdir /root/theitroad/

将本地文件或者目录复制到磁盘镜像中

"Copy-In"命令递归将本地文件或者目录复制到磁盘镜像中。

以下命令将文件theitroad.txt从本地系统复制到/root/onitad /磁盘镜像。

<fs> copy-in theitroad.txt /root/theitroad/

使用ls命令验证它:

<fs> ls /root/theitroad/
file.txt
theitroad.txt

将文件或者目录从磁盘镜像复制到主机系统

同样,我们可以使用下面的"复制 - out"命令将文件或者目录从磁盘镜像复制到本地主机系统。

<fs> copy-out /root/theitroad//home/sk/Downloads/

在上面的示例中,我正在复制/root/onitad /目录下载主机系统中的目录。

将文件下载到主机系统

这与copy-out命令相同。

Guestfish允许我们从Guest Machine下载并上传内容到主机,反之亦然。

概述下载文件的语法:

download <guest_file_location> <host_file_location>

以下命令将从guest机器下载到KVM主机系统中的"/etc/fstab"文件到KVM主机系统中的/home/sk/Downloads/目录。

<fs> download /etc/fstab /home/sk/Downloads/fstab

从主机系统上传文件到客户系统

这与Copy-In命令相同。

将文件从主机系统上传到Guest Machine,运行:

><fs> upload /home/sk/Downloads/fstab /etc/fstab

其中我将本地系统上载/home/sk /下载/fstab文件从我的本地系统到/etc/fstab在guest worlia。

显示guestfish手册页

要显示guestfish的man 页面:

><fs> man

退出guestfish

退出guestfish shell,运行:

><fs> exit

到目前为止,我们已看到的是我们访问,安装,检查和修改现有磁盘镜像。
guestfish也可以立即创建新磁盘镜像。

1.5. 创建新磁盘镜像

以下命令应在guestfish shell之外运行。
换句话说,它们应该在主机终端中运行。

请记住,我们使用-a参数添加了现有镜像?
是的。
要创建新的磁盘镜像,我们将进入-n( --new)参数。

要创建新的磁盘镜像并自动启动它,请从主机终端(不在guestfish)提示符下运行以下命令:

$guestfish -N fs

此命令将在当前目录中创建一个名为"test1.img"的新磁盘,并将浏览器提示。
此磁盘将包含单个分区,具有空文件系统。
默认情况下,磁盘大小将是1GB。
如果下次运行相同的命令,它将创建一个名为"test2.img"的新磁盘,其中大小为1g等。

可以创建自定义大小的磁盘镜像而不是创建固定大小的1G磁盘。

要创建一个空白的500MB磁盘,请运行:

$guestfish -N disk:500M

我们还可以创建一个使用特定文件系统格式化的磁盘镜像。
例如,以下命令将在当前目录中使用名为test1.img的ext4格式分区创建1g磁盘:

$guestfish -N fs:ext4

使用VFAT格式的分区创建500MB磁盘,然后安装它:

$guestfish -N fs:vfat:500M -m /dev/sda1

创建名为blankdisk.img的空白500MB磁盘(而不是默认名称test1.img):

$guestfish -N blankdisk.img=disk:500M

1.6. 添加远程磁盘镜像

不仅仅是本地磁盘镜像,我们还可以添加位于远程SSH,FTP,HTTP或者TFTP服务器上的磁盘。

添加位于远程SSH服务器上的磁盘:

$guestfish -a ssh://Hyman@theitroad/disk.img

用我们自己替换上面命令中的用户名和IP地址。

添加位于远程FTP服务器上的磁盘:

$guestfish -a ftp://Hyman@theitroad:port/disk.img
$guestfish -a ftps://Hyman@theitroad:port/disk.img

添加位于远程HTTP服务器上的磁盘:

$guestfish -a http://Hyman@theitroad:port/disk.img
$guestfish -a https://Hyman@theitroad:port/disk.img

添加位于远程TFTP服务器上的磁盘:

$guestfish -a tftp://Hyman@theitroad:port/disk.img

2.不进入guestfish shell,直接访问,查看和修改磁盘镜像

libguestfs提供了许多其他等效命令来访问,查看和修改磁盘镜像,而无需实际进入guestfish shell。

2.1. guestmount

GuestMount命令用于使用保险丝和libguestf在主机上安装客户文件系统。

以下命令将在主机系统中安装CentOS8-UEFI Guest Macher的FureSystem。

$mkdir ~/guestvm/
$sudo guestmount -d centos8-uefi -i ~/guestvm/

验证挂载目录的内容:

$sudo ls -l ~/guestvm

示例输出:

total 16
lrwxrwxrwx.  1 root root    7 Jan 11  2019 bin -> usr/bin
dr-xr-xr-x.  6 root root 4096 Jan 18 15:46 boot
drwxr-xr-x.  2 root root    6 Jan 18 15:23 dev
drwxr-xr-x. 78 root root 8192 Jan 25 17:54 etc
drwxr-xr-x.  2 root root    6 Jan 11  2019 home
lrwxrwxrwx.  1 root root    7 Jan 11  2019 lib -> usr/lib
lrwxrwxrwx.  1 root root    9 Jan 11  2019 lib64 -> usr/lib64
drwxr-xr-x.  2 root root    6 Jan 11  2019 media
drwxr-xr-x.  2 root root    6 Jan 11  2019 mnt
drwxr-xr-x.  2 root root    6 Jan 11  2019 opt
drwxr-xr-x.  2 root root    6 Jan 18 15:23 proc
dr-xr-x---.  2 root root  135 Jan 18 15:46 root
drwxr-xr-x.  2 root root    6 Jan 18 15:23 run
lrwxrwxrwx.  1 root root    8 Jan 11  2019 sbin -> usr/sbin
drwxr-xr-x.  2 root root    6 Jan 11  2019 srv
drwxr-xr-x.  2 root root    6 Jan 18 15:23 sys
drwxrwxrwt.  7 root root  119 Jan 25 18:44 tmp
drwxr-xr-x. 12 root root  144 Jan 18 15:24 usr
drwxr-xr-x. 20 root root  278 Jan 18 15:45 var

卸载它,运行:

$sudo umount ~/guestvm

有关更多详细信息,请参阅Man页面。

$man guestmount

2.2. virt-cat

virt-cat命令提示要查看存储在磁盘镜像或者虚拟机中的文件的内容。

$sudo virt-cat -a CentOS_8_Server.img /etc/fstab

或者,

$sudo virt-cat -d centos8-uefi /etc/fstab

示例输出:

## /etc/fstab
# Created by anaconda on Sat Jan 18 05:53:25 2016
## Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
## After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#/dev/mapper/cl-root   /                   xfs     defaults        0 0
UUID=6a7f6481-5eb3-4589-ad19-b2291ddfcda1 /boot                   ext4    defaults        1 2
UUID=6906-5D0A          /boot/efi               vfat    umask=0077,shortname=winnt 0 2
/dev/mapper/cl-swap     swap                    swap    defaults        0 0

2.3. virt-copy-in

virt-copy-in命令用于将文件和目录从主机复制到磁盘镜像或者虚拟机。

$sudo virt-copy-in -a CentOS_8_Server.img theitroad.txt /root/

或者,

$sudo virt-copy-in -d centos8-uefi theitroad.txt /root/

2.4. virt-copy-out

virt-copy-out命令用于将文件和目录从磁盘镜像或者虚拟机中复制。

$sudo virt-copy-out -a CentOS_8_Server.img /root/theitroad.txt ~/Downloads

或者,

$sudo virt-copy-in -d centos8-uefi /root/theitroad.txt ~/Downloads

上面的命令将从虚拟机磁盘中将/root/theitroad.txt文件复制到本地主机系统中的~/下载目录。

2.4. virt-df

virt-df命令在guest虚拟机文件系统上显示可用空间。

查看磁盘镜像上的可用空间:

$sudo virt-df -a CentOS_8_Server.img

示例输出:

Filesystem                                Size       Used  Available  Use%
CentOS_8_Server.img:/dev/sda1             976M       260M       649M   27%
CentOS_8_Server.img:/dev/cl/root           17G       1.4G        16G    9%

查看VM上的磁盘空间:

$sudo virt-copy-in -d centos8-uefi /root/theitroad.txt ~/Downloads

示例输出:

Filesystem                                Size       Used  Available  Use%
centos8-uefi:/dev/sda1                    599M       6.6M       592M    2%
centos8-uefi:/dev/sda2                    976M       121M       788M   13%
centos8-uefi:/dev/cl/root                  16G       1.2G        15G    8%

2.5. virt-edit

在磁盘镜像或者虚拟机中编辑文件。

$sudo virt-edit -a CentOS_8_Server.img /root/theitroad.txt

或者,

$sudo virt-edit -d centos8-uefi /root/theitroad.txt

此命令将在默认编辑器中打开远程文件。
只需进行更改并保存并关闭文件即可。

2.6. virt-filesystems

列出虚拟机或者磁盘镜像中的文件系统,分区,块设备,LVM。

$sudo virt-filesystems -a CentOS_8_Server.img -l

或者,

$sudo virt-filesystems -d centos8-uefi -l

示例输出:

Name          Type        VFS   Label  Size         Parent
/dev/sda1     filesystem  vfat  -      629145600    
/dev/sda2     filesystem  ext4  -      1073741824   
/dev/cl/root  filesystem  xfs   -      17620271104  

要显示分区详细信息,请在上面的命令中添加 - 分页:

$sudo virt-filesystems -d centos8-uefi --partitions
/dev/sda1
/dev/sda2
/dev/sda3

同样,我们可以使用--logical-volumes, --volume-groups, --physical-volumes, --block-devices来列出这些项目。

2.7. virt-inspector

Virt-Inspector用于显示有关磁盘镜像或者虚拟机的操作系统版本和其他信息。

$sudo virt-inspector -a CentOS_8_Server.img

或者,

$sudo virt-inspector -d centos8-uefi

2.8. virt-ls

VIST-LS用于显示磁盘镜像或者虚拟机中的文件和目录及其大小,属性,校验和。

$sudo virt-ls -R -a CentOS_8_Server.img/| less

或者,

$sudo virt-ls -R -d centos8-uefi /root

我们可以使用具有Virt-LS命令的大多数普通的"LS"命令选项/标志。

2.9. virt-log

Virt-log用于从磁盘镜像或者虚拟机显示日志文件。

$sudo virt-log -a CentOS_8_Server.img

或者,

$sudo virt-log -d centos8-uefi

2.10. virt-tail

Virt-tail命令用于遵循磁盘镜像或者虚拟机中的日志文件。

$sudo virt-tail -a CentOS_8_Server.img /var/log/messages

或者,

$sudo virt-tail -d centos8-uefi /var/log/messages

故障排除

以下是一些常见问题的解决方案。

1. 在ubuntu中Libguestfs没有root权限无法运行

在尝试访问Ubuntu上的磁盘镜像时可能会遇到此错误:

libguestfs: error: /usr/bin/supermin exited with error status 1.
To see full error messages you Jan need to enable debugging.
Do:
  export LIBGUESTFS_DEBUG=1 LIBGUESTFS_TRACE=1
and run the command again.  For further information, read:
  http://libguestfs.org/guestfs-faq.1.html#debugging-libguestfs

要解决此问题,请运行:

$sudo chmod 0644 /boot/vmlinuz*

我们可能需要将自己添加到KVM组:

$sudo usermod -a -G kvm sk

使用我们自己的用户名将"sk"替换为"sk"。

  • 如果我们已经在系统上安装了LibVirt或者KVM并尝试将Libguesfs工具用作root用户,则应查看此权限错误:
libguestfs: error: could not create appliance through libvirt.
Try running qemu directly without libvirt using this environment variable:
export LIBGUESTFS_BACKEND=direct
Original error from libvirt: Cannot access backing file '/root/CentOS_8_Server.qcow2' of storage file '/tmp/libguestfsiPjmga/overlay1.qcow2' (as uid:107, gid:107): Permission denied [code=38 int1=13]

这是由libvirt引起的,因此只有在使用libvirt后端时才发生。
要解决此问题,请通过设置此环境变量来切换到直接后端:

export LIBGUESTFS_BACKEND=direct

要永久使其,请将此行添加到~/.bashrc文件中。