部署到生产环境

本指南可帮助您为 Data Manager API 生产部署选择和配置合适的身份验证方法。

选择部署方案

选择与您的应用架构和部署环境相符的身份验证方法:

如需有关 Google Cloud 身份验证的一般指导,请参阅 Google Cloud 身份验证决策树。

Google Cloud 中的工作负载

在 Google Cloud 上运行时,请直接将服务账号附加到计算资源,或配置 Workload Identity Federation for GKE。客户端库使用 ADC 自动检索服务账号的短期有效凭据,而无需凭据文件或环境变量。

Compute Engine

创建虚拟机实例时,请指定服务账号和 Data Manager API 范围,以便实例元数据服务器返回的访问令牌包含所需的授权。

gcloud compute instances create INSTANCE_NAME \
  --service-account="SERVICE_ACCOUNT_EMAIL" \
  --scopes="https://www.googleapis.com/auth/datamanager,https://www.googleapis.com/auth/cloud-platform"

如需更新现有实例的范围或服务账号,请停止该实例,使用 set-service-account 更新配置,然后重启该实例:

gcloud compute instances stop INSTANCE_NAME

gcloud compute instances set-service-account \
  INSTANCE_NAME \
  --service-account="SERVICE_ACCOUNT_EMAIL" \
  --scopes="https://www.googleapis.com/auth/datamanager,https://www.googleapis.com/auth/cloud-platform"

gcloud compute instances start INSTANCE_NAME

Cloud Run

部署服务时指定服务账号:

gcloud run deploy SERVICE_NAME \
  --image="IMAGE_URL" \
  --service-account="SERVICE_ACCOUNT_EMAIL"

Cloud Functions

在部署函数时指定服务账号:

gcloud functions deploy FUNCTION_NAME \
  --service-account="SERVICE_ACCOUNT_EMAIL" \
  --runtime="RUNTIME" \
  --trigger-http

GKE

  1. 在集群上启用 Workload Identity Federation for GKE。
  2. 将 Kubernetes 服务账号 (KSA) 绑定到 Google 服务账号 (GSA):

    # Define the Kubernetes service account member:
    KUBERNETES_MEMBER="serviceAccount:PROJECT_ID.svc.id.goog[KUBERNETES_NAMESPACE/KUBERNETES_SA_NAME]"
    
    # Grant the Workload Identity User role to the Kubernetes service account:
    gcloud iam service-accounts add-iam-policy-binding \
      SERVICE_ACCOUNT_EMAIL \
      --role="roles/iam.workloadIdentityUser" \
      --member="${KUBERNETES_MEMBER}"
    
  3. 使用 Google 服务账号电子邮件地址为 Kubernetes 服务账号添加注解:

    kubectl annotate serviceaccount KUBERNETES_SA_NAME \
      --namespace="KUBERNETES_NAMESPACE" \
      iam.gke.io/gcp-service-account="SERVICE_ACCOUNT_EMAIL"
    
  4. 在 pod 规范中指定 Kubernetes 服务账号:

    apiVersion: v1
    kind: Pod
    metadata:
      name: data-manager-worker
    spec:
      serviceAccountName: KUBERNETES_SA_NAME
      containers:
      - name: worker
        image: IMAGE_URL
    

验证 IAM 和账号访问权限

在部署生产应用之前,请验证您的服务账号是否具有必要的权限:

  1. Google Cloud IAM 权限:在启用了 Data Manager API 的 Google Cloud 项目中,向服务账号授予 Service Usage Consumer 角色 (roles/serviceusage.serviceUsageConsumer)。

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \
      --role="roles/serviceusage.serviceUsageConsumer"
    
  2. 目标账号访问权限:向服务账号授予对目标账号的必要访问权限。如需了解分步说明,请参阅设置账号访问权限。

Google Cloud 外部的工作负载

在本地数据中心或其他云服务提供商中运行代码时,请选择以下身份验证机制之一:

  • 工作负载身份联合(推荐):配置工作负载身份联合,以便您的应用可以交换来自外部身份提供方的凭据,以获取短期有效的 Google Cloud 凭据,而无需管理服务账号密钥。生成凭据配置文件,并使用 GOOGLE_APPLICATION_CREDENTIALS 环境变量将其提供给 ADC。

  • 服务账号密钥(后备):如果工作负载身份联合不可用,请创建服务账号密钥,并使用 GOOGLE_APPLICATION_CREDENTIALS 环境变量将其提供给 ADC。

