vTPM 实时迁移¶
https://blueprints.launchpad.net/nova/+spec/vtpm-live-migration
当 Nova 首次添加 vTPM 支持时,所有非生成操作都在 API 层面被 拒绝。在移动实例时,需要额外的工作来管理 vTPM 状态。这项工作最终完成了调整大小和冷迁移,并且这些操作被 解禁。对实时迁移、撤离、搁置和救援的阻止仍然 存在。
TPM 设备是 Windows Server 2022 和 2025 的某些功能所 必需的,特别是 BitLocker 驱动器加密。它也是运行 Windows 11 的必要条件。无法实时迁移具有 vTPM 的实例是任何在 OpenStack 云中运行 Windows 客体的主要障碍。
Libvirt 现在支持 vTPM 实时迁移(更多详细信息请参见 问题描述),但在 Nova 更改完成后才能删除 API 阻止。此规范描述了这些更改。
问题描述¶
vTPM 实时迁移有四个方面:共享与非共享 vTPM 状态存储、Libvirt 支持和密钥管理。还有一个相关问题,虽然与实时迁移无关,但可以通过支持实时迁移所需的更改来解决:Nova 无法在计算主机重新启动后启动具有 vTPM 的实例。
vTPM 状态存储¶
vTPM 状态存储与实例状态存储不同,Libvirt 支持使用本地存储和共享存储(如 NFS)来实现两者。
可以通过 source XML 元素告诉 Libvirt 在哪里存储 vTPM 状态,而 Nova 不支持这一点。Nova 部署使用 Libvirt 默认的 vTPM 状态路径。在 Ubuntu 和 Red Hat 操作系统上,此路径为 /var/lib/libvirt/swtpm/<实例 UUID>。此路径与实例状态路径不同。
测试通常侧重于本地存储,未来可以扩展到共享存储,如 NFS。目前 Nova CI 网关没有配置 NFS 的任何作业。
Libvirt 支持¶
虽然找不到 Libvirt 工件明确演示了对非共享 vTPM 状态存储的 vTPM 实时迁移的支持,但从 版本 8.10 开始,支持具有共享 vTPM 存储的 vTPM 实时迁移,并且 此评论 表明,对于非共享存储,vTPM 实时迁移自版本 7.1.0 起就已支持。
因此,此规范需要 Libvirt 7.1.0。截至 2025.1 (Epoxy),我们当前的最低 Libvirt 版本是 8.0.0,因此在实现此功能时,我们不需要进行任何最低版本检查。
密钥管理¶
在创建具有 vTPM 的实例时,Nova 会要求密钥管理器(通常是 Barbican)生成一个密钥。至关重要的是,这是使用用户的令牌完成的,并且创建的密钥由用户拥有,其他人(包括管理员或 Nova 服务用户)都无法读取它。然后 Nova 在 Libvirt 中定义密钥,并在实例 XML 中通过其 UUID 引用该密钥。这告诉 Libvirt 使用该密钥的内容作为对称密钥来加密实例的 vTPM 状态。Nova 在 Libvirt 域成功生成后 取消定义密钥。
为了使 vTPM 实时迁移起作用,需要在目标主机上定义一个具有相同 UUID 和内容的 Libvirt 密钥,以便目标 Libvirt 可以解密 vTPM 状态。目前,Nova 没有办法做到这一点。实时迁移是一项管理员操作,管理员或 Nova 服务用户都无法访问 Barbican 密钥(除非管理员恰好是实例的所有者,但这是一种边缘情况)。由于该密钥被定义为 私有的,并且在域生成后被取消定义,因此也无法在源主机上重新读取该密钥。
计算主机重新启动¶
由于同样的原因(缺乏 Barbican 密钥访问权限以及无法从 Libvirt 中重新读取 Libvirt 密钥),Nova 无法在计算主机重新启动后启动具有 vTPM 的实例。
用例¶
作为云运营商,我希望能够实时迁移具有 vTPM 设备的实例,特别是 Windows 实例。
作为云用户,我希望保持我的实例的 vTPM 内容的私密性。云系统只有在我通过我的用户令牌请求时才能解密它,并且系统应该只在有限的时间内保留解密密钥。我作为用户愿意接受这种隐私要求限制我对实例进行的一些管理员发起的生命周期操作。
作为云运营商,我希望计算主机上的 vTPM 实例在主机重新启动后能够再次启动。
提议的变更¶
由于 vTPM 密钥的安全性(无论是在 Barbican 中还是在 Libvirt 中)都会影响可以对实例执行的操作,因此用户应该能够指定他们需要的安全级别,并且运营商需要指定他们愿意支持的安全级别。还需要应用一个默认级别,如果未明确指定,则应用于实例。
提出了三种可能的安全级别。它们在下表中呈现。
值 |
机制 |
安全影响 |
实例迁移性 |
|---|---|---|---|
|
只有实例所有者才能访问 Barbican 密钥。这是现有行为,也将是默认行为。 |
这是最安全的选项,因为即使 Nova 服务用户和计算主机的 root 都无法读取密钥。 |
实例无法移动,并且无法在计算主机崩溃或重新启动时由 Nova 启动。 |
|
Libvirt 密钥是持久的并且可检索的。 |
这是“中等”安全级别。API 级别的管理员和 Nova 服务用户无法访问密钥,但具有足够权限的计算主机上的用户可以访问它。 |
实例可以实时迁移,因为 Nova 可以从源主机的 Libvirt 中读取密钥,并通过 RPC 发送到目标主机。通过线路上的安全性由运营商负责,但假定使用 TLS 或类似的安全措施。由于相同的原因,实例也可以在计算主机崩溃或重新启动时由 Nova 启动。 |
|
Nova 服务用户拥有 Barbican 密钥。 |
这是最不安全但最灵活的选项。 |
实例可以实时迁移,因为 Nova 可以从 Barbican 下载密钥并在目标主机上定义它。由于相同的原因,实例也可以在计算主机崩溃或重新启动时由 Nova 启动。 |
用户可以通过选择设置新的 hw:tpm_secret_security flavor extra spec 的 flavor 来选择他们需要的级别。如果 flavor extra spec 中未指定特定策略,则实例将默认为 user 策略,这与旧行为相同。
为了简单起见,如果 flavor extra specs 中未设置 hw:tpm_secret_security,则具有 vTPM 的实例将默认为 user TPM 密钥安全策略。
故意不提供新的镜像属性,因为服务器重建在 API 中被阻止。如果用户通过镜像属性选择带有给定 TPM 密钥安全策略的服务器,则该策略将被锁定,并且无法更改。用户无法更改镜像属性,因为他们无法重建,并且他们也无法调整大小到不同的 TPM 密钥安全策略,因为镜像属性和 flavor extra spec 将冲突并以 HTTP 409 失败。
运营商可以使用新的 [libvirt]supported_tpm_secret_security 配置选项来指定他们支持的级别。这是一个每个计算主机的列表选项,可以采用来自上表中的一个或多个安全级别的值。其默认值为所有三个级别。这些值作为驱动程序功能特性公开。 hw:tpm_secret_security flavor extra spec 被转换为与驱动程序功能匹配的必需特性。
实例在实时迁移期间的行为由其持久的嵌入式 flavor hw:tpm_secret_security extra spec 定义。具有 user 的实例无法实时迁移。对于具有 host 的实例,源计算主机从 Libvirt 读取密钥并通过 RPC 发送到目标主机。对于具有 deployment 的实例,目标主机从 Barbican 下载密钥并在 Libvirt 中定义它。由于实例的 hw:tpm_secret_security 值转换为必需的特性,因此可以保证为实时迁移选择的目标主机支持实例所需的任何行为。
备选方案¶
这是此规范的唯一版本,涵盖了基本要素:新实例的用户可以选择他们需要的安全级别,并且运营商可以选择他们愿意支持的安全级别,考虑到较高安全级别施加的限制。
我们还可以提供一个用于选择 TPM 密钥安全策略的镜像属性,但由于当前无法重建具有 vTPM 的实例(它在 API 中被阻止),因此会存在问题。如果用户通过镜像属性选择他们的策略,他们将被锁定到该策略,无法更改。他们无法更改镜像属性值,因为他们无法重建,并且他们也无法通过 flavor extra spec 进行更改,因为镜像属性和 flavor extra spec 将冲突并失败,返回 HTTP 409。
如果将来我们希望支持镜像属性,我们可以同时添加重建 vTPM 实例的能力来做到这一点。目前尚不清楚是否存在任何技术限制阻止实施重建,但我们可以肯定地进行调查。
数据模型影响¶
无。
REST API 影响¶
没有新的微版本。flavor extra spec 验证代码已更新以允许 hw:tpm_secret_security。
安全影响¶
此规范的主要安全后果是 host 和 deployment 值对 hw:tpm_secret_security 的影响。
在 host 的情况下,任何具有足够访问计算主机权限的人都可以读取 vTPM 密钥。虽然这不太好,但用户也选择加入,并且假定计算主机由云运营商保护。
在 deployment 的情况下,Nova 服务用户的妥协会导致所有 vTPM 密钥暴露。同样,这也是用户选择加入的,并且假定 Nova 服务用户是安全的。
通知影响¶
无。
其他最终用户影响¶
无。
性能影响¶
无。
其他部署者影响¶
无。
开发人员影响¶
无。
升级影响¶
需要计算服务版本更新。
在部署的最低服务版本达到升级版本之前,将阻止实时迁移具有 vTPM 的实例。云必须完全升级。
部署者必须创建具有将 hw:tpm_secret_security extra spec 设置为 host 或 deployment 的 flavor,以便启用具有相应 TPM 密钥安全策略的实例的创建。
任何未设置此项的实例都是预先存在的实例,为了简单起见,它们将不会被迁移。如果用户希望选择加入实时迁移,他们可以将现有的实例调整大小到具有将 hw:tpm_secret_security extra spec 设置为 host 或 deployment 的 flavor。
将预先存在的实例自动迁移到 TPM 密钥安全策略可以讨论并作为未来的工作来考虑。
实现¶
负责人¶
- 主要负责人
notartom, melwitt
功能联络人¶
- 功能联络人
melwitt, dansmith
工作项¶
引入
hw:tpm_secret_securityflavor extra spec 和[libvirt]supported_tpm_secret_security配置选项将
vtpm_secret_uuid和vtpm_secret_value字段添加到LibvirtLiveMigrateData对象中,以便在hostTPM 密钥安全策略的情况下,将数据通过 RPC 从源主机携带到目标主机修改预实时迁移和回滚代码以处理密钥定义和清理
修改调整大小代码以处理 TPM 密钥安全策略转换,包括预先存在的实例的 TPM 密钥安全策略的缺失
更新服务版本
修改现有的 API 阻止,以便在最低服务版本达到更新版本后,仅允许实时迁移
host或deployment实例添加白盒/集成测试
如果可能,添加常规 Tempest 测试
更新文档
依赖项¶
Libvirt 版本 7.1.0。这可以在代码中动态强制执行。
测试¶
Nova 的功能测试已扩展为使用 Libvirt fixture 测试 Nova 逻辑。这对于无法在真实环境中轻松测试的情况特别有用,例如回滚。
现有的 whitebox-tempest-plugin vTPM 测试 已扩展,以在实际环境中,使用真实的 Libvirt 测试实时迁移。
文档影响¶
Nova 的 vTPM 文档 已更新,以移除实时迁移的限制,并解释 supported_tpm_secret_security 配置选项的用法,以及所有可能值的影响。明确说明 vTPM 状态存储不共享,并且共享 vTPM 状态存储的实时迁移未经测试。
参考资料¶
空。
历史¶
发布名称 |
描述 |
|---|---|
2026.1 Gazpacho |
重新提出 |
2025.2 Flamingo |
重新提出 |
2025.1 Epoxy |
引入 |