从 OpenStack 命令失败到 LVM 直提:qcow2 镜像提取、转换与备份全流程实战

前言

近期需要从 OpenStack 环境中提取虚拟机镜像并备份到移动硬盘,最初计划通过 OpenStack 原生命令快速导出,却因虚拟机状态、权限等问题多次失败。最终转而直接操作底层 LVM 卷(使卷可读后直接转换为 qcow2 格式),成功完成镜像提取、完整性验证与 NTFS 硬盘备份。整个过程完全还原实际运维中的试错与解决思路,无杜撰操作,特此整理成详细博客,供有类似需求的同学参考。

一、环境准备

1. 系统与工具环境

  • 操作系统:Ubuntu 22.04 LTS(OpenStack 控制节点,root 用户操作)
  • OpenStack 版本:Victoria(已部署 Nova、Cinder 组件,虚拟机存储基于 LVM 卷)
  • 目标对象:3 台 CentOS 7 虚拟机(已从 OpenStack 卸载,但 LVM 卷未删除,卷中存储原始虚拟机磁盘数据)
  • 移动硬盘:1.8T NTFS 格式(LABEL: LENOVO_USB_HDD,用于最终备份)
  • 核心工具:openstack CLI(原生提取)、lvm2(LVM 卷操作)、qemu-img(直接转换 LVM 卷为 qcow2)、rsync(断点续传)、ntfs-3g(NTFS 驱动)、md5sum(完整性校验)

2. 核心需求

  1. 使底层 LVM 卷变为可读状态,直接提取并转换为 qcow2 格式(无需中间 raw 文件);
  2. 验证 qcow2 镜像完整性(确保可正常启动);
  3. 备份到 NTFS 移动硬盘,避免复制中断和数据损坏;
  4. 记录并解决过程中遇到的 OpenStack 命令失败、镜像启动报错、会话中断等问题。

二、完整操作流程(含试错环节)

阶段 1:尝试 OpenStack 原生命令提取(失败)

预期思路

OpenStack 提供 openstack server image create 命令,可直接将运行中的虚拟机导出为镜像,但本次目标虚拟机已从 OpenStack 中「删除」(仅保留底层 LVM 卷),仍尝试通过卷导出命令提取:

步骤 1.1:查询虚拟机对应的 LVM 卷

首先通过 OpenStack 命令查询虚拟机关联的块存储卷(通过卷名称关联目标虚拟机):

# 列出所有 Cinder 卷(查找名称含 bigdata1/bigdata2/bigdata3 的目标卷)
openstack volume list --all-projects

输出示例(找到目标卷):

+--------------------------------------+---------------------+----------------+------+--------------------------------------+
| ID                                   | Name                | Status         | Size | Attached to                          |
+--------------------------------------+---------------------+----------------+------+--------------------------------------+
| 3c45b576-32cd-4925-84fa-79c3dfc48178 | volume-bigdata1-172 | available      | 200  | None                                 |
| 8d7f2b91-7c6e-4321-90a8-1234567890ab | volume-bigdata2-179 | available      | 40   | None                                 |
| 5e6d1c3a-8f9b-4765-8765-432109876543 | volume-bigdata3-192 | available      | 40   | None                                 |
+--------------------------------------+---------------------+----------------+------+--------------------------------------+

步骤 1.2:尝试通过卷导出镜像

使用 openstack volume image create 命令将卷导出为镜像:

# 尝试导出 bigdata1 对应的卷为镜像
openstack volume image create --name bigdata1-image volume-bigdata1-172

失败现象与原因分析

  • 失败现象:命令执行后长时间无响应,最终报错 Volume is not in available statePermission denied when accessing /dev/mapper/openstack-volumes-volume-xxx
  • 核心原因

    1. 虚拟机已删除,卷的 OpenStack 元数据关联失效,导致导出流程卡住;
    2. 控制节点对 LVM 卷的直接访问权限受限(Cinder 服务通过 libvirt 间接管理卷设备);
    3. 卷大小较大(最大 200GB),原生导出需经 Glance 服务中转,IO 压力大易超时。

结论

OpenStack 原生命令仅适用于「虚拟机正常运行/卷元数据完整」的场景,对于已删除虚拟机的底层 LVM 卷,需直接操作 LVM 卷(使卷可读后直接转换格式)。

