使用工作负载身份联合生成服务账号访问令牌超时报错
报错根因
这个报错的核心触发逻辑是从下往上执行的,不属于GCP服务侧故障:
GCP SDK加载external_account类型的认证文件后,需要先获取当前AWS环境的有效身份凭证,才能向GCP IAM接口申请交换服务账号的访问令牌,最终调用Pub/Sub接口发消息。SDK默认会访问AWS链路本地元数据服务地址169.254.169.254拉取绑定在AWS资源上的IAM角色临时凭证,这一步连接超时,导致整个认证流程中断。
另外报错里显示的服务账号邮箱格式为<topic_id>@<project_id>.iam.gserviceaccount.com属于明显的参数拼接错误,就算元数据连通,后续也会触发权限类报错,需要优先修正。
排查步骤
- 先验证元数据服务连通性:在部署服务的AWS资源(EC2/ECS/EKS节点等)上执行
curl -m 5 http://169.254.169.254/latest/meta-data/iam/security-credentials,如果5秒超时,优先排查网络配置:- 检查实例安全组、本地iptables/nftables规则是否放通到169.254.169.254的80端口出流量
- 检查服务运行环境是否配置了全局HTTP/HTTPS代理,链路本地地址的流量被转发到代理服务器必然超时
- 检查EC2实例是否开启了IMDSv2强制访问、是否直接禁用了元数据服务
- 核对代码传入参数:确认传入SDK的服务账号名称不是Topic ID,GCP服务账号邮箱格式固定为
<服务账号名>@<GCP项目ID>.iam.gserviceaccount.com,和Pub/Sub主题ID没有关联。 - 核对认证文件配置:打开生成的
external_account类型JSON文件,检查credential_source字段配置是否匹配当前运行环境:- EC2环境下该字段应该指向AWS元数据服务地址,同时
imdsv2配置要和实例元数据服务的设置一致 - ECS、Lambda、EKS Pod或者本地测试环境下,该字段应该配置为从环境变量读取AWS凭证,而非硬编码元数据地址
- EC2环境下该字段应该指向AWS元数据服务地址,同时
- 核对IAM配置:确认当前AWS资源绑定的IAM角色ARN,已经被添加到GCP工作负载身份池的信任规则中,且身份池已经绑定目标GCP服务账号,授予了
roles/iam.serviceAccountTokenCreator角色。
解决方案
- 修复网络连通问题:如果是代理导致的超时,在服务启动环境变量中添加
NO_PROXY=169.254.169.254,metadata.google.internal,将链路本地地址加入代理绕过列表;如果是防火墙/安全组拦截,放通对应元数据地址的80端口访问权限;如果是IMDSv2强制开启,在认证文件的credential_source配置中添加"imdsv2": true。 - 修正参数错误:删除代码中手动拼接服务账号邮箱的逻辑,不要将Topic ID作为服务账号名传入,直接使用认证文件中预配置的服务账号信息即可。
- 适配运行环境调整认证文件:非EC2环境下将
credential_source修改为从环境变量读取AWS凭证,配置参考如下:"credential_source": { "environment_id": "aws1", "region": "<你的AWS资源所在区域,例如ap-northeast-1>", "access_key_id_env_var": "AWS_ACCESS_KEY_ID", "secret_access_key_env_var": "AWS_SECRET_ACCESS_KEY", "security_token_env_var": "AWS_SESSION_TOKEN" } - 优先使用SDK默认隐式认证逻辑:不要手动在代码中加载认证文件、拼接项目/主题参数,通过环境变量
GOOGLE_APPLICATION_CREDENTIALS指定认证文件的绝对路径,让SDK自动走默认认证链加载配置,避免手动传参引入的错误。 - 修复配置后先做最小化验证:在服务运行环境下先执行简单的Pub/Sub主题列表查询、测试消息发布,确认认证流程正常后再部署业务逻辑。
内容的提问来源于stack exchange,提问作者Meilan
相关产品推荐
相关产品推荐

