GKE配置Workload Identity拉取Artifact Registry镜像报403错误
核心结论
你踩了GKE用户最常见的认知误区:Workload Identity仅为Pod运行时内部的业务进程提供GCP服务访问凭证,完全不参与kubelet的镜像拉取鉴权流程,你之前做的Kubernetes服务账号与IAM服务账号绑定配置,对镜像拉取没有任何作用。
关于凭证注入逻辑与节点手动拉取报错的说明
- 集群节点绑定的Compute Engine服务账号的凭证,通过节点本地的元数据服务(169.254.169.254)对外暴露,kubelet拉取镜像、节点上直接执行docker/crictl命令时,默认都会从这个元数据服务获取节点级服务账号的凭证做鉴权。你在节点上手动拉取镜像也报403,说明问题出在节点服务账号本身的权限配置上,和Kubernetes层的Workload Identity配置无关。
- Workload Identity是GKE在GKE_METADATA模式下,通过劫持Pod内部的元数据请求实现的凭证注入,仅对Pod内运行的进程生效。镜像拉取动作发生在Pod容器启动前,由节点上的kubelet完成,此时Pod的网络、存储挂载都还没完成,根本拿不到Workload Identity注入的凭证。
- 节点上直接执行docker/crictl pull报403不是预期行为:只要节点绑定的服务账号配置了正确的Artifact Registry读权限,手动拉取镜像应该可以直接成功。你看到的
failed to fetch anonymous token报错,说明kubelet根本没拿到有效凭证,直接走匿名访问被Artifact Registry拒绝了。
镜像拉取的额外配置说明
- 走节点服务账号鉴权的默认拉取路径,不需要额外配置imagePullSecret,只要把节点服务账号的权限配对即可。
- 如果你不想给节点服务账号开放Artifact Registry读权限,才需要手动创建镜像拉取密钥配置到Pod的imagePullSecrets字段,但这种方式维护成本更高,不是GKE的默认推荐方案。
修复步骤
- 先SSH到集群节点,执行以下命令确认节点当前实际使用的默认服务账号,排除节点绑定了错误服务账号的情况:
curl -s "http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/email" -H "Metadata-Flavor: Google"
确认返回值是你创建的custom-service-account@personal-XXXX.iam.gserviceaccount.com。
2. 到GCP IAM权限配置页,找到上述自定义服务账号,确认它在镜像所在的项目、或者目标Artifact Registry仓库层级,被授予了Artifact Registry Reader角色,注意不要选错授权主体,也不要把权限绑定到其他项目或错误的服务账号上——这是你当前问题的最高概率原因,哪怕你确认自己配过,也请重新核对主体和权限范围。
3. 权限配置完成后等待1-2分钟生效,先在节点上手动执行crictl pull命令验证镜像拉取,成功后重启失败的Pod即可正常启动。
4. 补充说明:你之前配置的Workload Identity仅在Pod内业务进程需要访问GCP其他服务(比如云存储、云数据库等)时生效,不需要为了镜像拉取调整这部分配置。另外注意给需要使用Workload Identity访问GCP服务的Pod,显式指定serviceAccountName为你绑定好的Kubernetes服务账号,否则Pod会用默认的default服务账号,拿不到对应权限。
内容的提问来源于stack exchange,提问作者individualtermite
相关产品推荐
相关产品推荐

