前言

在使用云服务器产品时,由于问题修复、功能添加、软件更新等原因,往往需要对已有系统镜像进行二次修改。

这种情况下,最为简单的做法是:使用原镜像创建实例,在实例中进行修改,修改完毕后再转镜像。这种做法比较粗暴,系统启动的过程可能会为原本干净的系统镜像带来一些不必要的残留数据,而且也无法执行硬盘分区、文件系统等需要目标文件系统不在挂载状态下才能够执行的操作。

针对这些问题,一种改善的方法是:使用原镜像创建一块云硬盘,随后将这块云硬盘挂载至一台已创建的实例上并进行修改,修改完毕后将云硬盘转镜像。这样能够在较大程度上保证系统镜像的纯净性,也能够进行分区、文件系统方面的修改。

不过上述方式整体操作流程仍然比较冗长,为了缩减流程,libvirt提供了名为libguestfs-tools的工具,用来快捷地操作硬盘镜像。

简介

libguestfs-tools是一款系统管理员用来管理虚拟机硬盘镜像的工具包,里面包含了用于各种各样用途的工具,能够帮忙我们操作硬盘镜像的分区、文件系统、文件等等。

libguestfs-tools包含了如下工具:

  1. guestfish提供了一个交互式shell,在这个shell中可以通过一系列内置命令操作硬盘镜像的分区、文件系统、文件等等。
  2. guestmount能够将硬盘镜像中的文件系统挂载至宿主机上,从而像操作宿主机的文件一样操作硬盘镜像中的文件。
  3. virt-alignment-scan能够扫描磁盘镜像并检测分区对齐问题。
  4. virt-builder用于快速地构建一个可用的硬盘镜像。
  5. virt-cat用来展示硬盘镜像中指定文件的内容。
  6. virt-copy-in和virt-copy-out用来上传/下载硬盘镜像中的文件/目录。
  7. virt-customize用来定制硬盘镜像。
  8. virt-df展示硬盘镜像空间的使用情况。
  9. virt-diff展示硬盘镜像内两个文件的差异。
  10. virt-edit用来编辑硬盘镜像中的文件。
  11. virt-filesystems展示硬盘镜像中的文件系统、硬盘分区、块设备、LVM信息等等。
  12. virt-format用来格式化硬盘镜像内部的文件系统。
  13. virt-get-kernel用来获取硬盘镜像中的kernel/initrd。
  14. virt-inspector用来探测硬盘镜像内部的系统信息。
  15. virt-log展示硬盘镜像中的日志。
  16. virt-ls用来列出硬盘镜像中的文件。
  17. virt-make-fs能够使用指定的文件或归档包创建包含有一个文件系统的硬盘镜像。
  18. virt-rescue提供了一个交互式shell,用于操作硬盘镜像。
  19. virt-resize能够扩容硬盘镜像中的分区。
  20. virt-sparsify能够消除硬盘镜像中的空洞,压缩镜像大小。
  21. virt-syspgrep用于镜像初始化。
  22. virt-tail能够追踪硬盘镜像中指定文件的更新情况。
  23. virt-tar-in和virt-tar-out能够上传/下载硬盘镜像中的文件/目录并归档。
  24. virt-win-reg能够修改windows硬盘镜像中的注册表。

如上,可以看到为了简化对硬盘镜像的操作,libguestfs-tools提供了非常非常多的工具,这些工具每个都有着各自的用途,有的十分好用,而有的却很鸡肋。在绝大多数情况下,guestmount工具就可以满足我们的需求。

安装

libguestfs-tools工具位于centos的base源中,确认软件源后安装libguestfs-tools工具包:

yum install -y libguestfs-tools

案例

文件系统、分区、块设备、LVM信息获取

通过virt-filesystems命令可以方便地获取到硬盘镜像中所有分区和文件系统的信息:

