You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DevOps Pipeline在Azure VM中拉取ACR镜像失败求助

问题描述

运行DevOps Pipeline时,已成功构建并推送Docker镜像至Azure容器注册表(ACR),但在Azure Linux虚拟机内拉取镜像时失败,报错如下:

##[error]Error response from daemon: Head "https://<ACR_NAME>.azurecr.io/v2/<IMAGE_NAME>/manifests/latest": unauthorized: {"errors":[{"code":"UNAUTHORIZED","message":"authentication required, visit https://aka.ms/acr/authorization for more information."}]}

不清楚如何通过SSH连接到Linux虚拟机并成功拉取镜像,已尝试以下步骤:

  • 在VM上安装Azure CLI,并使用AzureCLI@2任务建立拉取镜像的会话
  • 创建了SSH和Docker Registry的服务连接,以及用于身份验证的服务主体(Service Principal)
  • 尝试过不使用Azure CLI的方式

以下是流水线文件:

variables:
  ACR_NAME: '&lt;ACR_NAME&gt;'
  IMAGE_NAME: '&lt;IMAGE_NAME&gt;'
  ACR_USER: '&lt;ACR_USER&gt;'
  VM_USER: '&lt;VM_USER&gt;'
  VM_HOST: '&lt;VM_HOST&gt;'
  SSH_CONN_NAME: '&lt;SSH_CONN_NAME&gt;'
  ACR_CONN_NAME: '&lt;ACR_CONN_NAME&gt;'
  RESOURCE_MANAGER_CONN: '&lt;RESOURCE_MANAGER_CONN&gt;'
  AIRFLOW_UID: '50000'

stages:
- stage: BuildAndDeploy
  displayName: 'Build and Deploy Stage'
  jobs:
  - job: BuildAndPush
    displayName: 'Build and Push Docker Image'
    pool:
      vmImage: 'ubuntu-latest'
    steps:
    - task: DockerInstaller@0
      inputs:
        dockerVersion: '27.0.2'

    - task: Docker@2
      displayName: 'Build the Docker Img'
      inputs:
        command: 'build'
        repository: '$(ACR_NAME).azurecr.io/$(IMAGE_NAME)'
        dockerfile: '$(Build.SourcesDirectory)/Dockerfile'
        tags: 'latest'

    - task: DockerCompose@0
      displayName: 'Push the Docker Img'
      inputs:
        action: 'Push services'
        azureSubscriptionEndpoint: '$(RESOURCE_MANAGER_CONN)'
        azureContainerRegistry: '$(ACR_NAME)'
        dockerComposeFile: 'docker-compose.prod.yaml'
        projectName: '$(Build.Repository.Name)'
        additionalImageTags: |
          $(Build.BuildId)
          prod
        qualifyImageNames: true

  - job: Deploy
    displayName: 'Deploy to Azure VM'
    pool:
      vmImage: 'ubuntu-latest'
    steps:
    - task: AzureCLI@2
      displayName: 'Azure CLI Login'
      inputs:
        azureSubscription: '$(RESOURCE_MANAGER_CONN)'
        scriptType: 'bash'
        scriptLocation: 'inlineScript'
        inlineScript: |
          az acr login --name $(ACR_NAME)

    - task: SSH@0
      displayName: 'Deploy using docker-compose on Azure VM'
      inputs:
        sshEndpoint: $(SSH_CONN_NAME)
        runOptions: 'inline'
        inline: |
          az acr login --name $(ACR_NAME)
          docker stop $(IMAGE_NAME) || true
          docker rm $(IMAGE_NAME) || true
          docker pull $(ACR_NAME).azurecr.io/$(IMAGE_NAME):latest
          cd $(Build.Repository.LocalPath)
          docker-compose -f docker-compose.p.yaml up -d
解决方案

核心问题分析

流水线中的AzureCLI@2任务是在DevOps代理机器(ubuntu-latest)上执行的,凭证不会同步到Azure VM环境中。SSH任务里执行az acr login时,VM上的Azure CLI没有有效身份凭证,导致Docker拉取镜像时认证失败。

以下是几种可行的解决方法:


方法1:在VM中使用服务主体认证ACR

直接在VM上通过服务主体完成身份验证,无需依赖代理机器的凭证:

  1. 确保服务主体拥有**ACR拉取(AcrPull)**权限
  2. 在流水线中添加保密变量SP_APP_ID、SP_PASSWORD、TENANT_ID
  3. 修改SSH任务的inline脚本:
# 用服务主体登录Azure CLI
az login --service-principal -u $(SP_APP_ID) -p $(SP_PASSWORD) --tenant $(TENANT_ID)
# 登录ACR
az acr login --name $(ACR_NAME)
# 执行镜像操作
docker stop $(IMAGE_NAME) || true
docker rm $(IMAGE_NAME) || true
docker pull $(ACR_NAME).azurecr.io/$(IMAGE_NAME):latest
# 注意:需先将docker-compose文件上传到VM,替换为VM上的实际路径
cd /vm/path/to/docker-compose
docker-compose -f docker-compose.p.yaml up -d

方法2:使用ACR访问密钥直接登录Docker

跳过Azure CLI,直接用ACR访问密钥给Docker完成登录:

  1. 在ACR门户的"访问密钥"页面开启管理员账户,获取用户名和密码
  2. 在流水线中添加保密变量ACR_USERNAME、ACR_PASSWORD
  3. 修改SSH任务脚本:
# 直接登录ACR
docker login $(ACR_NAME).azurecr.io -u $(ACR_USERNAME) -p $(ACR_PASSWORD)
# 执行镜像操作
docker stop $(IMAGE_NAME) || true
docker rm $(IMAGE_NAME) || true
docker pull $(ACR_NAME).azurecr.io/$(IMAGE_NAME):latest
# 替换为VM上docker-compose的实际路径
cd /vm/path/to/docker-compose
docker-compose -f docker-compose.p.yaml up -d

方法3:给VM系统分配身份赋予ACR权限

如果VM启用了系统分配托管身份,可直接通过身份完成认证:

  1. 在Azure门户给VM的系统分配身份添加**ACR拉取(AcrPull)**角色权限
  2. 在VM上安装azure-cli和docker-credential-acr-helper
  3. 修改SSH任务脚本:
# 用托管身份登录Azure CLI
az login --identity
az acr login --name $(ACR_NAME)
# 执行镜像操作
docker stop $(IMAGE_NAME) || true
docker rm $(IMAGE_NAME) || true
docker pull $(ACR_NAME).azurecr.io/$(IMAGE_NAME):latest
# 替换为VM上docker-compose的实际路径
cd /vm/path/to/docker-compose
docker-compose -f docker-compose.p.yaml up -d

额外注意事项

  • 流水线中的$(Build.Repository.LocalPath)是代理机器路径,VM上不存在,需通过CopyFilesOverSSH任务提前将docker-compose文件及相关资源上传到VM指定目录
  • 确保VM上的Docker和Azure CLI版本兼容,避免因版本问题导致登录失败

内容的提问来源于stack exchange,提问作者dimButTries

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 20:25:54