OpenStack 配置文件验证

https://blueprints.launchpad.net/congress/+spec/configuration-files-validation

Congress 可以被云运营商用来,借助用 Datalog 编写的业务规则,形式化配置文件的选项之间的约束,并自动验证其部署的合规性。它旨在补充配置管理系统,后者应该只创建有效的配置文件,以及集成测试,例如 RefStack。

问题描述

每个 OpenStack 服务在每个节点上都由一组描述各种配置选项值的配置文件参数化。在这个提案中,我们只考虑由 oslo-config 库管理的配置文件。配置选项不是独立的

  • 每个选项值都受到约束,但这些约束可能超出了 oslo-config 类型系统的表达能力。

  • 对于给定节点上的给定服务,不同选项之间可能存在约束。

  • 在给定节点上,属于不同服务的各种选项之间可能存在约束和不兼容性。例如,当给定服务中的功能依赖于另一个服务中的另一个功能的可用性时。

  • 在节点之间,存在针对给定服务的约束,或者服务之间的约束。

约束可以由不同的参与者定义

  • 服务开发者了解他们定义的选项上的约束,并且通常在与选项关联的描述字段中的源代码中非正式地记录它们。

  • 云集成商在开发部署代码时会发现额外的约束。大多数时候,这些选项只是在脚本的源代码中隐式定义的。

  • 管理员可能希望强制执行额外的约束,以反映运营环境的约束。

  • 对于拥有多个 OpenStack 实例的公司,可以使用规则来确保实例与其全局工程规则的合规性。

  • 虽然 OpenStack 提供了隐藏实现细节的抽象,但某些后端或某些后端组合可能会对可供最终用户使用的内容施加约束。当管理员发现一些后端限制时,在找到更永久的解决方案之前,添加反映这些限制的 congress 规则可能很有用。

Datalog 可以用作描述这些约束的形式语言,并且 Congress 可以用来强制执行这些约束,如果配置文件可用于处理。虽然 Congress 通常用于来自正在运行的实例的更动态的数据,但没有什么可以阻止使用更静态的数据源。

提议的变更

该扩展添加了一个新的代理,部署在 OpenStack 节点上,它收集其自身配置中定义的配置文件。该代理通过消息总线与包含在 congress 分析器中的数据源驱动程序进行通信。该代理配置了自己的配置文件,描述了它传输的文件(示例配置文件在“其他部署者影响”部分中给出)。

代理负责传递选项值,还包括它们的元数据:在组中的布局、类型、标志,例如弃用、秘密状态等。元数据在模板中描述,实际上是命名空间的集合。命名空间包含元数据的实际定义。为了避免版本问题,元数据必须直接从服务获取。

为了限制驱动程序和代理之间的流量,模板文件会被哈希。代理首先用哈希回复查询。如果哈希未知,驱动程序才会请求内容。相同的过程用于命名空间。

代理在选项文件上执行的唯一处理是删除秘密选项的值。

数据源驱动程序负责使用代理提供的信息填充扩展数据库

  • 选项定义从模板和命名空间中提取,并转换为新的 Datalog 表。

  • 选项值由 oslo-config 库解析,并与来源(文件和节点)的标识一起存储。

Datalog 模型定义了几个表

  • hosts

  • files

  • templates

  • namespaces

  • option values

选项的定义在三个表之间拆分

  • option 表定义了选项 id 与构成键的字段之间的映射:选项的名称、命名空间和组。

  • option_info 表定义了选项的类型和标志。它使用 option 表中定义的 id 来唯一标识选项。

  • 根据选项的类型,特定于给定类型的属性在专用表中定义。再次使用选项 id 作为键来引用 option 表。

关于扩展数据库中配置元数据的唯一性,驱动程序必须确保 id 是确定性的。由相同的名称、相同的组名和相同的命名空间名称标识的选项应始终被赋予相同的唯一 id。使用 MD5 哈希函数(没有加密要求)保证了唯一性和确定性。

备选方案

安装程序通常会为或多或少的扩展选项集生成正确的配置文件集,但对于这些文件的实时维护提供很少的帮助。他们也可能限制了配置空间,超出了必要的范围。

建议的更改应被视为一个正在进行中的工作。它没有完全解决约束的位置和管理问题。大多数约束由服务开发者了解,应该在服务的源代码中以选项定义的专用元数据字段中维护。

使用外部代理来推送服务配置不是唯一的解决方案。可以修改 oslo-config 库,以将服务读取的配置推送到数据源驱动程序。可以通过在 oslo-config 中使用钩子来完成。这将需要对服务进行额外的配置,以识别端点。

策略

我们希望将策略违规聚合到几个表中,按违规程度(错误、警告、信息)进行分区。

示例

X:neutron-server 主机

Y:ovs-agt 主机

Z:lb-agt 主机