export LIBGUESTFS_BACKEND=direct
virt-filesystems --all --long --uuid -h -a centos.qcow2
Name Type VFS Label MBR Size Parent UUID
/dev/sda1 filesystem xfs - - 1.0G - c21cde6e-fe3a-4aa1-8adb-d26d096b1889
/dev/sda2 filesystem swap - - 2.0G - ef8945c2-3538-4adf-a70c-c46d339b150d
/dev/centos_hikvisionos/root filesystem xfs - - 17G - 70ced207-d3bc-4ca0-b3ea-3050ebd4990c
/dev/centos_hikvisionos/root lv - - - 17G /dev/centos_hikvisionos gjQuy8-ed48-WMDo-PROV-14Sl-ghdp-UGE0b9
/dev/centos_hikvisionos vg - - - 17G /dev/sda3 BXeW80Nd2VQNBnvOCypsbf0a0n8etjSQ
/dev/sda3 pv - - - 17G - ZuUKoHbV7jyJW6C57p36BXvOuUzz4BRB
/dev/sda1 partition - - 83 1.0G /dev/sda -
/dev/sda2 partition - - 82 2.0G /dev/sda -
/dev/sda3 partition - - 83 17G /dev/sda -
/dev/sda device - - - 20G - -

* 文件修改

我们对硬盘镜像的改动在绝大多数情况下都属于文件修改,而不需要涉及到分区或文件系统的情况下,使用guestmount命令可以轻松搞定。

# 镜像的挂载路径
MOUNT_PATH=/mnt/centos
# 镜像的路径
IMAGE=/root/centos.qcow2 export LIBGUESTFS_BACKEND=direct
# -a指定镜像,-i表示自动识别待挂载的镜像文件系统
guestmount -a $IMAGE -i $MOUNT_PATH
# -m手动指定镜像内的待挂载文件系统
# guestmount -a $IMAGE -m /dev/centos/root $MOUNT_PATH
# 进入挂载路径
cd $MOUNT_PATH

上面这种方式能够修改硬盘镜像中的文件,不过,却无法执行硬盘镜像中的命令,如果涉及到需要执行镜像中命令的操作,比如说yum install安装软件、grub-install生成grub配置、dracut生成initrd等等,还需要增加一步chroot。

