统一 ceph nova-compute 凭据¶
为了使从镜像启动(并通过使用 libvirt-image-backend=rbd 配置存储在 ceph 中)的虚拟机能够成功地实时迁移,Ceph 凭据在所有 nova-compute charm 应用中应保持一致。
问题描述¶
目前,每个 nova-compute charm 应用都会注册一个以 charm 应用自身命名的 Ceph 凭据。因此,如果云中有两个名为 nova-compute-haswell 和 nova-compute-skylake 的 nova-compute charm 应用,那么它们的 Ceph 凭据将分别是各自的名称。
由此导致的问题是,从镜像启动的虚拟机,如果两个 nova-compute charm 应用都配置了 libvirt-image-backend=rbd(导致镜像存储在 ceph 中),则实时迁移将会失败。因为实例的 libvirt XML 将包含与源主机关联的 Ceph 凭据和密钥,而目标主机没有访问该镜像的密钥,从而导致由于权限被拒绝而迁移失败,如 [1] 中所述。
提议的变更¶
为了解决这个问题,所有 nova-compute charm 应用都需要访问相同的 Ceph 凭据,从而访问相同的密钥,使 libvirt XML 中指定的凭据与主机和目标都兼容。
为此,有必要摆脱 Ceph 凭据从 nova-compute charm 应用名称派生的做法。我们建议使用一个在所有应用中通用的新名称:‘nova-compute-ceph-auth-<secret-uuid-first-block>’。
选择上述新凭据名称的原因有很多
作为名称转换的一部分,有必要对 libvirt secret 条目进行更改。libvirt secret 条目由以下内容组成:
secret UUID - 名称/用途 - 密钥
对于每个已注册的 libvirt secret,我们只能更新密钥。为了允许在升级执行凭据转换的 charm 时,现有 VM 继续运行,我们不能删除并替换整个 secret。因此,有必要添加一个带有新凭据和新 UUID 的 secret,同时保留旧 secret。
如果每个现有的名称都被视为旧名称,则从旧名称到新名称的升级路径会更简单。例如,如果我们选择 ‘nova-compute’ 作为新名称,那么已经具有名为 ‘nova-compute’ 的 nova-compute charm 应用的部署需要进行不同的处理。这种方法的主要技术困难再次在于 libvirt secret 管理的限制,它阻止我们添加具有相同名称和新 UUID 的新 libvirt secret,也无法在无需添加新的 secret UUID 的情况下实现所需的功能。
使用极不可能与任何 charm 应用名称冲突的凭据名称可以避免上述情况。通过在凭据名称中使用 secret UUID 的第一个块,我们还可以更轻松地将凭据识别为新的凭据。如果将来需要执行更多凭据名称,则通过遵循此模式,我们可以轻松实现版本控制。
Charm 影响¶
只有 nova-compute charm 受代码更改的影响。ceph-mon charm 不需要代码更改。
升级影响¶
在升级时,从旧凭据过渡到新凭据包括:
每个 nova-compute unit 都需要将新的 application-name 发送到 ceph-mon。Ceph-mon 在第一次收到它时会注册新的凭据(后续收到新的 application-name 不需要重新注册新的凭据,因为它们已经存在),并发送回新凭据的密钥。
Nova-compute unit 在收到更新的密钥后,将使用新的凭据、密钥和 UUID 重写配置文件,并调用 libvirt 注册新的 secret。从那时起创建的新 VM 将使用新的凭据。
nova-compute unit 将其旧凭据密钥文件保留在其 /etc/ceph 文件夹中并在 libvirt 中注册,因此现有工作负载不受影响,并允许 unit 能够接收仍在使用的旧凭据的实时迁移实例。
现有工作负载影响¶
正在运行的现有 VM 将在其 libvirt XML 中声明其旧凭据,并可以继续正常运行,因为保留了旧凭据。需要对这些 VM 进行完全的电源循环才能更新其 libvirt XML 并切换到新的凭据。在重新启动之前,这些 VM 无法迁移到由不同的 nova-compute charm 应用操作的 nova-compute 节点。
扩展影响¶
使用更新的 charm 部署的新节点需要安装旧凭据和新凭据。为此,nova-compute 代码需要在 ceph-relation-joined 上发送旧的 application-name,然后在成功配置旧凭据后,发送新的 application-name 并触发升级路径。最终结果是,新部署的节点将同时具有旧凭据和新凭据,并且可以接收仍在使用的旧凭据的迁移实例。正如 [2] 中已经指出的问题。
回滚/降级可能性¶
不幸的是,如果发生意外情况,降级和回滚更改并不顺利,但相对简单。主要问题是,当前代码没有一种方法可以在 ceph-relation-joined 钩子函数之外将 application-name 重新发送到 ceph-mon,因此必须通过 juju relation-set 命令手动交换此信息。这足以回滚所有更改。
如果在升级或降级过程中出现问题,则可能需要手动维护 libvirt secret,以解决潜在的错误或名称、UUID 或重置密钥的冲突。
Charm 配置选项¶
此更改不会影响任何 charm 配置选项,也不需要添加任何配置选项。但是,此更改仅影响用户配置 libvir-image-backend 设置为 ‘rbd’ 的用户。
配置文件¶
配置文件会受到以下影响:
/etc/ceph/secret.xml - 此文件将被更新,以包含新的 UUID 和凭据名称。它仅用于将 secret 注册到 libvirt 一次。
/etc/ceph/ceph.client.nova-compute-ceph-auth-<secret-uuid-first-block> - 此文件将添加新的凭据的密钥。
/etc/nova/nova.conf - rbd_user 和 rbd_secret_uuid 属性将分别使用新的凭据和 UUID 进行更新。
非 Charm 配置¶
nova-compute 和 ceph charm 之间的 relation-data 更改会影响以下 2 个字段:
application_name - Ceph-mon 将收到 application name nova-compute-ceph-auth-<secret-uuid-first-block>,而不是 nova-compute charm 应用名称。
key - Nova-compute 将收到新的凭据密钥,而不是旧凭据密钥。
OpenStack 版本¶
此功能将为 Yoga 和更高版本的 OpenStack 版本启用。
操作系统版本¶
此功能将为 Ubuntu 20.04 (focal) 和更高版本的 Ubuntu 版本启用。
Juju 版本依赖项¶
此功能没有 Juju 版本的依赖项。
备选方案¶
可以使用 Gerrit topic “lp2028559” 来实现相同结果的替代设计,尽管有一些优点和缺点
更改 relation-data 以在所有 nova-compute unit 之间交换包含所有 nova-compute charm 应用名称和密钥的字典。为此,需要涉及 nova-cloud-controller(因为它当前已经用于交换 SSH 密钥),或者需要在不同的 charm 应用之间的 nova-compute 之间创建一个新的 relation。这种替代方案需要更多的代码更改和 relation 数据结构更改,但最终结果通常更一致且更能抵抗意外行为,例如钩子错误或钩子运行顺序错误。
实现¶
负责人¶
- 主要负责人
ganso
Gerrit Topic¶
使用 Gerrit topic “lp2028559” 用于与此规范相关的所有补丁。
git-review -t lp2028559
仓库¶
这项工作不需要新的存储库。
文档¶
作为这项工作的一部分,需要更新以下文档:
Charm 指南
发行说明
安全性¶
charm 中的更改不会引入任何额外的安全隐患,超出已经存在的安全要求和妥协。
ceph 中的额外凭据和 nova-compute 中的额外密钥受到与现有凭据和密钥相同的漏洞影响。
测试¶
将为该功能实现单元测试和功能测试。功能测试将验证 nova-compute 节点是否具有来自其 charm 应用名称派生的凭据文件,以及新的提议的唯一名称。
目前,CI 中没有配置多个 nova-compute charm 应用,功能测试代码也不支持它们,也没有实时迁移测试。作为未来的工作,可以在不同的 nova-compute charm 应用之间进行实时迁移测试。
工作项¶
在 nova-compute charm 中实现代码更改
将功能测试添加到 zaza-openstack-tests
提供有关更改影响的用户文档
依赖项¶
此更改的功能不需要任何硬件、软件或版本依赖项。