你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用托管标识从 Azure 容器注册表部署到 Azure 容器实例

Azure 容器注册表 (ACR) 是基于 Azure 的托管容器注册表服务,用于存储专用的 Docker 容器映像。 本文介绍在使用 Azure 容器实例部署到容器组时,如何拉取存储在 Azure 容器注册表中的容器映像。 配置注册表访问权限的一种方法是创建 Microsoft Entra 托管标识。

使用专用终结点限制对 Azure 容器注册表 (ACR) 的访问时,使用托管标识允许部署到虚拟网络的 Azure 容器实例通过专用终结点访问容器注册表。

先决条件

Azure 容器注册表:需要具有至少一个映像的高级 SKU Azure 容器注册表。 如果需要创建注册表,请参阅使用 Azure CLI 创建容器注册表。 请务必记下注册表的 idloginServer

Azure CLI:本文中的命令行示例使用 Azure CLI,并采用适用于 Bash shell 的格式。 可在本地安装 Azure CLI,或使用 Azure Cloud Shell

限制

  • Windows 容器不支持使用 ACR 拉取的系统分配托管标识身份验证映像,仅支持用户分配的映像。

配置注册表身份验证

容器注册表必须已启用“受信任服务”。 若要查找有关如何启用受信任服务的说明,请参阅允许受信任服务安全地访问受网络限制的容器注册表

创建标识

使用 az identity create 命令在订阅中创建标识。 可以使用之前用于创建容器注册表的同一资源组,也可以使用其他资源组。

az identity create --resource-group myResourceGroup --name myACRId

若要在以下步骤中配置标识,请使用 az identity show 命令将标识的资源 ID 和服务主体 ID 存储在变量中。

为了在以后的步骤中正确配置标识,请使用 az identity show 获取标识的资源 ID 和服务主体 ID 并将其存储在变量中。

# Get resource ID of the user-assigned identity
USERID=$(az identity show --resource-group myResourceGroup --name myACRId --query id --output tsv)
# Get service principal ID of the user-assigned identity
SPID=$(az identity show --resource-group myResourceGroup --name myACRId --query principalId --output tsv)

需要标识的资源 ID 以从虚拟机登录到 CLI。 若要显示值,请执行以下操作:

echo $USERID

资源 ID 的格式为:

/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/resourcegroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myACRId

还需要服务主体 ID 来授予托管标识对容器注册表的访问权限。 若要显示值,请执行以下操作:

echo $SPID

服务主体 ID 的格式为:

xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx

向标识授予角色分配

为了使标识能够访问容器注册表,必须授予其角色分配。 使用以下命令将 acrpull 角色授予刚刚创建的标识,确保提供之前获得的注册表 ID 和服务主体:

az role assignment create --assignee $SPID --scope <registry-id> --role acrpull

使用 Azure 资源管理器 (ARM) 模板进行部署

首先将以下 JSON 复制到名为 azuredeploy.json 的新文件。 在 Azure Cloud Shell 中,可以使用 Visual Studio Code 在工作目录中创建文件:

code azuredeploy.json

通过在容器组定义中包含 imageRegistryCredentials 属性,可以在 ARM 模板中指定 Azure 容器注册表的属性。 例如,可以直接指定注册表凭据:

注意

这不是一个全面的 ARM 模板,而是一个完整模板的 resources 节的示例。

{
    "type": "Microsoft.ContainerInstance/containerGroups",
    "apiVersion": "2021-09-01",
    "name": "myContainerGroup",
    "location": "norwayeast",
    "identity": {
      "type": "UserAssigned",
      "userAssignedIdentities": {
        "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/resourcegroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myACRId": {}
        }
    },
    "properties": {
      "containers": [
        {
          "name": "mycontainer",
          "properties": {
            "image": "myacr.azurecr.io/hello-world:latest",
            "ports": [
              {
                "port": 80,
                "protocol": "TCP"
              }
            ],
            "resources": {
              "requests": {
                "cpu": 1,
                "memoryInGB": 1
              }
            }
        }
        }
      ],
      "imageRegistryCredentials": [
        {
            "server":"myacr.azurecr.io",
            "identity":"/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/resourcegroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myACRId"
        }
      ],
      "ipAddress": {
        "ports": [
          {
            "port": 80,
            "protocol": "TCP"
          }
        ],
        "type": "public"
      },
      "osType": "Linux"
    }
  }

部署模板

使用以下命令部署资源管理器模板:

az deployment group create --resource-group myResourceGroup --template-file azuredeploy.json

使用 Azure CLI 进行部署

若要使用托管标识部署容器组以通过 Azure CLI 对映像拉取进行身份验证,请使用以下命令并确保 <dns-label> 全局唯一:

az container create --name my-containergroup --resource-group myResourceGroup --image <loginServer>/hello-world:v1 --acr-identity $USERID --assign-identity $USERID --ports 80 --dns-name-label <dns-label>

使用 Azure CLI 在虚拟网络中部署

若要使用托管标识将容器组部署到虚拟网络,以通过 Azure CLI 对来自在专用终结点后面运行的 ACR 的映像拉取进行身份验证,请使用以下命令:

az container create --name my-containergroup --resource-group myResourceGroup --image <loginServer>/hello-world:v1 --acr-identity $USERID --assign-identity $USERID --vnet "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/"/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/resourceGroups/myVNetResourceGroup/providers/ --subnet mySubnetName

有关如何部署到虚拟网络的详细信息,请参阅将容器实例部署到 Azure 虚拟网络

使用 YAML 和 Azure CLI 在虚拟网络中部署多容器组

若要使用托管标识将多容器组部署到虚拟网络,以通过 Azure CLI 对来自在专用终结点后面运行的 ACR 的映像拉取进行身份验证,可以在 YAML 文件中指定容器组配置。 然后将该 YAML 文件作为参数传递给命令。

apiVersion: '2021-10-01'
location: eastus
type: Microsoft.ContainerInstance/containerGroups
identity: 
  type: UserAssigned
  userAssignedIdentities: {
    '/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/resourcegroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myACRId': {}
    }
properties:
  osType: Linux
  imageRegistryCredentials:
  - server: myacr.azurecr.io
    identity: '/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/resourcegroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myACRId'
  subnetIds:
  - id: '/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/resourceGroups/myVNetResourceGroup/providers/Microsoft.Network/virtualNetworks/myVNetName/subnets/mySubnetName'
    name: mySubnetName
  containers:
  - name: myContainer-1
    properties:
      resources:
        requests:
          cpu: '.4'
          memoryInGb: '1'
      environmentVariables:
        - name: CONTAINER
          value: 1
      image: 'myacr.azurecr.io/myimage:latest'
  - name: myContainer-2
    properties:
      resources:
        requests:
          cpu: '.4'
          memoryInGb: '1'
      environmentVariables:
        - name: CONTAINER
          value: 2
      image: 'myacr.azurecr.io/myimage:latest'
az container create --name my-containergroup --resource-group myResourceGroup --file my-YAML-file.yaml

有关如何部署到多容器组的详细信息,请参阅部署多容器组

清理资源

若要从 Azure 订阅中删除所有资源,请删除资源组:

az group delete --name myResourceGroup

后续步骤