为您的环境配置 Secret Manager

Cloud Composer 1 | Cloud Composer 2

本页面介绍如何使用 Secret Manager 安全存储 Airflow 连接和密文。

准备工作

  • 如需使用 Secret Manager,您的 Cloud Composer 环境必须使用 Airflow 1.10.10 或更高版本,以及 Python 3.6 或更高版本。
  • 不支持 Python 2。

为您的环境配置 Secret Manager

本部分介绍如何配置 Secret Manager,以便在 Cloud Composer 环境中使用 Secret。

启用 Secret Manager API

控制台

启用 Secret Manager API。

启用 API

gcloud

Enable the Secret Manager API:

gcloud services enable secretmanager.googleapis.com

配置访问权限控制

您必须配置访问权限控制,以便 Airflow 可以访问 Secret Manager 中存储的 Secret。

为此,访问 Secret 的服务账号必须拥有具有 secretmanager.versions.access 权限的角色。例如,Secret Manager Secret Accessor 角色包含此权限。

您可以在密文、项目、文件夹或组织级层授予此角色。

使用以下任一选项:

启用 DAG 序列化

通常情况下,您应仅在运算符的 execute() 方法中或与 Jinja 模板搭配使用时使用 Secret Manager 后端。例如,您可以使用 var.value.example_var 来检索变量。

Airflow Web 服务器在具有有限权限的其他服务账号下运行,因此它无法访问 Secret Manager 中的密文。如果您的 DAG 代码在 DAG 处理期间(而不仅是从任务)访问 Secret,并且无法对其进行调整以从 execute() 方法访问 Secret,那么请启用 DAG 序列化。启用之后,Airflow Web 服务器接受经过处理的 DAG,并且不需要访问 Secret。

启用并配置 Secret Manager 后端

  1. 替换以下 Airflow 配置选项:

    部分
    secrets backend airflow.providers.google.cloud.secrets.secret_manager.CloudSecretManagerBackend
  2. 通过替换以下 Airflow 配置选项来添加可选设置:

    部分
    secrets backend_kwargs 请参阅以下说明。

    backend_kwargs 值是 backend_kwargs 对象的 JSON 表示法,其中包含以下字段:

    • connections_prefix:指定要读取以获取连接的密文名称的前缀。默认值为 airflow-connections
    • variables_prefix:指定要读取以获取变量的密文名称的前缀。默认值为 airflow-variables
    • gcp_key_path:Google Cloud 凭据 JSON 文件的路径(如果未提供,则使用默认服务账号)。
    • gcp_keyfile_dict:Google Cloud 凭据 JSON 字典。它与 gcp_key_path 是互斥的。
    • sep:用于连接 connections_prefixconn_id 的分隔符。默认值为 -
    • project_id:存储密文的 Google Cloud 项目 ID。

    例如,backend_kwargs 的值可以是 {"project_id": "<project id>", "connections_prefix":"example-connections", "variables_prefix":"example-variables", "sep":"-"}

在 Secret Manager 中添加连接和变量

按照创建 Secret 和版本中所述的步骤创建 Secret。

变量

  • 必须使用 [variable_prefix][sep][variable_name] 格式。
  • [variable_prefix] 的默认值为 airflow-variables
  • 默认分隔符 [sep]-

例如,如果变量名称为 example-var,则 Secret 名称为 airflow-variables-example-var

连接名称

  • 必须使用 [connection_prefix][sep][connection_name] 格式。
  • [connection_prefix] 的默认值为 airflow-connections
  • 默认分隔符 [sep]-

例如,如果连接名称为 exampleConnection,则 Secret 名称为 airflow-connections-exampleConnection

连接值

  • 必须使用 URI 表示法。例如 mysql://login:password@examplehost:9000

  • URI 必须进行网址编码(百分号编码)。例如,包含空格符号的密码必须按照以下格式进行网址编码:mysql://login:secret%20password@examplehost:9000

Airflow 提供一种生成连接 URI 的便捷方法Airflow 文档中提供了有关如何使用 JSON extras 对复杂网址进行编码的示例。

将 Secret Manager 与 Cloud Composer 搭配使用

在提取变量和连接时,Cloud Composer 会首先检查 Secret Manager。如果未找到请求的变量或连接,Cloud Composer 会检查环境变量和 Airflow 数据库。

使用 Jinja 模板读取变量

您可以使用 Secret Manager 为模板化运算符字段(在执行时解析)读取具有 Jinja 模板的变量。

对于 airflow-variables-secret_filename Secret:

file_name = '{{var.value.secret_filename}}'

使用自定义运算符和回调读取变量

您还可以用 Secret Manager 来读取自定义运算符中的变量或从运算符中读取回调方法。从 DAG 中读取变量会对性能产生负面影响,因此如果要在 DAG 中使用变量,请使用 Jinja 模板。

例如,对于 airflow-variables-secret_filename Secret:

from airflow.models.variable import Variable
file_name = Variable.get('secret_filename')

读取连接

除非您要编写自定义运算符,否则几乎不需要直接访问连接。大多数钩子会将连接名称作为其实例化参数,并且在任务执行时自动从密文后端检索连接。

在编写您自己的钩子时,直接读取连接可能会很有用。

例如,对于 airflow-connections-exampleConnection 连接:

from airflow.hooks.base_hook import BaseHook
exampleConnection = BaseHook.get_connection('exampleConnection')

BaseHook.get_connection 会返回一个 Connection 对象。可以获取连接的 URI 字符串表示形式,如下所示:

exampleConnectionUri = BaseHook.get_connection('exampleConnection').get_uri()

后续步骤