跳转到: 导航, 搜索

Fuel/外部快照

外部快照

我们根据 libvirt 文档,将外部快照视为外部形式的“系统检查点”类型快照 https://libvirt.org/formatsnapshot.html#SnapshotAttributes

什么是外部快照?

外部快照是外部形式的两种类型快照的组合

  • 磁盘快照 - 包含磁盘内容
  • 内存(或虚拟机)状态 - 仅跟踪 RAM 和虚拟机使用的所有其他资源的状态


外部形式意味着快照不是创建在一个文件中,而是创建在不同的文件中,与内部形式不同。
磁盘快照是一对文件:至少一个用于快照本身,另一个用于在创建快照后写入更改(快照文件 - 是此文件的备份存储)。
在外部形式下,内存状态也是一个单独的文件。

外部快照中的卷链

在使用外部快照时,必须考虑一个特性:磁盘的多个连续外部快照会创建一个卷链。每个后续快照都是与前一个快照以及前一个快照相关的所有卷的“增量”。依此类推,直到基本卷。这是由于磁盘外部快照的设计所致。

Fuel 系统测试环境中的外部快照

外部快照支持已添加到 fuel-devops 应用程序。
要在 fuel-devops 中开始使用外部快照,只需定义 SNAPSHOTS_EXTERNAL 环境变量并将其值设置为“true”。
export SNAPSHOTS_EXTERNAL=true

它是如何工作的?

Fuel-devops 对环境中的每个节点执行以下步骤:

创建快照

  • 创建一个卷,并将当前设置的磁盘作为备份存储以保存快照后的更改(为连接到虚拟机的每个磁盘创建)。
    这样做是为了在 fuel-devops 数据库中拥有新的卷,以便将来能够控制该卷。
  • 定义内存状态文件的路径
  • 使用 snapshot libvirt 功能从生成的 XML 定义创建快照
  • 将快照重新定义为当前快照

将虚拟机恢复到快照状态

  • 销毁节点
  • 选择在虚拟机恢复后使用的卷
    • 如果它是链中的最新快照,将使用相同的卷(重新创建卷)。
    • 否则将创建新卷
  • 使用 restore libvirt 功能启动虚拟机

已知问题

事实证明,在使用 host-passthrough cpu 模式时无法创建外部快照。原因如下:

  • virDomainSnapshotGetXMLDesc 函数不会在快照 XML 定义中返回 cpu 模型
  • libvirt 禁止在修改快照定义期间更改 cpu 模型


需要完整的快照 XML 定义才能将快照重新定义为当前快照。为了避免此问题,已实现从域定义获取 cpu 模型并将其注入快照定义的功能。 另外,作为一种解决方法,可以在创建环境之前通过将 DRIVER_USE_HOST_CPU 变量设置为 false 来禁用 host-passthrough 模式。
export DRIVER_USE_HOST_CPU=false


未来外部快照的使用计划

导出和导入环境

假设我们有有限数量的节点(例如 Jenkins 从节点),可以在这些节点上执行部署测试。如果测试失败,则需要禁用发生故障的节点,以便能够执行根本原因分析。这会导致资源稀缺并降低 CI 环境的整体性能。在这种情况下,最好能够将环境从一个节点(我们称之为 源节点,例如 Jenkins 从节点)导出到另一个节点(目标节点,例如用于故障排除和分析的备份节点)。这样可以使节点从失败的环境中释放出来,并将其返回到 CI 环境。

由于此任务不简单,首先考虑目标节点用于导入环境是空的,即 libvirt 环境中不包含任何节点、项目等。

系统测试环境由以下部分组成:

  1. fuel-devops DB 中的记录(以便能够使用 libvirt 对象)
  2. Libvirt 环境(域、网络、卷、快照等)

目前,导出和导入 systest 环境的步骤已实现为 shell 脚本。

导出环境

NOTE: Steps 7 - 9 are implemented in a separate script as it needs root privileges to run.

这里有一系列导出环境的步骤(使用 libvirt virsh 和 psql)::

  1. 从 fuel-devops DB 导出记录(psql -c '\copy ...'
  2. 转储存储池定义(pool-dumpxml
  3. 转储网络定义(net-dumpxml
  4. 转储卷定义(vol-dumpxml
  5. 转储域定义(dumpxml
  6. 下载卷(vol-download)。它在当前使用的 libvirt 1.2.12 中表现出较差的性能。相关错误:(https://bugzilla.redhat.com/show_bug.cgi?id=1026136 https://bugzilla.redhat.com/show_bug.cgi?id=1026137)。因此,我们需要升级 libvirt 或实现直接复制卷(移动到单独的脚本,如 7-9 步中所做)。
  7. 转储快照定义。目前使用直接复制,因为实现起来更容易,因为snapshot-dumpxml 返回的 XML 文件在 cpu 模式为“host-passthrough”时(默认设置)没有 cpu 模型,也没有 libvirt 需要的 <active/> 标签。
  8. <active>1</active> 设置为将设置为当前快照的 XML 定义(要导出的快照列表中的第一个),并将 <active>0</active> 设置为所有其他快照定义
  9. 复制内存状态文件(用于快照)

导入环境

NOTE:There're 2 ways to import snapshots:
 1. Replay snapshots, i.e. create snapshots in the same order as it was done on the source node
and then redefine ones using exported definitions 2. Add snapshots definitions to /var/lib/libvirt/qemu/snapshot/<domain> directory

第一种方法比较复杂,因为在许多快照和复杂的快照创建方案的情况下,有很多步骤需要执行。此外,还需要考虑到所有“重放”的快照必须与源快照的状态相同。
第二种方法要容易得多,因为它只需要将快照定义放入 libvirt 快照目录并将内存状态文件复制到与源节点上相同目录即可。为此,我们需要 root 权限。

目前已实现第二种方法。
这里有一系列导入环境的步骤(使用 libvirt virsh)::

  1. 将记录导入到 fuel-devops DB(psql -c '\copy ...'
  2. 从定义创建存储池并自动启动它(pool-definepool-startpool-autostart
  3. 从定义创建网络并自动启动网络(net-definenet-startnet-autostart
  4. 从定义创建卷(vol-create
  5. 将内容从导出的文件上传到卷(vol-upload
  6. 从定义创建域(define
  7. 将内存状态文件放置到与源节点上相同路径
  8. 将快照 XML 定义复制到 /var/lib/libvirt/qemu/snapshot/<domain> 目录
  9. 重新启动 libvirt 守护程序