Google Cloud 连接¶
Google Cloud 连接类型启用 Google Cloud 集成。
验证 Google Cloud¶
使用 Airflow 连接 Google Cloud 有三种方式
使用 Application Default Credentials(应用默认凭证),
使用 服务账户,通过指定 JSON 格式的密钥文件。密钥可以以以下三种方式提供:
Keyfile Path(密钥文件路径)、Keyfile JSON(密钥文件内容)或在 Secret Manager 中的密钥(Keyfile secret name)。一次只能使用其中一种方式来定义密钥。如果需要管理多个密钥,请配置多个连接。使用 凭证配置文件,通过指定有效凭证配置文件的路径或内容。凭证配置文件通常包含非敏感的元数据,用于指示
google-auth库如何检索外部主体令牌并将其交换为服务账户访问令牌。警告
可能需要额外的权限
使用来自 Secret Manager 的密钥的连接需要 Application Default Credentials(ADC)拥有访问密钥负载的权限。
注意
存储连接的替代方式
除了仅在 Secret Manager 中存储密钥,还可以选择存储整个连接。更多细节请参阅 Google Secret Manager 后端。
默认连接 ID¶
所有与 Google Cloud 相关的钩子和算子默认使用 google_cloud_default。
关于 Application Default Credentials 的说明¶
当在 Google Compute Engine 上运行 Airflow 时,ADC 会由 GCE 元数据服务器推断;在 GKE 上运行时,则由 GKE 元数据服务器推断,这允许将 Kubernetes Service Account 映射到 GCP 服务账户 Workload Identity。这在管理单个 GKE 集群上多个拥有不同 IAM 足迹的 Airflow 实例时非常有用。只需为工作节点 / Web 服务器部署分配 KSA,Workload Identity 即会将其映射到不同的 GCP 服务账户(而不是共享集群级别的 GCE 服务账户)。从安全角度来看,这种方式无需在磁盘或 Airflow 数据库中存储 Google 服务账户密钥,从而避免了长期凭证密钥泄露的风险。
从 Airflow 的角度来看,只需在连接中指定空 URI,即可使用 Application Default Credentials。
例如
export AIRFLOW_CONN_GOOGLE_CLOUD_DEFAULT='google-cloud-platform://'
配置连接¶
- 项目 ID(可选)
要连接的 Google Cloud 项目 ID。算子会默认使用此项目 ID,通常可以在算子级别覆盖。
- 密钥文件路径
磁盘上 服务账户 密钥文件(JSON 格式)的路径。
如果使用应用默认凭证,则无需填写。
- 密钥文件 JSON
磁盘上 服务账户 密钥文件(JSON 格式)的内容。
如果使用应用默认凭证,则无需填写。
- 凭证配置文件
凭证配置文件的 JSON 内容,或文件系统中凭证配置文件的路径。
如果使用应用默认凭证,则无需填写。
- 保存密钥文件 JSON 的密钥名称
Secret Manager 中包含 服务账户 密钥的密钥名称。
如果使用应用默认凭证,则无需填写。
- 作用域(逗号分隔)
用于认证的逗号分隔的 Google Cloud 作用域 列表。
- 重试次数
整数,表示使用随机指数退避的重试次数。如果所有重试均失败,
googleapiclient.errors.HttpError将代表最后一次请求。若为零(默认),则仅尝试一次。- 模拟链
可选的服务账户,用于使用短期凭证进行模拟,或一系列需要依次获取访问令牌的账户链。链中的最后一个账户将在所有使用此连接的请求中被模拟。如果以字符串形式提供,则该账户必须授予发起账户 “Service Account Token Creator” IAM 角色。如果以逗号分隔的列表提供,则列表中的每个身份必须向其前一个身份授予 “Service Account Token Creator” IAM 角色,列表中的首个账户则向发起账户授予该角色。
在环境变量中指定连接时,应使用 URI 语法,并满足以下要求:
scheme 部分应为
google-cloud-platform(注意:包含连字符)authority(用户名、密码、主机、端口),path 被忽略
query 参数包含此类连接的特定信息。接受以下键:
project– 项目 IDkey_path– 密钥文件路径keyfile_dict– 密钥文件 JSONkey_secret_name– 保存密钥文件 JSON 的密钥名称key_secret_project_id– 保存密钥文件 JSON 的项目 IDscope– 作用域num_retries– 重试次数
请注意,URI 的所有组件都应进行 URL 编码。
例如,使用以下 URI 格式:
export AIRFLOW_CONN_GOOGLE_CLOUD_DEFAULT='google-cloud-platform://?key_path=%2Fkeys%2Fkey.json&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform&project=airflow&num_retries=5'
并使用 JSON 格式:
export AIRFLOW_CONN_GOOGLE_CLOUD_DEFAULT='{"conn_type": "google_cloud_platform", "extra": {"key_path": "/keys/key.json", "scope": "https://www.googleapis.com/auth/cloud-platform", "project": "airflow", "num_retries": 5}}'
直接模拟服务账户¶
Google 算子支持通过 impersonation_chain 参数(在同时与其他云提供商服务通信的算子中为 google_impersonation_chain)直接模拟服务账户。模拟链也可以直接在 Google Cloud 连接中配置(如上所述),但传递给算子的 impersonation_chain 参数的优先级更高。
例如
import os
from airflow.providers.google.cloud.operators.bigquery import (
BigQueryCreateEmptyDatasetOperator,
)
IMPERSONATION_CHAIN = "impersonated_account@your_project_id.iam.gserviceaccount.com"
create_dataset = BigQueryCreateEmptyDatasetOperator(
task_id="create-dataset",
gcp_conn_id="google_cloud_default",
dataset_id="test_dataset",
location="southamerica-east1",
impersonation_chain=IMPERSONATION_CHAIN,
)
为了使本示例工作,impersonated_account 必须向在 google_cloud_default 连接中指定的服务账户授予 “Service Account Token Creator” IAM 角色。这将允许生成 impersonated_account 的访问令牌,从而能够以其权限代表其操作。impersonated_account 本身甚至不需要生成密钥。
对于同时连接多个 Google 服务的算子,所有钩子均使用相同的 impersonation_chain 值(如适用)。您也可以模拟来自发起账户所在项目之外的账户。在这种情况下,模拟账户的项目 ID 将作为算子逻辑中的默认项目 ID,除非您在连接配置或算子参数中显式指定了项目 ID。
模拟链也可以层叠使用:如果连接中指定的服务账户在账户 A 上拥有 “Service Account Token Creator” 角色,而账户 A 在账户 B 上也拥有该角色,则我们可以模拟账户 B。
例如,使用下面的 terraform 配置……
terraform {
required_version = "> 0.11.14"
}
provider "google" {
}
variable "project_id" {
type = "string"
}
resource "google_service_account" "sa_1" {
account_id = "impersonation-chain-1"
project = "${var.project_id}"
}
resource "google_service_account" "sa_2" {
account_id = "impersonation-chain-2"
project = "${var.project_id}"
}
resource "google_service_account" "sa_3" {
account_id = "impersonation-chain-3"
project = "${var.project_id}"
}
resource "google_service_account" "sa_4" {
account_id = "impersonation-chain-4"
project = "${var.project_id}"
}
resource "google_service_account_iam_member" "sa_4_member" {
service_account_id = "${google_service_account.sa_4.name}"
role = "roles/iam.serviceAccountTokenCreator"
member = "serviceAccount:${google_service_account.sa_3.email}"
}
resource "google_service_account_iam_member" "sa_3_member" {
service_account_id = "${google_service_account.sa_3.name}"
role = "roles/iam.serviceAccountTokenCreator"
member = "serviceAccount:${google_service_account.sa_2.email}"
}
resource "google_service_account_iam_member" "sa_2_member" {
service_account_id = "${google_service_account.sa_2.name}"
role = "roles/iam.serviceAccountTokenCreator"
member = "serviceAccount:${google_service_account.sa_1.email}"
}
……我们应在 Airflow 连接中使用 impersonation-chain-1 账户的密钥,并为 impersonation_chain 参数提供以下值……
PROJECT_ID = os.environ.get("TF_VAR_project_id", "your_project_id")
IMPERSONATION_CHAIN = [
f"impersonation-chain-2@{PROJECT_ID}.iam.gserviceaccount.com",
f"impersonation-chain-3@{PROJECT_ID}.iam.gserviceaccount.com",
f"impersonation-chain-4@{PROJECT_ID}.iam.gserviceaccount.com",
]
……随后请求将使用 impersonation-chain-4 账户的权限执行。
域范围委派¶
部分 Google 算子、钩子和传感器支持 域范围委派,除了直接模拟服务账户之外。委派允许用户或服务账户授予另一服务账户代表其操作的权限。这意味着委派方仍可访问和管理自己的资源,而被委派的服务账户也可以访问和管理这些资源。
例如
PROJECT_ID = os.environ.get("TF_VAR_project_id", "your_project_id")
SPREADSHEET = {
"properties": {"title": "Test1"},
"sheets": [{"properties": {"title": "Sheet1"}}],
}
from airflow.providers.google.suite.operators.sheets import (
GoogleSheetsCreateSpreadsheetOperator,
)
create_spreadsheet_operator = GoogleSheetsCreateSpreadsheetOperator(
task_id="create-spreadsheet",
gcp_conn_id="google_cloud_default",
spreadsheet=SPREADSHEET,
impersonation_chain=f"projects/-/serviceAccounts/SA@{PROJECT_ID}.iam.gserviceaccount.com",
)
请注意,由于域范围委派目前仅在大多数 Google 算子和钩子中得到支持,其使用应仅限于 Google Workspace(gsuite)以及营销平台的算子和钩子,或通过 GoogleDiscoveryAPI 钩子访问这些服务。以下情形已不推荐使用:
所有 Google Cloud 算子和钩子。
Firebase 钩子。
所有涉及不同提供商的 Google Cloud 传输算子,例如:
airflow.providers.amazon.aws.transfers.gcs_to_s3.GCSToS3Operator。