设置 GOOGLE_APPLICATION_CREDENTIALS

将 GOOGLE_APPLICATION_CREDENTIALS 环境变量设置为工作负载身份联合凭据配置文件或服务账号密钥文件的绝对路径,以便客户端库可以使用 ADC 自动找到您的凭据。

Linux/macOS

在 shell 配置文件或部署脚本中设置环境变量:

export GOOGLE_APPLICATION_CREDENTIALS=\
  "/path/to/credentials.json"

Windows (PowerShell)

在 PowerShell 中设置环境变量:

$env:GOOGLE_APPLICATION_CREDENTIALS = `
  "C:\path\to\credentials.json"

Docker / 容器

将凭据文件装载到容器中,并设置环境变量:

ENV GOOGLE_APPLICATION_CREDENTIALS="/secrets/credentials.json"

或者在运行时传递环境变量:

HOST_CREDS="/host/path/credentials.json"
docker run -e GOOGLE_APPLICATION_CREDENTIALS="/secrets/credentials.json" \
  -v "${HOST_CREDS}:/secrets/credentials.json:ro" \
  IMAGE_NAME

Kubernetes

将凭据装载为 Secret,并在 pod 的环境中引用该 Secret:

apiVersion: v1
kind: Pod
metadata:
  name: data-manager-worker
spec:
  containers:
  - name: worker
    image: IMAGE_URL
    env:
    - name: GOOGLE_APPLICATION_CREDENTIALS
      value: "/etc/secrets/google/credentials.json"
    volumeMounts:
    - name: credentials-volume
      mountPath: "/etc/secrets/google"
      readOnly: true
  volumes:
  - name: credentials-volume
    secret:
      secretName: data-manager-credentials

对 REST 和 curl 请求进行身份验证

如果您的自动化流水线使用 curl 发出原始 HTTP 请求,而不是使用客户端库,请使用 Google Cloud CLI 以非互动方式进行身份验证并管理访问令牌,而无需手动签署令牌:

  1. 使用在您的环境中配置的凭据文件向 Google Cloud CLI 授权:

    gcloud auth login --cred-file="${GOOGLE_APPLICATION_CREDENTIALS}"
    
  2. 在 API 请求的 Authorization 标头中传递生成的访问令牌:

    curl -X POST "https://datamanager.googleapis.com/v1/..." \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: application/json" \
      -d @request.json
    

    Google Cloud CLI 会自动缓存访问令牌,并在令牌过期之前刷新它。

验证 IAM 和账号访问权限

在部署生产应用之前,请验证您的服务账号是否具有必要的权限:

  1. Google Cloud IAM 权限:在启用了 Data Manager API 的 Google Cloud 项目中,向服务账号授予 Service Usage Consumer 角色 (roles/serviceusage.serviceUsageConsumer)。

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \
      --role="roles/serviceusage.serviceUsageConsumer"
    
  2. 目标账号访问权限:向服务账号授予对目标账号的必要访问权限。如需了解分步说明,请参阅设置账号访问权限。

代表用户执行操作

营销平台和代理机构等第三方平台通常需要代表注册其服务的多个广告客户发送 API 请求。

在此架构中,请使用 OAuth 2.0 Web 服务器流程从每个广告客户处获取具有离线访问权限的用户凭据,而不是使用应用默认凭据,然后根据请求所管理的广告客户账号,在运行时使用这些凭据配置客户端库。

实现 OAuth 2.0 Web 流程

以下是为多租户应用设置用户委托的方法:

  1. 请求离线访问权限:引导用户前往 Google 的 OAuth 权限请求页面,请求具有 access_type=offline 和 prompt=consent 的 https://www.googleapis.com/auth/datamanager 范围。您的服务器将授权代码换取为访问令牌和 refresh_token。如需查看分步说明,请参阅针对 Web 服务器应用使用 OAuth 2.0。

  2. 安全地存储凭据:在与您平台上的每个用户账号关联的加密凭据存储区中,安全地存储每个用户的刷新令牌。

  3. 在运行时初始化客户端库:当代表特定用户发送 API 请求时,请使用您为该用户存储的刷新令牌以及应用的客户端 ID 和客户端密钥来构建用户凭据,并在初始化客户端时传递这些凭据:

    .NET

    using Google.Ads.DataManager.V1;
    using Google.Apis.Auth.OAuth2;
    
    UserCredential credential = CredentialFactory.FromJsonParameters<UserCredential>(
        new JsonCredentialParameters
        {
            Type = JsonCredentialParameters.AuthorizedUserCredentialType,
            ClientId = clientId,
            ClientSecret = clientSecret,
            RefreshToken = refreshToken
        });
    
    IngestionServiceClient client = new IngestionServiceClientBuilder
    {
        Credential = credential
    }.Build();
    

    Go

    import (
        "context"
    
        datamanager "cloud.google.com/go/datamanager/apiv1"
        "golang.org/x/oauth2"
        "golang.org/x/oauth2/google"
        "google.golang.org/api/option"
    )
    
    cfg := &oauth2.Config{
        ClientID:     clientID,
        ClientSecret: clientSecret,
        Endpoint:     google.Endpoint,
    }
    ts := cfg.TokenSource(ctx, &oauth2.Token{RefreshToken: refreshToken})
    
    client, err := datamanager.NewIngestionClient(ctx, option.WithTokenSource(ts))
    

    Java

    import com.google.ads.datamanager.v1.IngestionServiceClient;
    import com.google.ads.datamanager.v1.IngestionServiceSettings;
    import com.google.api.gax.core.FixedCredentialsProvider;
    import com.google.auth.oauth2.UserCredentials;
    
    UserCredentials credentials =
        UserCredentials.newBuilder()
            .setClientId(clientId)
            .setClientSecret(clientSecret)
            .setRefreshToken(refreshToken)
            .build();
    
    IngestionServiceSettings settings =
        IngestionServiceSettings.newBuilder()
            .setCredentialsProvider(FixedCredentialsProvider.create(credentials))
            .build();
    
    try (IngestionServiceClient client = IngestionServiceClient.create(settings)) {
      // Send API requests using client...
    }
    

    Node.js

    const {IngestionServiceClient} = require('@google-ads/datamanager').v1;
    const {UserRefreshClient} = require('google-auth-library');
    
    const authClient = new UserRefreshClient({
      clientId,
      clientSecret,
      refreshToken,
    });
    
    const client = new IngestionServiceClient({authClient});
    

    PHP

    use Google\Ads\DataManager\V1\Client\IngestionServiceClient;
    use Google\Auth\Credentials\UserRefreshCredentials;
    
    $credentials = new UserRefreshCredentials(
        null,
        [
            'client_id' => $clientId,
            'client_secret' => $clientSecret,
            'refresh_token' => $refreshToken,
        ]
    );
    
    $client = new IngestionServiceClient(['credentials' => $credentials]);
    

    Python

    from google.ads.datamanager_v1 import IngestionServiceClient
    from google.oauth2.credentials import Credentials
    
    credentials = Credentials.from_authorized_user_info({
        "client_id": client_id,
        "client_secret": client_secret,
        "refresh_token": refresh_token,
    })
    
    client = IngestionServiceClient(credentials=credentials)
    

    Ruby

    require "google/ads/data_manager/v1"
    require "googleauth"
    
    credentials = Google::Auth::UserRefreshCredentials.new(
      client_id: client_id,
      client_secret: client_secret,
      refresh_token: refresh_token
    )
    
    client = Google::Ads::DataManager::V1::IngestionService::Client.new do |config|
      config.credentials = credentials
    end
    

完成 OAuth 应用验证

由于 https://www.googleapis.com/auth/datamanager 是敏感范围,因此任何用于从外部 Google 账号获取用户凭据的 Google Cloud 应用都必须先通过 Google OAuth 验证,然后才能投入生产:

  • 开发:当应用的发布状态在 Google Cloud 控制台的受众群体页面上设置为测试时,只有指定的测试账号可以授权您的应用。
  • 正式版:在面向外部用户发布应用之前,请将发布状态设置为正式版,然后提交应用以供验证。

使用服务账号运行的工作负载不需要进行应用验证。 此外,对于内部应用等场景,也有一些例外情况。如需了解详情,请参阅何时无需验证。

如果您的组织是已获批的数据合作伙伴,则可以使用合作伙伴链接,而无需管理每个用户的 OAuth 令牌,即可持续提取数据。

通过合作伙伴关联,广告客户可以在 Google Ads、Display & Video 360 或 Google Ad Manager 界面中将其账号与您的数据合作伙伴账号相关联。关联建立后,您的应用会通过 ADC 使用自己的服务账号凭据发送提取请求,从而避免了存储和维护长期有效的用户刷新令牌。

生产最佳做法

迁移到生产环境时,请查看以下关键操作注意事项: