Google Cloud Build构建Cloud Run镜像时如何正确注入服务账号凭证?
Cloud Build构建Laravel镜像访问Secret Manager失败解决方案
问题描述
构建过程中出现以下报错:
Failed to load secrets: cURL error 28: Failed to connect to 169.***.***.** port 80 after 130458 ms: Couldn't connect to server (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for http://169.***.***.**/computeMetadata/v1/instance/service-accounts/default/token?scopes=https://www.googleapis.com/auth/cloud-platform
原因:Cloud Build环境无法访问GCE实例元数据服务器,导致无法获取默认服务账号令牌。
用户目标
- 通过Cloud Build构建Laravel应用Docker镜像
- 构建期间从Secret Manager获取密钥
- 自动将密钥注入Docker镜像供应用使用
已尝试操作
- 创建拥有
roles/secretmanager.secretAccessor权限的服务账号 - 安全存储服务账号密钥JSON文件
- 修改
cloudbuild.yaml注入GOOGLE_APPLICATION_CREDENTIALS环境变量
解决方案
1. 服务账号凭证注入Cloud Build的最佳方式
优先使用Cloud Build内置的服务账号授权,无需手动注入JSON密钥,步骤如下:
- 找到Cloud Build默认服务账号,格式为
[PROJECT_NUMBER]@cloudbuild.gserviceaccount.com - 为该账号添加
roles/secretmanager.secretAccessor权限:- 进入Google Cloud控制台IAM页面
- 定位到Cloud Build服务账号,点击编辑权限
- 添加
Secret Manager Secret Accessor角色
- 无需在
cloudbuild.yaml中手动设置GOOGLE_APPLICATION_CREDENTIALS,Cloud Build会自动为默认服务账号提供临时凭证,Google Cloud客户端库会自动读取这些凭证,绕过元数据服务器访问。
若需权限隔离使用自定义服务账号,可在cloudbuild.yaml中指定:
steps: - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', 'gcr.io/$PROJECT_ID/laravel-app', '.'] serviceAccount: 'projects/[PROJECT_ID]/serviceAccounts/[CUSTOM_SERVICE_ACCOUNT_EMAIL]'
确保自定义服务账号已配置roles/secretmanager.secretAccessor权限。
2. 凭证方案选择
- 不推荐直接使用JSON密钥:属于长期凭证,泄露风险高,需手动管理存储和轮换,维护成本大。
- 推荐配置Cloud Build服务账号:使用临时凭证,无需存储长期密钥,符合Google Cloud安全最佳实践,客户端库自动识别凭证,无需额外配置。
额外优化:构建时注入密钥的正确方式
避免在镜像中嵌入服务账号凭证,可通过Cloud Build步骤先拉取密钥再构建:
- 在
cloudbuild.yaml中添加拉取密钥的步骤:
steps: - name: 'gcr.io/cloud-builders/gcloud' args: ['secrets', 'versions', 'access', 'latest', '--secret=laravel-app-secrets', '--out-file=./.env'] - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', 'gcr.io/$PROJECT_ID/laravel-app', '.']
- 在Dockerfile中复制密钥文件到镜像:
COPY .env /var/www/html/.env
内容的提问来源于stack exchange,提问作者ristol
相关产品推荐
相关产品推荐

