You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vertex AI中KFP管道使用自定义服务账号的认证异常排查

问题

我希望在Vertex AI中运行KFP管道时使用特定(非默认)服务账号,且无法使用JSON密钥。理想情况下,能按照google.auth用户指南的建议,通过google.auth.default()获取项目ID和凭据。

我已经尝试了三种方式:

  • 使用已弃用的kfp.v2.google.client.AIPlatformClient,指定项目ID实例化客户端,在create_run_from_spec中传入service_account关键字参数运行管道
  • 使用google.cloud.aiplatform.pipeline_jobs.PipelineJob,指定项目ID实例化对象,在submit时传入service_account关键字参数运行管道
  • 通过云控制台UI(配合编译管道生成的JSON文件)指定服务账号创建新运行

无论在实际管道(基于自定义构建容器)还是最小可复现示例(使用轻量Python组件)中尝试上述方法,运行creds, project = google.auth.default()并打印项目ID和creds.service_account_email时,得到的都是一个陌生的固定项目ID,且服务账号邮箱为default。看起来传递给管道运行的配置完全未生效,我找不到操作中的错误点。

最小可复现代码

from kfp.v2 import dsl

@dsl.component(packages_to_install=['google-auth'])
def check_auth(name:str) -> str:
    import google.auth
    creds,project = google.auth.default()
    print(f'Project is: {project}')
    print(f'Got creds for: {creds.service_account_email}')
    return project

@dsl.pipeline(
    name='adc-mwe-pipeline'
)
def pipeline() -> str:
    auth_check = check_auth(name='name')
    return auth_check.output


from google.cloud.aiplatform import pipeline_jobs
from kfp.v2 import compiler

compiler.Compiler().compile(pipeline_func=pipeline, package_path='mwe.json')

start_pipeline = pipeline_jobs.PipelineJob(
    display_name='mwe',
    template_path='mwe.json',
    location='some-location',
    project='my-project',
    enable_caching=False
)

start_pipeline.submit(service_account="my-service-account")

解决方案

你遇到的核心问题是:Vertex AI管道提交时指定的service_account仅用于管道控制层面的操作(比如创建作业、管理资源),组件运行时默认使用的是GKE节点的服务账号,不会自动继承这个指定账号,所以google.auth.default()拿到的是容器环境的默认凭据,而非你指定的服务账号。

下面是两种可行的解决方式:

方式一:在组件中模拟目标服务账号

通过google.auth的身份模拟功能,让组件获取指定服务账号的凭据,无需额外集群配置。

修改组件代码如下:

@dsl.component(packages_to_install=['google-auth'])
def check_auth(name:str, target_sa: str) -> str:
    import google.auth
    from google.auth import impersonated_credentials

    # 先获取环境默认凭据,用于发起身份模拟请求
    base_creds, _ = google.auth.default()
    # 模拟目标服务账号
    target_creds = impersonated_credentials.Credentials(
        source_credentials=base_creds,
        target_principal=target_sa,
        target_scopes=['https://www.googleapis.com/auth/cloud-platform'],
        lifetime=3600
    )

    # 从环境变量获取项目ID(Vertex AI会自动注入该变量)
    import os
    project = os.environ.get('CLOUD_ML_PROJECT_ID')

    print(f'Project is: {project}')
    print(f'Got creds for: {target_creds.service_account_email}')
    return project

修改管道定义,添加服务账号参数:

@dsl.pipeline(
    name='adc-mwe-pipeline'
)
def pipeline(target_sa: str) -> str:
    auth_check = check_auth(name='name', target_sa=target_sa)
    return auth_check.output

最后提交管道时传入参数:

start_pipeline = pipeline_jobs.PipelineJob(
    display_name='mwe',
    template_path='mwe.json',
    location='some-location',
    project='my-project',
    parameter_values={"target_sa": "my-service-account"},
    enable_caching=False
)

start_pipeline.submit(service_account="my-service-account")

方式二:使用工作负载身份绑定(更优雅的长期方案)

如果你的Vertex AI运行在启用工作负载身份的GKE集群上,可以通过绑定Kubernetes服务账号(KSA)和Google服务账号(GSA),让组件直接使用目标服务账号的凭据。

  1. 创建Kubernetes服务账号:
kubectl create serviceaccount my-ksa
  1. 绑定KSA到目标GSA:
gcloud iam service-accounts add-iam-policy-binding my-service-account \
  --member="serviceAccount:my-project.svc.id.goog[default/my-ksa]" \
  --role="roles/iam.workloadIdentityUser"
  1. 修改组件指定使用该KSA:
@dsl.component(packages_to_install=['google-auth'], service_account_name='my-ksa')
def check_auth(name:str) -> str:
    import google.auth
    creds, project = google.auth.default()
    print(f'Project is: {project}')
    print(f'Got creds for: {creds.service_account_email}')
    return project

这样组件运行时会自动获取绑定的GSA凭据,google.auth.default()就能直接拿到目标服务账号的信息。

前置权限要求

无论用哪种方式,都需要确保:

  • 目标服务账号拥有Vertex AI User(roles/aiplatform.user)权限,以及组件运行所需的其他业务权限(比如GCS访问权限)
  • 提交管道的账号拥有模拟目标服务账号的权限(方式一需要),或者管理工作负载身份绑定的权限(方式二需要)

内容的提问来源于stack exchange,提问作者daniel.young

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 13:47:51