Google Cloud 连接

Google Cloud 连接类型启用 Google Cloud 集成。

验证 Google Cloud

使用 Airflow 连接 Google Cloud 有三种方式

  1. 使用 Application Default Credentials(应用默认凭证),

  2. 使用 服务账户,通过指定 JSON 格式的密钥文件。密钥可以以以下三种方式提供:Keyfile Path(密钥文件路径)、Keyfile JSON(密钥文件内容)或在 Secret Manager 中的密钥(Keyfile secret name)。一次只能使用其中一种方式来定义密钥。如果需要管理多个密钥,请配置多个连接。

  3. 使用 凭证配置文件,通过指定有效凭证配置文件的路径或内容。凭证配置文件通常包含非敏感的元数据,用于指示 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 – 项目 ID

    • key_path – 密钥文件路径

    • keyfile_dict – 密钥文件 JSON

    • key_secret_name – 保存密钥文件 JSON 的密钥名称

    • key_secret_project_id – 保存密钥文件 JSON 的项目 ID

    • scope – 作用域

    • 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 钩子访问这些服务。以下情形已不推荐使用:

此条目是否有帮助?