通过 Azure DevOps 使用 Arm 模板部署容器应用程序:未经授权:需要身份验证

问题描述 投票:0回答:1

我第一次尝试部署容器应用程序。

我已经部署了 Azure 容器注册表。 我已在订阅级别设置了用于 ACR 拉/推等的 Azure 服务连接的权限。

我做的第一件事是通过 Azure Devops 管道构建图像并将其推送到注册表。这效果很好。 我也有容器应用程序环境 其次,我使用 Arm 模板来创建容器应用程序。

- task: AzureResourceManagerTemplateDeployment@3
  displayName: "Create Container App"
  inputs:
    deploymentScope: 'Resource Group'
    azureResourceManagerConnection: $(serviceConnection)
    subscriptionId: '$(SubscriptionID)'
    action: 'Create Or Update Resource Group'
    resourceGroupName: '$(ResourceGroupName)'
    location: 'West Europe'
    templateLocation: 'Linked artifact'
    csmFile: '$(Pipeline.Workspace)/drop/armtemplates/container_deployment.json'
    csmParametersFile: '$(Pipeline.Workspace)/drop/armtemplates/container_parameters.json'
    deploymentMode: 'Incremental'
  continueOnError: false

模板的资源部分:

    "resources": [
        {
            "type": "Microsoft.App/containerApps",
            "apiVersion": "2023-05-01",
            "name": "[parameters('containerAppName')]",
            "location": "[parameters('location')]",
            "properties": {
                "managedEnvironmentId": "[resourceId('Microsoft.App/managedEnvironments', parameters('containerAppEnvName'))]",
                "configuration": {
                    "ingress": {
                        "external": true,
                        "targetPort": "[parameters('targetPort')]",
                        "allowInsecure": false,
                        "traffic": [
                            {
                                "latestRevision": true,
                                "weight": 100
                            }
                        ]
                    }
                },
                "template": {
                    "revisionSuffix": "firstrevision",
                    "containers": [
                        {
                            "name": "[parameters('containerAppName')]",
                            "image": "[parameters('containerImage')]",
                            "resources": {
                                "cpu": "[json(parameters('cpuCore'))]",
                                "memory": "[format('{0}Gi', parameters('memorySize'))]"
                            }
                        }
                    ],
                    "scale": {
                        "minReplicas": "[parameters('minReplicas')]",
                        "maxReplicas": "[parameters('maxReplicas')]"
                    }
                }
            }
        }
    ]
}

错误详细信息:以下字段无效或缺失。字段“template.containers.NameContainerApp.image”的详细信息无效:“无效值:“containerregistryname.azurecr.io/todolistapp:latest”:GET https:?scope=repository%3Atodolistapp%3Apull&service=containerregistryname.azurecr.io:未经授权:需要身份验证

在这种情况下到底需要什么授权?

azure azure-devops azure-pipelines containers azure-resource-manager
1个回答
0
投票

在您的模板中,当您部署私有注册表上托管的映像时,您没有在容器应用程序配置中提供凭据。

  1. 使用容器注册表

您可以在容器应用程序资源模板的 properties.configuration 部分的 registries 数组中定义注册表。

passwordSecretRef
字段标识您在其中定义密码的
secrets
数组名称中的密钥名称。

