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.
gcloud
Enable the Secret Manager API:
gcloud services enable secretmanager.googleapis.com
配置访问权限控制
您必须配置访问权限控制,以便 Airflow 可以访问 Secret Manager 中存储的 Secret。
为此,访问 Secret 的服务账号必须拥有具有 secretmanager.versions.access
权限的角色。例如,Secret Manager Secret Accessor 角色包含此权限。
您可以在密文、项目、文件夹或组织级层授予此角色。
使用以下任一选项:
替换 Airflow 用于访问 Secret Manager 的服务账号。
- 向服务账号授予此角色。
- 设置
backend_kwargs
Airflow 配置选项的gcp_key_path
参数,使其指向包含服务账号凭据的 JSON 文件。
启用 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 后端
替换以下 Airflow 配置选项:
部分 键 值 secrets
backend
airflow.providers.google.cloud.secrets.secret_manager.CloudSecretManagerBackend
通过替换以下 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_prefix
和conn_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()