允许对关闭 VM 的操作进行受控的 GuestOS 关闭¶
https://blueprints.launchpad.net/nova/+spec/user-defined-shutdown
当前不给 Guest 操作系统机会执行受控关闭而直接关闭 VM 的行为可能导致数据损坏。
问题描述¶
目前在 libvirt 中的操作(停止、救援、挂载、调整大小)在关闭 VM 时不会给 GuestOS 以优雅关闭的机会。某些 GuestOS(例如 Windows)对这种虚拟电源故障反应不佳,因此最好让这些操作遵循与 soft_reboot 相同的方法,并给 GuestOS 以优雅关闭的机会。
提议的变更¶
拟议的更改将使停止、救援、调整大小和挂载的默认行为是在关闭 VM 之前给 GuestOS 以执行受控关闭的机会。
该更改将在 hypervisor 中封装向 GuestOS 发出信号并等待其关闭的复杂性,并允许镜像所有者通过镜像元数据调整相关时间,以考虑需要较长时间才能关闭的 GuestOS(例如 Windows)。
用户可以通过新的 shutdown_type 参数在每次操作的基础上指定关闭行为,与当前的 reboot 操作保持一致,其中“soft”关闭将给 GuestOS 以执行干净关闭的机会,而“hard”关闭将导致立即断电。默认行为将是“soft”关闭。
一个想要覆盖默认行为的用户示例是 Tempest,它通常不关心 GuestOS 是否会损坏,并且可能更喜欢执行速度而不是数据完整性。
在 hypervisor 层,关闭行为将由两个值控制
一个超时值,以秒为单位指定 hypervisor 应等待 GuestOS 关闭多长时间。如果 GuestOS 在此期间未关闭,则 VM 仍将被关闭。值为 0 将在不向 Guest 发出信号的情况下关闭 VM。
一个重试间隔,以秒为单位指定在所述期间 hypervisor 应多久向 guest 发出关闭信号。这是为了防止 guest 在第一次发出信号时尚未准备好处理关闭信号 - 如果实例在创建后立即被删除,则这是一个常见问题,并且 GuestOS 正在启动。
例如,如果总超时设置为 60 秒,而重试间隔设置为 10 秒,则将在断电之前向 guest 发送多达六次信号。
这些值将由计算管理器传递给 virt 驱动程序,从而允许对所有 hypervisor 使用相同的值。
超时值将是 Nova 配置参数,因为不同的操作员可能希望有不同的默认值。重试值将在 Nova 代码中实现为常量。可以通过镜像元数据设置覆盖每个镜像的超时值。
备选方案¶
另一种方法是公开一个新的操作,该操作仅关闭 GuestOS(使用用户定义的时序参数),通过 API 公开该操作的状态,并依赖于客户端进行所有重试逻辑。但是,我们认为干净关闭应该是 Nova 中的默认行为,而不必将其作为单独的活动进行管理(这必须在所有 API 绑定中复制)。
之前合并了一个使用更简单的单个参数来指定 hypervisor 应等待多长时间的替代方案,但由于它使 Tempest 运行时间增加了大约 25 分钟,因此不得不撤销:https://review.openstack.org/#/c/35303/
这是由于 Tempest 经常在创建实例后立即停止实例,在这种情况下,ACPI 信号在 GuestOS 处于可以处理它的状态之前被传递。这导致关闭等待整个超时期间。
上述修订后的方法通过定期重新发送关闭信号给 GuestOS 来避免此问题。
一旦此更改合并,Tempest 可以优化以避免此延迟(例如,通过通过镜像元数据或 nova.conf 将超时设置为零)。
有人可能会认为 delete 操作也应该允许相同的受控关闭方案,以便使用和/或从卷启动的实例也可以将这些文件系统置于安全状态。但是,如果修改 stop 操作以提供受控关闭,则用户可以通过在 delete 之前执行 stop 来实现所需的序列。这还避免了 http delete 请求通常不接受正文的问题。
数据模型影响¶
无,该更改主要包含在计算管理器和 virt 驱动程序之间的交互中。
REST API 影响¶
以下 API 方法将扩展为接受可选的 shutdown_type 参数
- Stop POST servers/{server_id}/action
{“os-stop”: {“shutdown_type”: “HARD|SOFT”}}
- Rescue POST servers/{server_id}/action
{“rescue”: {“shutdown_type”: “HARD|SOFT”}}
- Resize POST servers/{server_id}/action
- {“resize”: {“shutdown_type”: “HARD|SOFT”,
“flavor_id”: <id>}}
- Shelve POST servers/{server_id}/action
{“shelve”: {“shutdown_type: “HARD|SOFT”}}
- Migrate POST servers/{server_id}/action
{“migrate”: {“shutdown_type: “HARD|SOFT”}}
安全影响¶
无,该更改不会更改用户可以执行的操作集。
通知影响¶
无。
其他最终用户影响¶
用户将能够为 stop、rescue 和 delete 提供其他选项。这些将在 python-novaclient 中公开
nova stop [–hard-shutdown] nova rescue [–hard-shutdown] nova resize [–hard-shutdown] nova shelve [–hard-shutdown]
请注意,这里“–hard-shutdown”优于 reboot 中使用的“–hard”选项,因为“soft resize”可能会被解释为对分配资源的软更改(例如禁用 cpu)。
为了使 novaclient CLI reboot 命令保持一致,它也将被修改为接受 –hard-shutdown 作为 –hard 的别名。
性能影响¶
性能影响仅限于 stop、rescue 和 delete 操作的处理路径中的更改。在执行干净关闭时,这些操作将比以前花费更长的时间,因为系统会等待 GuestOS 关闭。观察这种状态变化的轮询开销可以忽略不计,并且调用线程将在每次轮询之间休眠(让出)。
其他部署者影响¶
一旦此组更改合并,系统默认配置将等待实例在 stop、shelve、rescue 和 resize 操作期间优雅关闭。
部署者需要考虑是否要修改默认超时参数,和/或将覆盖值添加到现有镜像的元数据中。
配置参数将对所有 hypervisor 都是通用的,但此 BP 仅提供 libvirt 实现。
开发人员影响¶
只有第一阶段的实现是 hypervisor 依赖的,一旦合并,就可以添加其他 hypervisor 实现。
剩余阶段将适用于实现修订后的 power_off 选项的任何 hypervisor。
实现¶
负责人¶
- 主要负责人
philip-day
工作项¶
将超时参数添加到 virt 驱动程序的 virt power_off 方法中,并提供 libvirt 实现。将 clean_shutdown 实现到计算管理器的 stop() 中作为初始示例。
将 clean_shutdown 选项添加到计算管理器 Rescue、Resize 和 Shelve 操作
使用镜像属性覆盖超时值
通过 rpcapi 公开 clean shutdown
通过 API 公开 clean shutdown
依赖项¶
无
测试¶
正在修改的方法已经过 Tempest 进行了广泛测试,这将确保不会出现功能回归。
默认行为将是执行干净关闭,尽管很难看出 Tempest 如何验证这一点,因为它需要在 Guest 中提供特定的支持,并且任何 GuestOS 的行为通常被认为超出 Nova 的范围。同样,Tempest 可以行使不进行干净关闭的能力(Tempest 可能会将其作为其正常情况),但很难看出如何验证它。将向 Tempest 社区征求意见,以了解可以采取哪些措施来解决这些问题。
文档影响¶
需要更新 API 规范。
需要记录 stop、rescue、resize 和 shelve 的默认行为更改(等待 GuestOS 关闭)。
需要记录在每个镜像的基础上覆盖关闭超时值的能力。
参考资料¶
第一个工作项的代码可供审查 https://review.openstack.org/#q,I432b0b0c09db82797f28deb5617f02ee45a4278c,n,z