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

Azure App Service使用托管身份无法访问ACR的问题求助

Azure App Service多容器部署ACR镜像认证失败问题

问题概述

我在Azure App Service上部署多容器环境,使用存储在Azure Container Registry (ACR)中的镜像。已为App Service和ACR配置托管身份,并为App Service的托管身份分配了ACR Pull角色。可通过Azure CLI连接注册表,流水线也能正常推送镜像,但App Service拉取镜像时出现认证错误:

DockerApiException: Docker API responded with status code=InternalServerError, response={"message":"Head \"https://<my-registry>.azurecr.io/v2/<image>/manifests/latest\": unauthorized: authentication required, visit https://aka.ms/acr/authorization for more information."}

我的配置

  • App Service托管身份:已启用(状态为On),在ACR资源范围分配了ACR Pull角色
  • ACR托管身份:已启用(状态为On)
  • 部署流水线(Azure DevOps):构建并推送Docker镜像至ACR,配置片段如下:
trigger:
- main

variables:
  buildConfiguration: 'Release'
  appServiceName: 'myAppService'
  backendImageName: 'myregistry.azurecr.io/my-backend'
  frontendImageName: 'myregistry.azurecr.io/my-frontend'
  resourceGroup: 'myResourceGroup'
  subscriptionId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'

stages:
# Stage 1: Build and Push Docker Images
- stage: BuildAndPush
  displayName: Build and Push Docker Images to Azure Container Registry
  jobs:
  - job: BuildAndPush
    displayName: Build and Push Backend and Frontend Docker Images
    pool:
      vmImage: 'ubuntu-latest' # Use Ubuntu for Docker tasks
    steps:
    # Step 1: Login to Azure Container Registry
    - task: Docker@2
      displayName: Login to Azure Container Registry
      inputs:
        command: login
        containerRegistry: 'my_container_registry'

    # Step 2: Build and Push Backend Docker Image
    - task: Docker@2
      displayName: Build and Push Backend Docker Image
      inputs:
        command: buildAndPush
        dockerfile: ./Dockerfile
        context: ./Backend.Api
        repository: my-backend
        containerRegistry: 'my_container_registry'
        tags: |
          latest
          $(Build.BuildId)

    # Step 3: Build and Push Frontend Docker Image
    - task: Docker@2
      displayName: Build and Push Frontend Docker Image
      inputs:
        command: buildAndPush
        dockerfile: ./Frontend.Client/Dockerfile
        context: ./Frontend.Client
        repository: my-frontend
        containerRegistry: 'my_container_registry'
        tags: |
          latest
          $(Build.BuildId)

# Stage 2: Deploy to Azure
- stage: Deploy
  displayName: Deploy Docker Containers to Azure App Service
  dependsOn: BuildAndPush
  condition: succeeded()
  jobs:
  - job: DeployToAzure
    displayName: Deploy Containers to Azure App Service
    pool:
      vmImage: 'ubuntu-latest'
    steps:
    # Step 1: Login to Azure CLI
    - task: AzureCLI@2
      displayName: Login to Azure
      inputs:
        azureSubscription: 'Azure subscription 1(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)'
        scriptType: bash
        scriptLocation: inlineScript
        inlineScript: |
          echo "Logging in to Azure CLI"
    - task: Docker@2
      displayName: Login to Azure Container Registry
      inputs:
        command: login
        containerRegistry: 'my_container_registry'

    # Step 2: Generate Docker Compose File
    - script: |
        echo "
        version: '3.8'
        services:
          backend:
            image: $(backendImageName):latest
            ports:
              - 5000:80
          frontend:
            image: $(frontendImageName):latest
            ports:
              - 3000:80
        " > docker-compose.yml
      displayName: Generate Docker Compose File

    # Step 3: Configure App Service for Multi-Container Deployment
    - task: AzureCLI@2
      displayName: Configure Azure App Service with Docker Compose
      inputs:
        azureSubscription: 'Azure subscription 1(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)'
        scriptType: bash
        scriptLocation: inlineScript
        inlineScript: |
          az webapp config container set \
            --name $(appServiceName) \
            --resource-group $(resourceGroup) \
            --subscription $(subscriptionId) \
            --multicontainer-config-type compose \
            --multicontainer-config-file docker-compose.yml

    # Step 4: Restart App Service to Apply Changes
    - task: AzureCLI@2
      displayName: Restart Azure App Service
      inputs:
        azureSubscription: 'Azure subscription 1(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)'
        scriptType: bash
        scriptLocation: inlineScript
        inlineScript: |
          az webapp restart \
            --name $(appServiceName) \
            --resource-group $(resourceGroup) \
            --subscription $(subscriptionId)
  • 最终用于App Service的docker-compose.yml:
version: '3.8'
services:
  backend:
    image: <my-registry>.azurecr.io/backend:latest
    ports:
      - 5000:80
  frontend:
    image: <my-registry>.azurecr.io/frontend:latest
    ports:
      - 3000:80

已执行的排查步骤

  • 确认App Service和ACR均已启用托管身份
  • 确认App Service的托管身份已分配ACR Pull角色
  • 确认Docker镜像存在于ACR中,本地可通过同一docker-compose.yml拉取
  • 检查是否存在网络限制或防火墙阻断App Service与ACR的连接

错误日志

DockerApiException: Docker API responded with status code=InternalServerError, response={"message":"Head \"https://<my-registry>.azurecr.io/v2/<image>/manifests/latest\": unauthorized: authentication required, visit https://aka.ms/acr/authorization for more information."}

问题

  1. 需额外配置哪些项才能让App Service通过托管身份从ACR拉取镜像?
  2. 是否有特定的网络安全组(NSG)设置需要验证?

预期结果

  • App Service使用系统分配的托管身份向ACR认证
  • ACR Pull角色具备足够的镜像拉取权限
  • 容器可成功启动,无认证或授权问题

解决方案

1. 配置App Service使用托管身份认证ACR

执行以下Azure CLI命令,明确指定App Service使用托管身份连接ACR:

az webapp config container set \
  --name <你的App Service名称> \
  --resource-group <你的资源组名称> \
  --docker-registry-server-url https://<你的ACR名称>.azurecr.io \
  --enable-managed-identity true

这条命令会让App Service自动使用系统托管身份完成ACR认证,无需在docker-compose中配置凭证。

2. 验证ACR Pull角色分配的准确性

  • 确认角色是直接分配在ACR资源上,而非父资源组或订阅(虽然层级分配也生效,但直接绑定ACR更精准)。
  • 核对角色分配的主体:在App Service的“标识”页面复制系统托管身份的Object ID,然后在ACR的“访问控制(IAM)”中确认该Object ID已被授予ACR Pull角色。

3. 检查ACR的网络访问配置

  • 若ACR启用了防火墙:将App Service的所有出站IP地址添加到ACR的允许列表(可在App Service“属性”页面获取出站IP);或开启ACR的“允许受信任的Microsoft服务访问”选项。
  • 若ACR使用专用端点:确保App Service所在虚拟网络能访问该专用端点,且配置了正确的私有DNS区域(用于解析ACR域名到专用IP)。

4. 确认多容器部署配置无冲突

  • docker-compose文件中不要添加任何认证相关的配置(如credentials字段),避免覆盖托管身份认证逻辑。
  • 检查镜像名称是否完全正确,包括注册表域名、仓库名、标签,确保与ACR中的镜像一致。

5. NSG设置验证

  • 检查App Service所在子网的NSG出站规则:允许HTTPS(443端口)流量访问ACR的IP范围或域名。
  • 检查ACR所在子网的NSG入站规则:允许来自App Service子网的HTTPS流量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 05:54:55