rootwrap 守护模式¶
https://blueprints.launchpad.net/neutron/+spec/rootwrap-daemon-mode
Neutron 是一个严重依赖在网络节点上执行需要 Linux 系统 root 权限的操作的项目。目前,这是通过 oslo.rootwrap 实现的,需要使用 sudo 运行。sudo 和 rootwrap 都会产生显著的性能开销。本蓝图涵盖了通过使用 rootwrap 操作的新模式,称为“守护模式”,来减轻 sudo 和 rootwrap 引入的部分开销。
问题描述¶
正如 Miguel Angel Ajo 在 [2] 中所述
在拥有 1 个公用网络、192 个私有网络、192 个路由器和 192 个纳米 VM 的数据库上,使用 OVS 插件
网络节点设置时间 (rootwrap): 24 分钟
网络节点设置时间 (sudo): 10 分钟
如您所见,rootwrap 与纯粹的 sudo 使用相比,存在巨大的开销,并且大部分开销是由于每个请求所需的漫长的 Python 解释器启动时间造成的。开销的详细信息在 [1] 中介绍。
提议的变更¶
本蓝图建议采用 oslo.rootwrap 守护模式,该模式允许将 rootwrap 作为守护进程运行。守护进程的工作方式与普通的 rootwrap 相同,但将通过经过身份验证的 UNIX 域套接字而不是命令行接受要运行的命令,并在后台持续运行。rootwrap 守护进程的概述在 [3] 中。
应添加两个新的配置选项
rootwrap_mode= daemon | process 将使代理使用守护进程或通常的 rootwrap 进程;默认情况下将启用守护进程。如果守护模式的性能符合我们的预期,则此选项将来可能会被弃用。rootwrap_config将提供用于运行守护进程的 rootwrap 配置文件路径,默认情况下,它将指向 neutron 提供程序的 rootwrap 文件。
由于 root_helper 在 Neutron 中传递(与其他项目中使用全局配置相反),因此我们必须将 root_helper 作为某种对象,封装所有必要的信息以使用 root 权限运行命令。这是在第一个补丁 [4] 中完成的。
该补丁引入了两个 root helper 类
ProcessHelper(基类) 只是按原样运行命令,不带任何包装器;WrappedProcessHelper使用包装器运行命令,就像root_helper选项过去那样。
这些类具有两个接口方法
create_process启动一个进程并返回与之关联的 Popen 实例;execute启动一个进程(默认情况下使用create_process),向其提供一些输入并捕获返回码以及 stdout 和 stderr 输出。
请注意,create_process 和 execute 方法在 neutron.agent.linux.utils 模块中仍然存在,但它们只是预处理参数并将它们传递给 root_helper 的适当方法。
第二步 [5] 将是创建这些配置选项并添加另一个 root helper 类 RootwrapDaemonHelper。该类将为具有相同 rootwrap_config 的所有实例使用一个 rootwrap 客户端。它的 execute 方法将只是调用 rootwrap 客户端的 execute 方法,该方法会将请求传递给守护进程。
请注意,我们当前无法使用守护进程启动长期运行的进程,因此 create_process 将使用普通的 rootwrap 启动该进程。此外,对于长期运行的进程,收益可以忽略不计。
数据模型影响¶
无
REST API 影响¶
无
安全影响¶
此更改将启动作为 root 运行的 oslo rootwrap 守护进程,并通过经过良好身份验证(OTP)的 unix 域套接字提供给 neutron。
因此,neutron-rootwrap-daemon 应添加到 sudoers 文件中,并使用与 neutron-rootwrap 相同的设置。
安全性由 oslo-rootwrap 处理,该工具已经经过了充分的验证。
在 [1] 中涵盖了使用客户端+守护进程而不是纯 rootwrap 的所有安全问题。
通知影响¶
无
其他最终用户影响¶
无
性能影响¶
此更改为依赖于调用大量使用 rootwrap 命令的代理程序带来性能提升。当前 rootwrap 守护程序的状态显示,与通常的 sudo rootwrap 调用相比,速度提高了 10 倍以上。代理程序的总速度提升不会那么令人印象深刻,但应该非常明显。rootwrap 守护程序实现包含一个基准测试,该基准测试生成了速度提升结果。
其他部署者影响¶
此更改引入了两个新的配置变量
rootwrap_mode使用daemon作为默认值;rootwrap_config必须指向部署给 Neutron 的rootwrap.conf(默认/etc/neutron/rootwrap.conf)。
请注意,默认情况下 use_rootwrap_daemon 将被关闭,因此要获得速度提升,必须将其打开。启用后,root_helper 配置选项将被忽略,并且 neutron-rootwrap-daemon 将用于运行大多数需要 root 权限的命令。
此更改还引入了新的二进制文件 neutron-rootwrap-daemon,该文件应与 neutron-rootwrap 一起部署,并添加到 sudoers 中。
开发人员影响¶
无
社区影响¶
社区普遍对更快的代理操作感兴趣。
备选方案¶
不使用 rootwrap 的 sudo,以牺牲安全性为代价,或者通过实现特定的 sudo 插件来允许等效的 rootwrap 过滤。这将需要维护针对 openstack 的 C sudo 插件。
将 rootwrap 重写为 C,但这需要代码审计,并且也偏离了 openstack 社区的标准 python。
自动将 rootwrap 转换为 C++,并获得编译版本,这个选项已经被探索过,并且似乎可以通过 shedskin 进行修改 rootwrap 以避免动态类型来实现。顺便说一下,shedskin 是实验性的,并且一些 python 模块没有实现。此外,生成的 C++ 代码不易于人类阅读,可能需要进行安全评估。此解决方案并不能消除 sudo 性能影响,这并非微不足道。
其他解决方案¶
其他解决方案主要与 rootwrap 优化有关,并在 [1] 中介绍(其中一些在 [6] 中介绍)。
这并不是 Neutron 方面除了切换到 rootwrap 守护进程之外可以做的唯一选择(有关详细信息,请参阅 [6])
避免 L3 代理中路由器处理中的不必要的锁定
避免不必要的调用
合并系统调用:Carl Baldwin 探索了这个选项,并证明它对代码库来说非常困难和具有侵入性。
所有这些都可以与 rootwrap 守护进程一起完成,因为每次调用守护进程仍然会产生一些开销。
IPv6 影响¶
无
实现¶
负责人¶
- 主要负责人
twilson (Terry Wilson, otherwiseguy @ freenode)
- 原始贡献者
yorik-sar (Yuriy Taraday, YorikSar @ freenode)
工作项¶
依赖项¶
无
测试¶
Tempest 测试¶
此更改不会更改 API,因此不需要额外的集成测试。如果 tempest 对启用 use_rootwrap_daemon 感到满意,则该功能有效。
功能测试¶
现有的功能测试将在执行代理功能测试时对 rootwrap 客户端进行测试。Rootwrap 也有自己的功能测试,用于 rootwrap 客户端/守护进程组件 [7]。
API 测试¶
不需要 API 测试。
文档影响¶
用户文档¶
由于我们包括两个新的配置设置,因此需要正确记录这些设置。
开发人员文档¶
如果对接口进行了任何更改,开发人员文档可能会更新,以描述如何使用新的接口来执行系统命令。