步骤:

  • 在访问键中启用管理员用户,您将获得密码。

    admin user

  • 在管道中,设置一个名为

    secrets
    的秘密变量,该值是您在访问密钥中获得的密码。

    secret

  • 在您的

    container_deployment.json
    中,在属性配置中添加
    secrets
    registries
    。 示例资源部分:

  "resources": [
    {
      "type": "Microsoft.App/containerApps",
      "apiVersion": "2023-05-01",
      "name": "[parameters('containerAppName')]",
      "location": "[parameters('location')]",
      "properties": {
        
        "managedEnvironmentId": "[resourceId('Microsoft.App/managedEnvironments', parameters('containerAppEnvName'))]",
        "configuration": {
          "ingress": {
            "external": true,
            "targetPort": "[parameters('targetPort')]",
            "allowInsecure": false,
            "traffic": [
              {
                "latestRevision": true,
                "weight": 100
              }
            ]
          },
            "secrets": [
              {
                "name": "myregistrypassword",
                "value": "[parameters('registry_password')]"
              }
            ],
            "registries": [
              {
                "server": "miao0909.azurecr.io",
                "username": "miao0909",
                "passwordSecretRef": "myregistrypassword"
              }
            ],
          "activeRevisionsMode": "Single"
        },
        "template": {
          "revisionSuffix": "firstrevision",
          "containers": [
            {
              "name": "[parameters('containerAppName')]",
              "image": "[parameters('containerImage')]",
              "resources": {
                "cpu": "[json(parameters('cpuCore'))]",
                "memory": "[format('{0}Gi', parameters('memorySize'))]"
              }
            }
          ],
          "scale": {
            "minReplicas": "[parameters('minReplicas')]",
            "maxReplicas": "[parameters('maxReplicas')]"
          }
        }
      }
    }
  ]
  • registry_password
    任务中使用
    Parameters: '-registry_password $(secrets)'
    覆盖
    AzureResourceManagerTemplateDeployment@3
    参数。
- task: AzureResourceManagerTemplateDeployment@3
  displayName: 'ARM Template deployment: Resource Group scope'
  inputs:
    deploymentScope: 'Resource Group'
    azureResourceManagerConnection: ''
    subscriptionId: ''
    action: 'Create Or Update Resource Group'
    resourceGroupName: 'Default'
    location: ''
    templateLocation: 'Linked artifact'
    csmFile: '$(Pipeline.Workspace)/drop/armtemplates/container_deployment.json'
    csmParametersFile: '$(Pipeline.Workspace)/drop/armtemplates/container_parameters.json'
    overrideParameters: '-registry_password $(secrets)'
    deploymentMode: 'Incremental'
  1. 使用 Azure 容器注册表托管身份

您可以使用 Azure 托管标识向 Azure 容器注册表进行身份验证,而不是使用用户名和密码。有关详细信息,请参阅 Azure 容器应用程序中的托管身份。

要将托管身份与注册表一起使用,必须在应用程序中启用该身份,并且必须在注册表中为其分配 acrPull 角色。要配置注册表,请在注册表的标识属性中使用托管标识资源 ID 作为用户分配的标识,或使用系统作为系统分配的标识。使用托管身份时请勿配置用户名和密码。

步骤:

  • 创建用户分配的身份
  • 将 ACR 拉/推角色分配给用户分配的身份
  • 在注册表的身份属性中添加托管身份资源 ID。

示例资源部分:

  "resources": [
    {
      "identity": {
        "userAssignedIdentities": {
          "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/Default/providers/Microsoft.ManagedIdentity/userAssignedIdentities/username": {}
        },
        "type": "UserAssigned"
      },
      "type": "Microsoft.App/containerApps",
      "apiVersion": "2023-05-01",
      "name": "[parameters('containerAppName')]",
      "location": "[parameters('location')]",
      "properties": {
        
        "managedEnvironmentId": "[resourceId('Microsoft.App/managedEnvironments', parameters('containerAppEnvName'))]",
        "configuration": {
          "ingress": {
            "external": true,
            "targetPort": "[parameters('targetPort')]",
            "allowInsecure": false,
            "traffic": [
              {
                "latestRevision": true,
                "weight": 100
              }
            ]
          },
            "registries": [
              {
                "server": "miao0909.azurecr.io",
                "identity": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/Default/providers/Microsoft.ManagedIdentity/userAssignedIdentities/username"
              }
            ],
          "activeRevisionsMode": "Single"
        },
        "template": {
          "revisionSuffix": "firstrevision",
          "containers": [
            {
              "name": "[parameters('containerAppName')]",
              "image": "[parameters('containerImage')]",
              "resources": {
                "cpu": "[json(parameters('cpuCore'))]",
                "memory": "[format('{0}Gi', parameters('memorySize'))]"
              }
            }
          ],
          "scale": {
            "minReplicas": "[parameters('minReplicas')]",
            "maxReplicas": "[parameters('maxReplicas')]"
          }
        }
      }
    }
  ]
© www.soinside.com 2019 - 2024. All rights reserved.