将控制台转换为使用对象框架¶
https://blueprints.launchpad.net/nova/+spec/convert-consoles-to-objects
使控制台使用对象框架——当前的控制台代码没有利用框架对象,而是提供了一些类型(console/type.py)来处理它们。这些类型不提供任何处理版本控制、RPC 或任何使其有用的方法的功能。
问题描述¶
当前代码没有提供任何处理版本控制的机制。此外,由于 RPC 无法处理从 Python 对象类型派生的类,我们需要在 RPC 调用之间处理一个“connect_info”字典,并且没有提供任何方法来跨进程共享控制台的状态。
另一个问题在于令牌,memcached 不是数据库,无法保证尊重过期时间,令牌可能会在限制之前过期(驱逐)。通过使用框架对象,我们可以有机会将整个 Console 对象的状态与数据库中的有效令牌一起存储,并在进程之间共享状态。
例如,bug 1425640 需要知道用户从多个角度连接到特定端口的时间:从计算节点,返回下一个定义的未连接端口;从代理,拒绝已连接端口上的新连接;从 API,让用户知道没有更多可用端口。
我们还将通过仅将令牌的哈希值存储在数据库中来增强安全性,在将干净的令牌返回给用户之后。然后,当用户请求连接控制台时,传递的令牌将被哈希并与数据库中存储的令牌进行比较以进行验证。
将引入一个新的选项 [workarounds]enable_consoleauth,它将允许操作员选择启用同时使用数据库和旧版 consoleauth 后端。使用这种方式的原因是,如果操作员不希望他们所有现有的控制台授权在数据库后端可用时失效。通常,控制台授权的 TTL 是短期的(默认是 10 分钟),因此使现有控制台失效通常不是问题。但是,如果操作员配置了更长的 TTL,他们可能希望利用 [workarounds]enable_consoleauth 选项,以便为已存在的控制台回退到 consoleauth。一旦所有预数据库后端控制台授权都已过期,操作员可以将 [workarounds]enable_consoleauth 设置回 False 并停止运行 consoleauth 服务。
consoleauth 服务将保留用于旧版兼容性,但处于弃用状态,支持一个发布版本。在此期间,consoleauth 服务可以被移除。
由于新的令牌将进入数据库,我们需要考虑 cells v2。子单元数据库是控制台连接信息的适当位置,因为它直接与实例相关。目前,返回给用户的控制台连接 URL 仅包含一个令牌。这不足以确定哪个单元持有控制台连接。最初的想法是向控制台代理 URL 添加实例 UUID 并使用它来针对实例的单元数据库验证控制台代理的源协议。但是,当我们向 URL 添加实例 UUID 时,Tempest 任务在 noVNC 测试中失败,因为 noVNC 无法分隔 URL 中的多个查询参数,因此 URL 的 ?instance_uuid=<uuid> 部分被视为令牌的一部分,第一个查询参数 token=<token>。因此,我们将通过为每个单元运行控制台代理而不是全局部署来解决单元数据库问题,这样单元数据库将位于控制台代理的本地。这种方法与现有的控制台代理兼容,并且通过将代理分片到每个单元而不是所有控制台通过一个集中式代理来减少大型部署的负载。
用例¶
开发人员可以在添加新的控制台或功能时利用框架对象。
提议的变更¶
定义一个新的 ConsoleAuthToken 对象。
将驱动程序转换为生成 ConsoleAuthToken 对象。
定义模式和 API,以将 ConsoleAuthToken 对象存储在子单元数据库中。
更新代码,以将带有有效令牌的 ConsoleAuthToken 存储在数据库或 consoleauth 中,具体取决于开关,直到 consoleauth 被移除。
更新代理,以使用数据库或 consoleauth,具体取决于开关,直到 consoleauth 被移除。
定义一个定期任务来清理数据库中存储的过期对象;为了平衡负载并避免长时间阻塞数据库,每个计算节点将负责清理其托管的客户的 connection_info。
添加一个配置选项
[workarounds]enable_consoleauth,默认值为 False,操作员可以选择启用它,如果他们希望运行旧版 consoleauth 服务以回退,因为他们为控制台授权配置了较长的 TTL,并且不希望在数据库后端可用时使现有的控制台失效。更新文档,以反映新的所需部署布局,即控制台代理必须为每个单元运行,而不是全局部署。
修复 bug 1425640
备选方案¶
继续使用 memcached 作为后端将使连接信息行为不可预测,因为对象可能会被驱逐。此外,为了解决问题 1425640 和 1455252,必须进行扫描以列出可用的端口,这在使用 memcached 时很困难,除非添加特定代码来维护存储键的列表。
数据模型影响¶
需要定义一个新的 ConsoleAuthToken 模型,具有属性
instance:引用控制台的实例
host:用于处理主机名的字符串字段
port:用于处理服务编号的整数字段
token_hash:用于处理令牌或 null 的字符串字段
access_url:用于处理访问或 null 的字符串字段
options:用于处理特定信息(例如 usetls、internal_access_path、mode…)的字典字段
expires:指示令牌过期时间的日期时间或 null
数据库模式
CREATE TABLE console_connection (
instance_uuid CHAR(36) NOT NULL,
host VARCHAR(255) NOT NULL,
port INT NOT NULL,
token_hash CHAR(40),
access_url VARCHAR(255),
options TEXT,
expires DATETIME,
PRIMARY KEY (instance_uuid, host, port),
INDEX (token, instance_uuid),
FOREIGN KEY (instance_uuid)
REFERENCES instances(uuid)
ON DELETE CASCADE
);
注意
从 memcached 存储的序列化字典连接信息升级到数据库时,预计不会进行任何迁移,在升级期间,已经连接到控制台的客户端将保持其连接,直到代理重新启动。在此步骤中,我们预计 consoleauth 服务也将重新启动。
REST API 影响¶
无
安全影响¶
从令牌的角度来看,我们可以期望更好的安全性,因为当前令牌存储在 memcached 中,memcached 不提供任何安全层。现在只有令牌的哈希值才会存储在数据库中,并且安全策略也将得到增强,与存储在数据库中的其他关键组件相同。
通知影响¶
无
其他最终用户影响¶
当 proxyclient 重新启动时,用户将从我们的控制台断开连接,但如果尚未过期,应该使用相同的令牌重新连接到它。
性能影响¶
数据库负载将增加,但我们可以预期 DBA 的影响最小。
其他部署者影响¶
必须先重新启动 consoleauth 服务,然后再重新启动代理服务。当代理重新启动时,客户端将从控制台断开连接。consoleauth 将继续作为后端工作,直到一个弃用版本,操作员鼓励切换到数据库后端(参见选项:console_tokens_backend)。
如果部署者选择使用数据库来存储控制台连接信息,则不需要 consoleauth 服务。
开发人员影响¶
无
升级影响¶
新的控制台令牌授权将存储在数据库中,但已经存在的 consoleauth 服务令牌授权将继续工作,直到它们的 TTLs 到期,如果操作员在升级之前设置了 [workarounds]enable_consoleauth = True(默认值为 False)。一旦所有旧的 consoleauth 服务令牌授权都已过期,应该禁用该标志,并且不再需要运行 consoleauth 服务。
实现¶
负责人¶
- 主要负责人
melwitt
- 其他贡献者
sahid-ferdjaoui
工作项¶
将代码转换为使用对象框架
更新 consoleauth 以利用数据库来处理令牌
修复 bug 1425640
依赖项¶
无
测试¶
当前代码已经通过功能和单元测试进行了测试,由于我们没有提供任何功能,因此可以认为该代码将通过这些测试得到很好的覆盖。
新版本将在 gate 中进行测试。
文档影响¶
将更新单元部署布局文档,以反映控制台代理必须为每个单元运行而不是全局部署的新要求。
参考资料¶
无
历史¶
发布名称 |
描述 |
|---|---|
Liberty |
引入 |
Newton |
重新提出 |
Pike |
重新提出 |
Queens |
重新提出 |
Rocky |
重新提出 |