使用 libguestfs 和 qemu 工具更改 VM 磁盘镜像密码和扩容
libguestfs 是一个 C 语言库和一套用于访问和修改虚拟机(VM)磁盘镜像的工具集。它能让管理员能够在不启动虚拟机的情况下直接操作磁盘内容,极大简化了虚拟化环境的管理工作。
本文以 Rocky-9-GenericCloud-Base-9.6-20250531.0.x86_64.qcow2 这个镜像为例,简单演示添加用户、修改密码、添加密钥、修改硬盘大小等常用功能。
- 运行 useradd 添加用户并设置密码 - 注:默认情况下 - virt-customize不会显示- --run-command命令的标准输出,如果需要查看输出可以添加- -v或- --verbose标志- # 添加一个叫 rocky 的用户并设置密码为 MyPassword123 $ virt-customize -a ./Rocky-9-GenericCloud-Base-9.6-20250531.0.x86_64.qcow2 \ --run-command "useradd -m -s /bin/bash rocky" \ --password rocky:password:MyPassword123- # 修改 root 密码为 MyPassword123 $ virt-customize -a ./Rocky-9-GenericCloud-Base-9.6-20250531.0.x86_64.qcow2 \ --password root:password:MyPassword123 [ 0.0] Examining the guest ... [ 9.4] Setting a random seed [ 9.4] Setting passwords [ 11.1] Finishing off
- 扩容虚拟磁盘 - # 查看当前可用的分区大小和使用情况 $ virt-filesystems -a ./Rocky-9-GenericCloud-Base-9.6-20250531.0.x86_64.qcow2 --all --long -h Name Type VFS Label MBR Size Parent /dev/sda1 filesystem unknown - - 2.0M - /dev/sda2 filesystem vfat EFI - 100M - /dev/sda3 filesystem xfs BOOT - 1000M - /dev/sda4 filesystem xfs rocky - 8.9G - /dev/sda1 partition - - - 2.0M /dev/sda /dev/sda2 partition - - - 100M /dev/sda /dev/sda3 partition - - - 1000M /dev/sda /dev/sda4 partition - - - 8.9G /dev/sda /dev/sda device - - - 20G - $ virt-df -h -a ./Rocky-9-GenericCloud-Base-9.6-20250531.0.x86_64.qcow2 Filesystem Size Used Available Use% Rocky-9-GenericCloud-Base-9.6-20250531.0.x86_64.qcow2:/dev/sda2 100M 10M 90M 11% Rocky-9-GenericCloud-Base-9.6-20250531.0.x86_64.qcow2:/dev/sda3 936M 188M 748M 21% Rocky-9-GenericCloud-Base-9.6-20250531.0.x86_64.qcow2:/dev/sda4 8.9G 955M 7.9G 11% $ qemu-img info ./Rocky-9-GenericCloud-Base-9.6-20250531.0.x86_64.qcow2 image: ./Rocky-9-GenericCloud-Base-9.6-20250531.0.x86_64.qcow2 file format: qcow2 virtual size: 10 GiB (10737418240 bytes) disk size: 609 MiB cluster_size: 65536 Format specific information: compat: 1.1 compression type: zlib lazy refcounts: false refcount bits: 16 corrupt: false extended l2: false- # 创建最终扩容好的镜像 $ qemu-img create -f qcow2 ./Rocky-9-expanded.qcow2 20G Formatting './Rocky-9-expanded.qcow2', fmt=qcow2 cluster_size=2097152 extended_l2=off compression_type=zlib size=21474836480 lazy_refcounts=off refcount_bits=16 cache=writeback # 会自动检测 --expand 的分区fs类型 $ virt-resize --expand /dev/sda4 \ > ./Rocky-9-GenericCloud-Base-9.6-20250531.0.x86_64.qcow2 \ > ./Rocky-9-expanded.qcow2 [ 0.0] Examining ./Rocky-9-GenericCloud-Base-9.6-20250531.0.x86_64.qcow2 ********** Summary of changes: /dev/sda1: This partition will be left alone. /dev/sda2: This partition will be left alone. /dev/sda3: This partition will be left alone. /dev/sda4: This partition will be resized from 8.9G to 18.9G. The filesystem xfs on /dev/sda4 will be expanded using the ‘xfs_growfs’ method. ********** [ 8.3] Setting up initial partition table on ./Rocky-9-expanded.qcow2 [ 23.3] Copying /dev/sda1 [ 23.3] Copying /dev/sda2 [ 23.5] Copying /dev/sda3 [ 24.6] Copying /dev/sda4 ...进度条 [ 39.4] Expanding /dev/sda4 using the ‘xfs_growfs’ method Resize operation completed with no errors. Before deleting the old disk, carefully check that the resized disk boots and works correctly. $ virt-filesystems -a ./Rocky-9-expanded.qcow2 --all --long -h Name Type VFS Label MBR Size Parent /dev/sda1 filesystem unknown - - 2.0M - /dev/sda2 filesystem vfat EFI - 100M - /dev/sda3 filesystem xfs BOOT - 1000M - /dev/sda4 filesystem xfs rocky - 19G - /dev/sda1 partition - - - 2.0M /dev/sda /dev/sda2 partition - - - 100M /dev/sda /dev/sda3 partition - - - 1000M /dev/sda /dev/sda4 partition - - - 19G /dev/sda /dev/sda device - - - 20G -
- 添加 ssh 登录密钥 - # 最好关闭SELinux,--ssh-inject 不会自动给 authorized-keys 文件打标签 $ virt-customize -a ./Rocky-9-GenericCloud-Base-9.6-20250531.0.x86_64.qcow2\ --run-command "sed -i s#SELINUX=enforcing#SELINUX=disabled# /etc/selinux/config" # 启动虚拟机进行简单测试,test 用户的 .ssh/authorized_keys 为手动创建 root@VM $ ls -Z /root/.ssh/authorized_keys system_u:object_r:unlabeled_t:s0 /root/.ssh/authorized_keys root@VM $ ls -Z /home/test/.ssh/authorized_keys unconfined_u:object_r:ssh_home_t:s0 /home/test/.ssh/authorized_keys # 在 sshd_config 中取消允许公钥登录的注释 # 此时 PermitRootLogin 默认应为 prohibit-password 即为不允许密码登录 root 用户 $ virt-customize -a ./Rocky-9-GenericCloud-Base-9.6-20250531.0.x86_64.qcow2 \ --run-command "sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/g' /etc/ssh/sshd_config"- # 添加公钥, 格式支持文件和字符串 # 参考通用说明 https://libguestfs.org/virt-builder.1.html#ssh-keys $ virt-customize -a ./Rocky-9-GenericCloud-Base-9.6-20250531.0.x86_64.qcow2 \ --ssh-inject root:string:'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFCdvnUa450M4W5o2Ty85H9RKwM8FZbG6ZiKtGEuO+jI shao'