# 挂载必要的设备路径并chroot
mount -t proc none $MOUNT_PATH/proc
mount --bind /dev $MOUNT_PATH/dev
mount -t devpts devpts $MOUNT_PATH/dev/pts
mount -t sysfs none $MOUNT_PATH/sys
chroot $MOUNT_PATH # 执行操作
rm -rf /tmp/*
yum clean all
rm -rf /var/cache/yum
cd /var/log/; ls -I audit -I sa -I samba|xargs rm -rf

在操作完后,卸载镜像挂载路径,对镜像的改动就算作是完成了,如果之前有chroot,那么还需退出chroot并卸载相关设备路径。

# 退出chroot并卸载设备路径
exit
rm -f $MOUNT_PATH/root/.bash_history
umount $MOUNT_PATH/proc
umount $MOUNT_PATH/dev/pts
umount $MOUNT_PATH/dev
umount $MOUNT_PATH/sys
# 卸载镜像挂载路径
umount $MOUNT_PATH

分区移除

注:分区的移除可直接使用virt-resize工具完成,本章节仅演示virt-rescue工具的用法

分区移除涉及到分区操作,务必谨慎,确保硬盘镜像已备份。分区移除分为末尾分区移除和非末尾分区移除两种情况,末尾分区移除比较简单,不做介绍,这里只考虑非末尾分区的移除。比如说硬盘镜像中不再需要用到swap功能,于是乎需要将中间的swap分区移除。

使用virt-rescue工具操作该镜像:

export LIBGUESTFS_BACKEND=direct
virt-rescue -a centos.qcow2
><rescue> lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
|-sda1 8:1 0 1G 0 part
|-sda2 8:2 0 2G 0 part
`-sda3 8:3 0 17G 0 part
`-centos_hikvisionos-root 252:0 0 17G 0 lvm
sdb 8:16 0 4G 0 disk /

归档第三个分区,并删除lvm相关配置(防止分区同步报错):

><rescue> mount /dev/centos_hikvisionos/root /sysroot/
><rescue> tar -cf rootfs.tgz /sysroot/
><rescue> umount /sysroot/
><rescue> lvremove centos_hikvisionos root
><rescue> vgremove centos_hikvisionos

删除第二、三分区,使用所有剩余空间重建为第二分区:

><rescue> fdisk /dev/sda

Command (m for help): p
...
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 2099199 2097152 1G 83 Linux
/dev/sda2 2099200 6293503 4194304 2G 82 Linux swap / Solaris
/dev/sda3 6293504 41943039 35649536 17G 83 Linux d
d
n Command (m for help): p
... Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 2099199 2097152 1G 83 Linux
/dev/sda2 2099200 41943039 39843840 19G 83 Linux Command (m for help): w
The partition table has been altered.

重建文件系统:

><rescue> pvcreate /dev/sda2
><rescue> vgcreate centos_hikvisionos /dev/sda2
><rescue> lvcreate --name root -l 100%FREE centos_hikvisionos
><rescue> mkfs.xfs /dev/centos_hikvisionos/root
><rescue> mount /dev/centos_hikvisionos/root /sysroot/
><rescue> tar -xf rootfs.tgz -C /

注意如果涉及到根分区或boot分区的改动,那么需要更新grub的启动配置:

# 这里省略guestmount并chroot的操作
# 如果boot分区被改动,需要执行这一步将grub安装到该硬盘镜像中
# grub2-install /dev/sda
grub2-mkconfig -o /boot/grub2/grub.cfg

随后退出交互式shell,使用该镜像作为系统盘创建一台云服务器,调试该镜像是否能够正常启动。

分区扩容/缩容/删除

virt-resize工具可以用于硬盘镜像的分区操作,该工具在操作分区的同时也会考虑到其上的文件系统,较为方便。

# 创建一个空镜像,大小为10G,作为输出镜像
qemu-img create -f qcow2 -o preallocation=metadata test-new.qcow2 10G
# 将sda2分区扩展至最大(9G)
virt-resize --expand /dev/sda2 test.qcow2 test-new.qcow2
# 将sda2分区扩展至最大,与此同时sda1分区扩展200M
virt-resize --resize /dev/sda1=+200M --expand /dev/sda2 test.qcow2 test-new.qcow2
# 将sda2分区扩展至最大,并将逻辑卷与文件系统扩容至最大
virt-resize --expand /dev/sda2 --LV-expand /dev/centos/root test.qcow2 test-new.qcow2
# 缩容分区,注意缩容前需要事先缩容文件系统或pv,否则会报错
virt-resize --shrink /dev/sda2 test.qcow2 test-new.qcow2
virt-resize --resize /dev/sda1=-200M test.qcow2 test-new.qcow2
# 删除分区
virt-resize --delete /dev/sda2 test.qcow2 test-new.qcow2

镜像空洞去除并压缩

virt-sparsify工具可以去除硬盘镜像的空洞并压缩。经测试,一个大小为4G的普通centos镜像能够压缩到700M,压缩比率较高,推荐使用,不过据工具说明,可能存在风险,目前尚未遇到有文件系统损坏的情况。

qemu-img info hikos.raw|grep virtual
# virtual size: 6 GiB (6443696128 bytes) # 创建一个新的同样大小的镜像test.qcow2
qemu-img create -f qcow2 -o preallocation=metadata test.qcow2 6G
# 使用virt-sparsify去除镜像空洞并压缩
virt-sparsify hikos.raw --compress --convert qcow2 test.qcow2

参考文档

guestfish(1) - Linux man page (die.net)

KVM镜像管理利器-guestfish使用详解_xiaoli110的技术博客_51CTO博客

如何快捷地修改虚拟机镜像——libguestfs-tools工具集介绍的更多相关文章

  1. 【资料】Mac OS X 10.9虚拟机镜像及tools

    原文链接 http://bbs.itheima.com/thread-141793-1-1.html 1.首先解压文件,两个同时选中,右键进行解压. 2.打开虚拟机VMware workstation ...

  2. 修改kvm虚拟机镜像大小

    修改虚拟机镜像大小(qcow2/raw resize) 创建一个镜像文件,大小1G taw muxueqz@muxueqz /tmp $ qemu-img create -f raw t.raw 1G ...

  3. 在VMware Workstation 16上安装Windows7虚拟机以及VMware tools安装失败解决方法

    安装VMware Workstation 16 搜素"VMware Workstation下载" 下载 VMware Workstation Pro 下载Windows7系统镜像 ...

  4. Jexus Web Server 完全傻瓜化图文配置教程(基于Ubuntu 12.04.3 64位)[内含Hyper-v 2012虚拟机镜像下载地址]

    1. 前言 近日有感许多新朋友想尝试使用Jexus,不过绝大多数都困惑徘徊在Linux如何安装啊,如何编译Mono啊,如何配置Jexus啊...等等基础问题,于是昨日向宇内流云兄提议,不如搞几个配置好 ...

  5. win7里linux虚拟机安装vmware tools(ubuntu12.04)

    安装Vmware Tools工具 1.安装linux虚拟机(略) 2.虚拟机去启动,选择虚拟机à设置,“硬件”中选择CD/DVD(IDE),右侧选择“使用ISO镜像文件(M)”  -- 文件选择vmw ...

  6. openStack 租户控制台修改虚拟机账户密码

    - cloud-init方式 该种方式需要虚拟机镜像安装cloud-init,将重置密码脚本注入到虚拟机中.nova boot –image=image-id –nic net-id=net-id – ...

  7. 虚拟机Tools工具安装过程

    1.选择:“虚拟机” >>> “安装VMware Tools” 在主机上,从 Workstation Pro 菜单栏中选择虚拟机 > 安装 VMware Tools. 如果安装 ...

  8. 改动虚拟机镜像的rootpassword

    有时从网上下载的虚拟机镜像.没有rootpassword,必须通过秘钥登录.然后秘钥又须要麻烦的注入到里面去.想用,却无法登录.非常头痛.本文提供一种通过改动虚拟机镜像里面的/etc/shadow文件 ...

  9. 为openstack制作CoreOS虚拟机镜像(基于CoreOS官方提供镜像)

    OpenStack源码交流群: 538850354 1.下载CoreOS镜像(633.1.0版本) CoreOS官网已经有openstack使用的虚拟机镜像,可以直接下载,然后进行修改 http:// ...

随机推荐

  1. JavaScript之数组常用API

    这篇文章主要帮助大家简单理解数组的一些常用API用法,许多小伙伴常用方法记不住?别急,看完下面的介绍您一定就会明白各个方法是如何用的了.该文章适合新手小白看,大佬可以多多指点️! 1.数组的创建以及A ...

  2. CodeForces - 1690F

    Problem - F - Codeforces 题意: 给出一个字符串,给出一个序列,每次对应位置的字符变成序列指定位置的字符,即序列中对应位置为2,那么字符串的这个位置的字符就要变成字符串第二个位 ...

  3. KingbaseESV8R6垃圾回收受到参数old_snapshot_threshold的影响

    垃圾回收影响因素 影响垃圾回收的因素有很多,垃圾回收不及时,最直接导致表膨胀,详情查看文档<KingbaseESV8R6 垃圾回收原理以及如何预防膨胀>. vacuum回收垃圾的tuple ...

  4. KingbaseES V8R6 ksql 关闭自动提交

    背景 用过oracle或mysql的人都知道,做一个dml语句,如果发现做错了,还可以rollback,但在Kingbase ksql 中,如果执行一个dml,没有先运行begin; 的话,一执行完就 ...

  5. K8S Pod及其控制器

    Pod K8S里能够运行的最小逻辑单元,1个Pod可以运行多个容器 Pod 控制器 Pod控制器是Pod启动的一种模版,用来保证在K8S中启动的Pod始终按照人们的预期运行(副本数,生命周期.健康状态 ...

  6. mysql_阻塞和死锁

    什么是阻塞 由于不同锁之间的兼容关系,造成一个事务需要等待另一个事务释放其所占用的资源的现象 称为 阻塞 如何发现阻塞 mysql_8.0 SELECT waiting_pid as '被阻塞的线程' ...

  7. Java---Stream入门

    由于本文需要有一定的Lambda基础,所以如果不懂什么是Lambda的同学请移步:Java---Lambda 学习Stream的目的 函数式编程渐渐变成主流,而Stream是函数式编程的重点. 相对于 ...

  8. Ingress资源规范

    k8s v1.19版本中Ingress资源规范从v1beta1版本升级至稳定的v1版本 v1beta1版本 v1beta1版本的Ingress资源位于API群组的extensions之中,该版本的资源 ...

  9. 组件化开发1-git命令简洁版

    1-给项目添加git git init 2-查询当前状态,(红色显示的为在工作区,绿色为暂缓区) git status 3-提交到暂缓区 git add . 4-提交到本地仓库('xxxx'里面为注释 ...

  10. 【前端必会】使用indexedDB,降低环境搭建成本

    背景 学习前端新框架.新技术.如果需要做一些数据库的操作来增加demo的体验(CURD流程可以让演示的体验根据丝滑) 最开始的时候一个演示程序我们会调用后台,这样其实有一点弊端,就是增加了开发和维护成 ...