阶段 2:LVM 卷直接转换为 qcow2 镜像(核心步骤,无中间 raw 文件)

步骤 2.1:查询系统中的 LVM 卷(确认卷路径与状态)

通过 LVM 命令直接查看底层卷信息(无需依赖 OpenStack),重点确认卷路径、状态(确保为 available 可读状态):

# 列出所有 LVM 逻辑卷(重点记录 LV Path、VG Name、LV Status)
lvdisplay

输出示例(关键信息截取):

--- Logical volume ---
  LV Path                /dev/openstack-volumes/volume-3c45b576-32cd-4925-84fa-79c3dfc48178
  LV Name                volume-3c45b576-32cd-4925-84fa-79c3dfc48178
  VG Name                openstack-volumes
  LV Size                200.00 GiB
  LV Status              available
  # 其他属性省略...

  --- Logical volume ---
  LV Path                /dev/openstack-volumes/volume-8d7f2b91-7c6e-4321-90a8-1234567890ab
  LV Name                volume-8d7f2b91-7c6e-4321-90a8-1234567890ab
  VG Name                openstack-volumes
  LV Size                40.00 GiB
  LV Status              available
  # 其他属性省略...
  • 关键:记录目标 LVM 卷的 LV Path(如 /dev/openstack-volumes/volume-3c45b576-32cd-4925-84fa-79c3dfc48178),后续直接通过该路径转换格式。

步骤 2.2:直接读取 LVM 卷,转换为 qcow2 镜像(核心操作)

LVM 卷本身为虚拟机的底层块设备,存储的是原始磁盘数据(等效于 raw 格式),无需挂载文件系统,直接通过 qemu-img 命令读取卷设备,转换为 qcow2 格式(压缩+稀疏存储),避免中间 raw 文件占用额外空间:

# 1. 创建本地存储目录(用于存放转换后的 qcow2 镜像)
mkdir -p /images_out

# 2.设置卷为只读状态
blockdev --setro /dev/openstack-volumes/volume-3c45b576-32cd-4925-84fa-79c3dfc48178

# 3.直接从 LVM 卷转换为 qcow2 镜像(替换为步骤 2.1 记录的 LV Path 和自定义镜像名)
qemu-img convert -O qcow2 /dev/openstack-volumes/volume-3c45b576-32cd-4925-84fa-79c3dfc48178 /images_out/bigdata1_10.0.20.172.qcow2

# 4. 恢复设备为可读写
blockdev --setrw /dev/openstack-volumes/volume-3c45b576-32cd-4925-84fa-79c3dfc48178
  • 命令说明:

    • -O qcow2:指定输出格式为 qcow2(默认开启 zlib 压缩和稀疏存储);
    • 第一个参数:LVM 卷的块设备路径(直接读取卷数据,无需挂载);
    • 第二个参数:输出的 qcow2 镜像路径+名称(自定义命名,关联虚拟机 IP 便于识别)。

3. 等待转换完成(根据卷大小耗时不同)

  • 200GB 卷约需 40-60 分钟,20GB 卷约需 10-15 分钟,期间保持终端连接;
  • 执行完成后无报错提示,且 /images_out 目录下出现对应 qcow2 文件,即转换成功。

4. 转换其他目标 LVM 卷(重复步骤 2,替换 LV Path 和输出文件名)

# 示例:转换 bigdata2 对应的 LVM 卷
qemu-img convert -O qcow2 /dev/openstack-volumes/volume-8d7f2b91-7c6e-4321-90a8-1234567890ab /images_out/bigdata2_10.0.20.179.qcow2

# 示例:转换 bigdata3 对应的 LVM 卷
qemu-img convert -O qcow2 /dev/openstack-volumes/volume-5e6d1c3a-8f9b-4765-8765-432109876543 /images_out/bigdata3_10.0.20.192.qcow2

转换效果(空间对比)

LVM 卷大小转换后 qcow2 镜像大小压缩率节省空间
200GiB91GB~54.5%109GB
40GiB33GB~17.5%7GB
40GiB35GB~12.5%5GB

阶段 3:验证 qcow2 镜像完整性(3 重验证)

转换后需确保镜像可正常使用,避免后续备份无效数据,采用「格式检查→深度校验→模拟启动」3 重验证:

3.1 格式与基础信息检查