warn('Multinode OVS and linuxbridge use incompatible UDP ports',
'vxlan_conflicting_ovs_lb_udp_ports') :-
    vxlan_conflicting_ovs_lb_udp_ports()

vxlan_conflicting_ovs_lb_udp_ports(Y, Z) :-
    value(X, 'neutron.conf', 'DEFAULT', 'core_plugin', 'ml2'),
    value(X, 'ml2_conf.ini', 'ml2', 'type_drivers', 'vxlan'),
    value(X, 'ml2_conf.ini', 'ml2', 'mechanism_drivers', 'openvswitch'),
    value(X, 'ml2_conf.ini', 'ml2', 'mechanism_drivers', 'linuxbridge'),
    value(Y, 'openvswitch_agent.ini', 'agent', 'tunnel_types', 'vxlan'),
    not value(Y, 'openvswitch_agent.ini', 'agent', 'vxlan_udp_port', 8472),
    value(Z, 'linuxbridge_agent.ini', 'vxlan', 'enable_vxlan', 'True')

我们希望“value”表对大多数潜在贡献者来说是易于理解的,并且有意义,足以避免可预测的连接。

当前,“value”表是从描述配置文件及其元数据的扩展表派生的。虽然它是故意定义的,但将其视为扩展谓词可能是有用的。以下是我们派生它的方式

value(hostname, file, group, name, value) :-
    config:option(id=option_id, group=group, name=name),
    config:file(id=file_id, host_id=host_id, name=file),
    config:host(id=host_id, name=hostname),
    config:value(option_id=option_id, file_id=file_id, val=value)

策略动作

无。

数据源

数据源是使用 Oslo.config 库进行配置的 OpenStack 项目的不同配置文件。

数据模型影响

REST API 影响

安全影响

配置文件包含敏感凭据。这些凭据绝不能传输到 Congress 引擎。代理可以访问类型,并且必须过滤掉凭据。任何标记为秘密的选项的值在引擎内都不可用。

通知影响

其他最终用户影响

除了数据源和策略的常规管理之外,没有其他内容。最终,我们希望用来自服务源代码并由服务源代码维护的规则来填充引擎。

性能影响

由于此数据源提供的静态值,性能影响应该有限。

主要影响是用于在代理和 Congress 服务器之间交换配置文件的消息总线上的流量。服务器可能会限制此流量。如果性能仍然是一个问题,另一个解决方案是限制总线的使用到公告,并在服务器上使用 REST 端点来记录新的配置文件。

我们赋予驱动程序控制数据检索方式。我们希望防止重复发送文件和模板,并防止驱动程序过载。当驱动程序被激活时,它会定期通过通信总线通知代理,请求它们的数据描述。代理发送其设置为提供的文件的描述。该描述包含命名空间、模板和配置文件的哈希值。然后,驱动程序请求哈希值未被识别的资源。

我们使用与 DseNode 关联的数据源的 RPC 服务器。

其他部署者影响

我们添加了一个专用的组和选项来配置代理和要管理的文件。

validator.host

一个字符串选项,充当管理员有意义的节点 id。

validator.version

一个字符串选项,引入了版本概念以及它在这个节点上会是什么。它可用于区分在云实例迁移期间同时存在于云实例中的不同配置文件的处理。此信息将来可能会以不同的方式提供,以在服务级别定义。

validator.services

一个字典选项,描述在此节点上激活的 OpenStack 服务。值也是字典。键是配置文件路径,值是关联模板的路径。例如

congress: { /etc/congress/congress.conf:
/opt/stack/congress/etc/congress-config-generator.conf }

示例配置

[DEFAULT]
transport_url = rabbit://..@control:5672/

[validator]
services = nova : { /etc/nova.conf:
/opt/stack/nova/etc/nova/nova-config-generator.conf:
version = ocata
host = node_A

开发者影响

讨论将影响在 OpenStack 上工作的其他开发人员的事情,例如

  • 如果蓝图提出对驱动程序 API 的更改,则需要讨论其他 hypervisor 将如何实现该功能。

实现

负责人

主要负责人

  • Valentin Matton

  • Pierre Crégut

工作项

  • 收集配置文件的代理

  • 与代理交互的数据源

  • 集成到 devstack

依赖项

我们将依赖于 oslo-config-generator 配置文件,它可以用来描述 OS 服务的配置文件。https://github.com/openstack/oslo-specs/blob/master/specs/juno/oslo-config-generator.rst

我们广泛依赖于 oslo-config 库。

测试

我们建议在具有 2 个节点的设置中使用 tempest 测试。其中一个节点托管 congress-server,第二个节点托管一个代理。将测试通信:元数据和文件的发送。

文档影响

此功能引入了一个代理组件,需要单独配置。它还定义了新的数据源。

参考资料