Vertex AI Pipelines如何访问Cloud Shell中的本地密钥文件
问题根本原因
你遇到的访问不到文件、变量无效的核心原因是环境完全隔离:
- Cloud Shell只是你编写、编译、触发Pipeline的客户端环境,当你执行
trigger_pipeline()提交任务后,所有自定义组件的实际运行环境是Vertex AI动态拉起的独立计算实例(独立的GCE虚拟机/GKE Pod),和你当前的Cloud Shell没有任何文件系统、内存层面的共享。 - 你在Cloud Shell进程内声明的全局变量、打开的文件句柄
sfile,仅存在于Cloud Shell的进程内存中,不会被同步到远端的组件运行实例;你在Cloud Shell本地写的文件路径,在全新初始化的组件实例上自然不存在,传路径过去必然找不到文件。 - 额外说明:你写的
sfile= open("/path/to/keyfile.json", "r")拿到的是Python绑定当前操作系统的文件句柄对象,就算能跨环境传递,这个句柄在远端实例上也是完全无效的。
解决方案
优先推荐无密钥传递的方案,安全性最高、配置最简单:
- 提交Pipeline时指定Pipeline运行使用的自定义服务账号,给这个服务账号绑定目标Secret的
roles/secretmanager.secretAccessor访问权限即可。 - 组件代码中不需要手动加载本地密钥文件,直接使用运行环境默认绑定的服务账号凭证初始化客户端,代码示例:
@component( packages_to_install=['google-cloud-secret-manager'] ) def print_secret_op(project_id: str, secret_id: str, version_id: str) -> str: from google.cloud import secretmanager # 自动读取运行环境绑定的服务账号凭证,无需手动加载密钥文件 client = secretmanager.SecretManagerServiceClient() # 正常编写Secret读取逻辑即可
如果确实需要使用自定义密钥文件,可通过参数传递密钥内容的方式实现,不要传路径或文件对象:
- 主程序中读取密钥文件的完整文本内容,将其作为Pipeline参数透传给目标组件
- 组件收到密钥内容字符串后,先写入运行实例的本地临时文件,再通过临时文件路径加载凭证
对应代码示例:
主程序修改:
if __name__ == '__main__': # 读取密钥文件的完整内容,而非创建文件句柄 with open("/path/to/keyfile.json", "r") as f: sa_key_content = f.read() # 将sa_key_content作为参数传入pipeline,透传给print_secret_op组件 compile() trigger_pipeline(sa_key_content=sa_key_content)
组件修改:
import tempfile from kfp import dsl @dsl.component( packages_to_install=['google-cloud-secret-manager'] ) def print_secret_op(project_id: str, secret_id: str, version_id: str, sa_key_content: str) -> str: from google.cloud import secretmanager from google.oauth2 import service_account # 将传入的密钥内容写入本地临时文件 with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as tmp_file: tmp_file.write(sa_key_content) tmp_key_path = tmp_file.name # 加载临时文件中的凭证 credentials = service_account.Credentials.from_service_account_file(tmp_key_path) client = secretmanager.SecretManagerServiceClient(credentials=credentials) # 后续业务逻辑
注意:该方案会将密钥内容作为Pipeline参数存储,存在一定泄露风险,仅在必要场景使用。
如果密钥文件体积较大,也可以先将密钥文件上传到GCS存储桶,组件运行时先从GCS下载文件到本地再加载,注意要给Pipeline运行的服务账号绑定对应GCS路径的读取权限。
内容的提问来源于stack exchange,提问作者schoon
相关产品推荐
相关产品推荐

