来自环境的配置选项

https://blueprints.launchpad.net/oslo.config/+spec/config-from-environment

在服务管理中,尤其是在容器编排中,使用由控制环境设置的环境变量来管理配置设置是很常见且方便的。这允许被管理的服务避免额外的文件和其他工件,从而实现服务不可变性,进而实现直接的弹性伸缩。本规范建议使用 驱动程序 功能,该功能由 oslo.config 提供,以自动支持使用标准且可预测的名称从环境变量覆盖或设置配置。

问题描述

一种常见的将特定于实例的设置传递给容器的方式是使用 shell 环境变量。例如,在 docker 中

docker run -t -p 127.0.0.1:8081:80 \
  -e "DB_SYNC=True" \
  -e "AUTH_STRATEGY=noauth2" \
  myservice

或者在 Kubernetes 部署(片段)中

spec:
  containers:
    - name: myservice
      image: myservice
      env:
        - name: DB_SYNC
          value: "True"
        - name: AUTH_STRATEGY
          value: noauth2
      ports:
      - containerPort: 80

在 OpenStack 中,这些设置通常由 oslo.config 读取的配置文件管理到 ConfigOpts 类的实例中。目前,没有统一的方法可以使用环境变量来设置这些配置,这意味着在许多情况下,如果部署者希望在容器中运行 OpenStack 服务,他们必须为该容器提供配置文件,或者提供某种方式让服务在运行时收集配置。

oslo.config 开发的 驱动程序 功能提供了一种用于运行时配置的模型,但并未专门解决使用简单环境变量的情况。

提议的变更

本规范建议使用驱动程序模型创建一个 ConfigurationSource,用于 oslo.config,该模型会查找正在运行的环境中与已注册配置设置的预期名称匹配的变量。该源将默认可用,理想情况下,在命令行覆盖之后,但在任何文件或其他源之前,排在堆栈中的第二位。如果由于文件和命令行处理中的相互依赖性而无法实现,则排在堆栈中的第一位是次优选择。

ConfigurationSource 将将配置选项名称转换为候选变量名称。如果这些变量在本地环境中设置(在 Python 中是 os.environ 的成员),则将返回这些值。如果未设置,则将继续处理其他源。

这个提议面临两个主要挑战。以令人满意的方式解决它们是编写本规范的原因。它们是

  1. 确定一种令人满意的方案,将配置选项名称转换为环境变量名称,该方案既对人类可预测,又极不可能与可能以其他方式使用的变量名称冲突。一个草案建议如下

    1. 在每个变量前加上 OS_

    2. 后跟组:DEFAULT

    3. 用双下划线 __ 分隔名称(允许组中的下划线)

    4. 后跟名称,结果如下:OS_PLACEMENT_DATABASE__CONNECTION

    在某些情况下,这将导致相当长的名称,但任何满足这两个要求的解决方案都可能出现这种情况。请注意,这种格式可以在两个方向上转换:从选项组和名称到环境变量名称,反之亦然。

  2. ConfigOpts 中的单个选项具有类型。另一方面,环境变量是字符串。我们需要建立一种将基于字符串的非字符串类型表示强制转换为所需类型的方法(keystonemiddleware 有一些代码可以做到这一点),或者我们可能最初只支持 StrOpt

这是一个人为的例子,描述了两个具有相似名称的选项,它演示了组处理的重要性。配置项如下

[placement]
database_connection = foo

[placement_database]
connection = bar

将产生两个环境变量 OS_PLACEMENT__DATABASE_CONNECTIONOS_PLACEMENT_DATABASE__CONNECTION

备选方案

这不需要在 oslo.config 中完成。各个服务可以管理自己的环境检查,但这与 oslo 原则和 OpenStack 的一致性目标不太一致。

在某些情况下,Opt 可以设置一个默认值,该值使用 default=os.environ.get('SOMETHING') 从环境中读取,但这有一个关键的缺点:只有当选项尚未在配置中设置时,才会使用环境变量。理想情况下,环境变量应该覆盖配置。

另一种方法是在 Opt 中添加另一个参数,名为 envvar。如果设置,该值将用于覆盖自动生成的环境变量名称(如上所述)。这被认为是不希望的,因为它可能导致已发布的变量命名不一致。

Impact on Existing APIs

见上文。

安全影响

如果存在碰巧匹配此处描述的命名方案的预先存在的环境变量,则服务行为可能会发生微小变化。

性能影响

预计不会有显著的性能影响。查询环境很快,并且查询是在需要时完成的,而不是针对所有可能的配置值。

Configuration Impact

在注册选项时,将不会添加新的选项。对基于环境变量的覆盖的支持将是自动的。

开发人员影响

开发人员将拥有额外的自定义选项。

Testing Impact

需要额外的单元测试来涵盖添加的功能。

实现

负责人

主要负责人

cdent

其他贡献者

志愿者?

里程碑

..TODO(cdent): 弄清楚

工作项

  • 实现新的 ConfigurationSource 驱动程序。

  • 将其集成为默认驱动程序。

  • 更新文档。

  • 更新示例配置生成器以包含变量名称。

  • 更新文档生成器以包含变量名称。

孵化

N/A

文档影响

需要更新文档,以指示可以使用环境变量覆盖每个选项,并描述将生成变量名称的方式。

依赖项

此实现依赖于新兴的 驱动程序 功能,该功能位于 oslo.config 中。

参考资料

注意

本作品采用知识共享署名 3.0 非移植许可协议授权。 http://creativecommons.org/licenses/by/3.0/legalcode