为您的环境配置 Secret Manager

Cloud Composer 1 |Cloud Composer 2 |Cloud Composer 3

本页面介绍如何使用 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

控制台

Enable the Secret Manager API.

Enable the 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:要获取的 Secret 名称前缀 变量。默认值为 airflow-variables
    • gcp_key_path:Google Cloud 凭据 JSON 文件的路径 (如未提供,则使用默认服务账号)。
    • gcp_keyfile_dict:Google Cloud 凭据 JSON 字典。相互影响 gcp_key_path 独有。
    • sep:用于连接 connections_prefixconn_id 的分隔符。默认值为 -
    • project_id:存储 Secret 的 Google Cloud 项目 ID。

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

在 Secret Manager 中添加连接和变量

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

变量

  • 必须使用 [variables_prefix][sep][variable_name] 格式。
  • [variables_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 表示法。例如 postgresql://login:secret@examplehost:9000

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

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

将 Secret Manager 与 Cloud Composer 搭配使用

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

使用 Jinja 模板读取变量

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

对于 airflow-variables-secret_filename 密钥:

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

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

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

例如,对于 airflow-variables-secret_filename 密钥:

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()

后续步骤