Skip to content

GitHub Actions推送Docker镜像到Google Artifact Registry权限问题解决

问题描述

当使用GitHub Actions将Docker镜像推送到Google Artifact Registry时,常遇到如下权限错误:

shell
denied: Permission "artifactregistry.repositories.uploadArtifacts" denied on resource 
"projects/PROJECT_ID/locations/asia-south1/repositories/images" (or it may not exist)

此错误表明当前服务账号缺少上传Docker镜像所需的权限,或Docker客户端未正确配置。以下是最常见的原因:

  1. IAM权限配置不正确(缺少Artifact Registry Writer角色)
  2. Docker未通过Google Cloud认证
  3. Region参数配置错误或缺失
  4. Workload Identity Federation认证配置问题

最佳解决方案

✅ 方案1:配置服务账号权限(必须)

  1. 添加Artifact Registry Writer角色

    • 访问Google Cloud Console → IAM & Admin
    • 找到您的服务账号
    • 点击编辑 → 添加角色 → 搜索"Artifact Registry Writer"并添加
  2. 补充token生成权限

    • 添加 roles/iam.serviceAccountTokenCreator 角色
    • 验证权限是否生效(需等待1-2分钟)

✅ 方案2:在GitHub Actions中配置Docker认证

使用docker/login-action进行认证:

yaml
- name: '登录到Google Artifact Registry'
  uses: docker/login-action@v3
  with:
    registry: ${{ env.REGION }}-docker.pkg.dev  # 替换为您的区域
    username: oauth2accesstoken
    password: ${{ steps.auth.outputs.access_token }} # 注意用access_token

✅ 方案3:配置gcloud Docker认证

在Actions中添加如下步骤:

yaml
- name: 配置Docker认证
  run: |
    gcloud auth configure-docker --quiet
    gcloud auth configure-docker ${{ env.REGION }}-docker.pkg.dev --quiet

完整工作流示例

yaml
name: 构建推送镜像到GCP Artifact Registry

on: [push]

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    permissions:
      id-token: write # 启用Workload Identity Federation
      contents: read
      
    steps:
    - name: 检出代码
      uses: actions/checkout@v4

    - id: auth
      name: Google Cloud认证
      uses: google-github-actions/auth@v2
      with:
        workload_identity_provider: 'projects/PROJECT_ID/locations/global/workloadIdentityPools/POOL_NAME/providers/PROVIDER_NAME'
        service_account: 'SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com'
        token_format: access_token  # 关键参数

    - name: 设置gcloud
      uses: google-github-actions/setup-gcloud@v1

    - name: 登录到Artifact Registry
      uses: docker/login-action@v3
      with:
        registry: asia-south1-docker.pkg.dev  # 替换您的区域
        username: oauth2accesstoken
        password: ${{ steps.auth.outputs.access_token }}  # 使用access_token

    - name: 构建Docker镜像
      run: docker build -t my-image:latest .

    - name: 推送到Artifact Registry
      run: |
        docker tag my-image:latest asia-south1-docker.pkg.dev/PROJECT_ID/images/my-image:latest
        docker push asia-south1-docker.pkg.dev/PROJECT_ID/images/my-image:latest

注意关键参数

  • token_format: access_token 必须明确设置
  • 确保密码使用 steps.auth.outputs.access_token 而不是 auth_token

常见错误排查

错误1:docker.push失败但前期步骤正常

shell
ERROR: (gcloud.auth.docker-helper) Unable to acquire impersonated credentials

解决方法:确保服务账号拥有 roles/iam.serviceAccountTokenCreator 权限

错误2:本地WSL环境配置问题

若本地开发遇到此问题:

  1. 确保已安装Google Cloud SDK
  2. 运行:
    bash
    gcloud init
    gcloud auth login
    gcloud auth configure-docker REGION-docker.pkg.dev

错误3:Docker安装方式导致

注意

如果使用Snap安装Docker,配置文件路径可能不同:

bash
# 解决方法:
sudo snap remove docker
curl -fsSL https://get.docker.com | sh  # 使用官方脚本重装

总结

要解决Permission "artifactregistry.repositories.uploadArtifacts" denied错误,需同时满足:

  1. IAM权限:服务账号拥有 Artifact Registry WriterService Account Token Creator 角色
  2. 认证配置
    • GitHub Actions中用docker/login-action显式登录
    • 确保使用access_token而非其他token格式
  3. Region一致性:所有命令中的region需匹配