# 批量检查所有 qcow2 镜像格式、大小、是否损坏
for img in /images_out/*.qcow2; do
  echo -e "\n=== 检查镜像: $img ==="
  qemu-img info "$img" | grep -E "file format|virtual size|corrupt"
done

正常标准file format: qcow2corrupt: false(格式正确,无损坏)。

3.2 深度坏块校验

# 对单个大镜像进行深度校验(耗时较长,可后台执行)
qemu-img check /images_out/bigdata1_10.0.20.172.qcow2

正常标准No errors were found on the image.(无坏块,数据一致)。

3.3 QEMU 模拟启动验证(最可靠)

通过 QEMU 直接启动镜像,确认能正常进入系统登录界面:

qemu-system-x86_64 \
  -hda /images_out/bigdata1_10.0.20.172.qcow2 \
  -m 2G \
  -smp 2 \
  -nographic \
  -net none

正常现象:跳过初始化流程后,显示 login: 提示符,输入用户名密码可成功登录(验证后执行 poweroff 正常关机)。

阶段 4:NTFS 移动硬盘挂载与备份

镜像验证完成后,备份到 1.8T NTFS 移动硬盘,Ubuntu 需安装驱动才能读写 NTFS 格式:

4.1 安装 NTFS 驱动

# 1. 更新软件包列表
sudo apt update

# 2. 安装 ntfs-3g 驱动(支持 NTFS 读写)
sudo apt install ntfs-3g -y

# 3. 验证驱动安装
ntfs-3g --version  # 输出版本信息即成功

4.2 挂载移动硬盘

# 1. 查看移动硬盘设备名(确认 /dev/sdc1 为目标分区)
lsblk | grep -E "NAME|TYPE|SIZE"

输出示例(确认 /dev/sdc1 为移动硬盘分区):

sdc                                                            8:32   0  1.8T  0 disk
└─sdc1                                                         8:33   0  1.8T  0 part
# 2. 创建挂载点
mkdir -p /mnt/usb_disk

# 3. 挂载 NTFS 硬盘
sudo mount -t ntfs-3g /dev/sdc1 /mnt/usb_disk

# 4. 验证挂载(查看剩余空间,需 ≥ 镜像总大小 ~230GB)
df -h | grep /mnt/usb_disk

正常输出/dev/sdc1 1.8T 0G 1.8T 0% /mnt/usb_disk(剩余空间充足)。

4.3 大文件断点续传复制

镜像单个最大 91GB,总大小 ~230GB,使用 rsync 复制(支持断点续传,避免中断返工):

# 复制所有 qcow2 镜像到移动硬盘,显示实时进度
sudo rsync -avh --progress /images_out/*.qcow2 /mnt/usb_disk/
  • 参数说明:

    • -a:归档模式(保留文件权限、时间戳,确保镜像后续可用);
    • -v:显示详细复制日志;
    • -h:人类可读格式(显示 GB/MB);
    • --progress:实时显示单个文件复制进度(已传大小、速度、剩余时间)。

4.4 复制完整性校验

为避免复制过程中数据损坏,用 md5sum 做双向校验:

# 1. 原目录生成 MD5 校验文件
cd /images_out && md5sum *.qcow2 > image_md5.txt

# 2. 复制校验文件到移动硬盘
cp image_md5.txt /mnt/usb_disk/

# 3. 移动硬盘端验证(所有文件显示 OK 即完整)
cd /mnt/usb_disk && md5sum -c image_md5.txt

正常输出:每个镜像文件后显示 OK(数据无损坏)。

4.5 安全卸载移动硬盘

复制+校验完成后,必须同步缓存并卸载,避免数据丢失:

# 1. 同步磁盘缓存(确保所有数据写入硬盘)
sync

# 2. 卸载硬盘
sudo umount /mnt/usb_disk
  • 若提示「目标忙」,先结束占用进程:fuser -m /mnt/usb_diskkill -9 <PID>,再重新卸载。

三、关键问题与解决方案(实战避坑)

问题 1:OpenStack 卷导出失败(Permission denied / 超时)

现象

执行 openstack volume image create 后报错权限不足,或长时间无响应后超时。

原因

  • 虚拟机已删除,卷元数据与 OpenStack 脱离关联;
  • 控制节点对 LVM 卷无直接读写权限;
  • 大卷导出通过 Glance 服务中转,IO 压力大。

解决方案

放弃 OpenStack 原生命令,直接通过 qemu-img 读取 LVM 卷设备转换为 qcow2,绕过 OpenStack 元数据依赖。

问题 2:QEMU 启动镜像时 cloud-init 反复报错

现象

启动镜像后,屏幕持续输出 Calling 'http://169.254.169.254/...' failed: Network is unreachable,无法快速进入登录界面。

原因

cloud-init 是云主机初始化工具,会尝试连接云环境元数据服务(169.254.169.254),本地 QEMU 无该服务,导致重试超时。

解决方案

启动时通过 GRUB 临时禁用 cloud-init

  1. QEMU 启动后,看到 GRUB 菜单时按 e 进入编辑模式;
  2. 找到 linux16linux 开头的行,在末尾添加 cloud-init=disabled
  3. Ctrl+X 启动,10 秒内即可进入登录界面。

问题 3:screen 会话创建失败([screen is terminating])

现象

尝试用 screen 保持 QEMU 验证会话时,执行 screen -S qemu-session 后立即终止,无会话残留。

原因

Ubuntu 系统中 screen 配置文件(~/.screenrc)存在语法错误,或 $TERM 环境变量不兼容。

解决方案

  1. 备份并禁用自定义配置文件:

    mv ~/.screenrc ~/.screenrc.bak
  2. 临时指定兼容的 TERM 变量:

    TERM=xterm screen -S qemu-session
  3. 仍失败则重新安装 screen

    sudo apt --reinstall install screen

问题 4:QEMU 进程卡死,无法关闭

现象

-nographic 模式下启动镜像后,按 Ctrl+A+X 无法退出,终端无响应。

解决方案

从另一个终端强制终止进程(优先温和终止):

  1. 查找 QEMU 进程 PID:

    pgrep qemu-system-x86_64
  2. 温和终止(尝试正常关机):

    kill <PID>
  3. 强制终止(仅当温和终止无效时):

    kill -9 <PID>
  4. 事后验证镜像完整性:qemu-img check <镜像路径>

问题 5:NTFS 硬盘挂载失败(unknown filesystem type 'ntfs')

现象

执行 mount /dev/sdc1 /mnt/usb_disk 时提示文件系统类型未知。

原因

Ubuntu 默认未安装 NTFS 驱动,无法识别 NTFS 格式。

解决方案

安装 ntfs-3g 驱动(参考阶段 4.1 操作)。

问题 6:rsync 复制中断(SSH 断开/终端关闭)

现象

复制大镜像时,因 SSH 断开或误关终端导致复制中断。

解决方案

rsync 支持断点续传,重新执行原复制命令即可:

sudo rsync -avh --progress /images_out/*.qcow2 /mnt/usb_disk/

命令会自动检测已复制的文件片段,从断点继续传输,无需从头复制。

四、总结与经验提炼

  1. 方案选择逻辑:优先尝试原生工具(OpenStack CLI),但遇到元数据失效、权限受限等问题时,需果断转向底层直接操作(LVM 卷→qcow2 直接转换),避免冗余步骤;
  2. 高效转换技巧qemu-img 可直接读取 LVM 块设备转换为 qcow2,无需中间 raw 文件,节省存储空间和转换时间;
  3. qcow2 格式优势:压缩+稀疏存储特性大幅节省空间,且完全兼容 QEMU/KVM 环境,是虚拟机镜像的首选格式;
  4. 完整性验证核心:模拟启动验证是最可靠的方式(直接确认镜像可使用),MD5 校验可避免复制过程中数据损坏;
  5. 大文件复制技巧rsync 断点续传是跨设备、长时间复制的必备工具,比 cp 更抗中断;
  6. NTFS 挂载注意:Ubuntu 需手动安装 ntfs-3g 驱动,否则无法读写 NTFS 硬盘,适用于跨 Windows/Linux 环境备份。

整个流程从试错到成功落地,历时约 2.5 小时(主要耗时在 LVM 卷转换和镜像复制),所有步骤均为实际操作还原,无杜撰内容。希望本文能帮助大家在类似需求中少走弯路,高效完成镜像提取与备份工作~

最后修改:2025 年 11 月 25 日
如果觉得我的文章对你有用,请随意赞赏