GCP Cloud Build SSH访问Compute Engine遇公钥权限拒绝问题排查
一、解决Permission denied (publickey)错误的步骤
1. 配置Cloud Build服务账号权限
给Cloud Build默认使用的服务账号(格式:[PROJECT_NUMBER]@cloudbuild.gserviceaccount.com)添加Compute OS Login角色(roles/compute.osLogin);如果需要以管理员身份执行命令,再补充添加Compute OS Admin Login角色(roles/compute.osAdminLogin)。
2. 启用VM的OS Login功能
在Compute Engine实例的元数据中添加键值对:
- 键:
enable-oslogin - 值:
TRUE
(也可在项目级元数据中设置,对所有VM生效)
3. 修改cloudbuild.yaml中的SSH命令
不要用root用户登录,改用OS Login自动生成的服务账号用户(格式:sa_[SERVICE_ACCOUNT_ID],比如sa_123456789012),或直接让gcloud自动处理身份映射:
steps: - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: - '-c' - | gcloud compute ssh INSTANCE_NAME --zone ZONE --project PROJECT_ID --command "cd /path/to/your/app && docker-compose down && git pull && docker-compose up -d"
若需管理员权限,在命令前加sudo即可:
gcloud compute ssh INSTANCE_NAME --zone ZONE --project PROJECT_ID --command "cd /path/to/your/app && sudo docker-compose down && sudo git pull && sudo docker-compose up -d"
原方案失败原因
- 无预定义密钥:Cloud Build运行环境的默认密钥对未被VM授权,直接被拒绝登录。
- 使用预定义密钥:Cloud Build环境未正确加载密钥,或密钥文件权限不符合sshd要求(权限过松会被拒绝)。而OS Login通过服务账号身份验证,无需手动管理密钥,可靠性更高。
二、更优的持续部署流程建议
方案1:镜像构建+推送+VM自动拉取更新
- Cloud Build构建镜像:代码提交时,Cloud Build构建Cube.js的Docker镜像并推送到GCP Artifact Registry。
- VM侧触发更新:
- 在VM上部署轻量webhook服务(如Python/Flask),订阅Artifact Registry的镜像推送Pub/Sub事件,收到事件后执行
docker-compose pull && docker-compose up -d。 - 或用Cloud Scheduler定期触发VM拉取最新镜像并重启,适合更新频率较低的场景。
- 在VM上部署轻量webhook服务(如Python/Flask),订阅Artifact Registry的镜像推送Pub/Sub事件,收到事件后执行
方案2:基于Kubernetes Engine(GKE)部署
将Cube.js部署到GKE,用Deployment管理容器:
- Cloud Build完成镜像构建与推送。
- Cloud Build执行
kubectl set image deployment/DEPLOYMENT_NAME CONTAINER_NAME=IMAGE_PATH:TAG,触发GKE自动滚动更新,无需手动操作VM。
该方案自带负载均衡、自动恢复、版本回滚等能力,更适配生产环境。
方案3:Cloud Build+Compute Engine启动脚本
Cloud Build推送镜像后,给VM添加启动脚本并重启,由启动脚本自动完成镜像拉取与容器重启:
steps: - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: - '-c' - | # 省略镜像构建与推送步骤 gcloud compute instances add-metadata INSTANCE_NAME --zone ZONE --metadata startup-script="#!/bin/bash cd /path/to/your/app docker-compose pull docker-compose up -d" gcloud compute instances reset INSTANCE_NAME --zone ZONE
内容的提问来源于stack exchange,提问作者Rodrigo Magaldi
相关产品推荐
相关产品推荐

