在 Azure 机器学习和其他服务之间设置身份验证

适用范围:Azure CLI ml 扩展 v2(最新版)Python SDK azure-ai-ml v2(最新版)

Azure 机器学习由多个 Azure 服务组成。 Azure 机器学习及其依赖的服务之间可以通过多种方式进行身份验证。

  • Azure 机器学习工作区使用托管标识来与其他服务通信。 默认情况下,此标识是系统分配的托管标识。 你也可以改用用户分配的托管标识。
  • Azure 机器学习使用 Azure 容器注册表 (ACR) 来存储用于训练和部署模型的 Docker 映像。 如果允许 Azure 机器学习自动创建 ACR,它将启用管理员帐户。
  • Azure 机器学习计算群集使用托管标识从 Azure Key Vault 检索数据存储的连接信息,以及从 ACR 拉取 Docker 映像。 你还可以配置对数据存储的基于标识的访问,这会改用计算群集的托管标识。
  • 根据数据存储服务和配置,可以沿多条路径进行数据访问。 例如,对数据存储的身份验证可以使用帐户密钥、令牌、安全主体、托管标识或用户标识。
  • 托管联机终结点在执行推理时可以使用托管标识访问 Azure 资源。 有关详细信息,请参阅从联机终结点访问 Azure 资源

先决条件

在按照本文中的步骤操作之前,请确保满足以下先决条件:

  • 若要分配角色,Azure 订阅登录名必须具有托管标识操作员角色或授予所需操作的其他角色(如所有者)。

  • 必须熟悉如何创建和使用托管标识

工作区标识类型

Azure 机器学习工作区使用托管标识来与其他服务通信。 Azure 机器学习支持多个标识类型。

托管标识类型 角色分配创建 目的
系统分配 (SAI) 由 Microsoft 管理 与资源关联的生命周期;单个资源使用;简单入门
系统分配+用户分配 (SAI+UAI) 由你管理 用户分配的标识、多资源使用的独立生命周期控制最低特权访问。 在训练作业中访问数据。

使用 SAI 标识类型创建工作区后,可以将其更新为 SAI+UAI,但不能从 SAI+UAI 更新回 SAI。 可以将多个用户分配的标识分配给同一工作区。

用户分配的托管标识

工作区

Azure 门户创建 Azure 机器学习工作区时,可以添加用户分配的托管标识。 创建工作区时使用以下步骤:

  1. 在“基本信息”页中,选择要用于工作区的 Azure 存储帐户、Azure 容器注册表和 Azure 密钥保管库。
  2. 在“标识”页中,选择“用户分配的标识”,然后选择要使用的托管标识

Azure 机器学习工作区的用户分配托管标识需要以下 Azure RBAC 角色分配,才能访问与工作区关联的资源中的数据。

资源 权限
Azure 机器学习工作区 参与者
Azure 存储 参与者(控制平面)+ 存储 Blob 数据参与者(数据平面,可选,用于在 Azure 机器学习工作室中启用数据预览)
Azure Key Vault(当使用 RBAC 权限模型时) 参与者(控制平面)+ Key Vault 管理员(数据平面)
Azure Key Vault(当使用访问策略权限模型时) 参与者 + 除清除操作之外的任何访问策略权限
Azure 容器注册表 参与者
Azure Application Insights 参与者

若要在用户分配的托管标识上自动创建角色分配,可以使用此 ARM 模板

提示

对于具有用于加密的客户管理的密钥的工作区,可以传入用户分配的托管标识以从存储向密钥保管库进行身份验证。 使用 user-assigned-identity-for-cmk-encryption (CLI) 或 user_assigned_identity_for_cmk_encryption (SDK) 参数传入托管标识。 此托管标识可与工作区主要用户分配的托管标识相同,也可不同。

若要使用多个用户分配的标识创建工作区,请使用以下方法之一:

适用于:Azure CLI ml 扩展 v2(当前)

az ml workspace create -f workspace_creation_with_multiple_UAIs.yml --subscription <subscription ID> --resource-group <resource group name> --name <workspace name>

其中 workspace_creation_with_multiple_UAIs.yml 的内容如下所示:

location: <region name>
identity:
   type: user_assigned
   user_assigned_identities:
    '<UAI resource ID 1>': {}
    '<UAI resource ID 2>': {}
storage_account: <storage acccount resource ID>
key_vault: <key vault resource ID>
image_build_compute: <compute(virtual machine) resource ID>
primary_user_assigned_identity: <one of the UAI resource IDs in the above list>

若要更新工作区的用户分配标识(包括添加新标识或删除现有标识),请使用以下方法之一:

适用于:Azure CLI ml 扩展 v2(当前)

az ml workspace update -f workspace_update_with_multiple_UAIs.yml --subscription <subscription ID> --resource-group <resource group name> --name <workspace name>

其中 workspace_update_with_multiple_UAIs.yml 的内容如下所示:

identity:
   type: user_assigned
   user_assigned_identities:
    '<UAI resource ID 1>': {}
    '<UAI resource ID 2>': {}
primary_user_assigned_identity: <one of the UAI resource IDs in the above list>

提示

若要添加新的 UAI,可以在 user_assigned_identities 部分下指定新的 UAI ID,除了现有的 UAI 以外,还需要传递所有现有的 UAI ID。
若要删除一个或多个现有的 UAI,可以将需要保留的 UAI ID 放在 user_assigned_identities 部分下,其余 UAI ID 将被删除。

除了系统分配的标识之外,还向工作区添加用户分配的托管标识

在某些情况下,除了默认的系统分配的工作区标识之外,你可能需要使用用户分配的托管标识。 若要添加用户分配的托管标识,而不更改现有工作区标识,请使用以下步骤:

  1. 创建用户分配的托管标识。 保存所创建的托管标识的 ID。

  2. 若要将托管标识附加到工作区,需要一个指定标识的 YAML 文件。 下面是 YAML 文件内容的一个示例。 将 <TENANT_ID><RESOURCE_GROUP><USER_MANAGED_ID> 替换为你的值。

    identity:
        type: system_assigned,user_assigned
        tenant_id: <TENANT_ID>
        user_assigned_identities:
            '/subscriptions/<SUBSCRIPTION_ID/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<USER_MANAGED_ID>':
            {}
    
  3. 使用 Azure CLI az ml workspace update 命令更新工作区。 使用 --file 参数指定上一步中的 YAML 文件。 以下示例展示了这种命令:

    az ml workspace update --resource-group <RESOURCE_GROUP> --name <WORKSPACE_NAME> --file <YAML_FILE_NAME>.yaml
    

计算群集

注意

Azure 机器学习计算群集只支持一个系统分配的标识或支持多个用户分配的标识,而不能同时支持这二者。

默认托管标识是系统分配的托管标识或第一个用户分配的托管标识。

在运行期间,一个标识有两种应用:

  1. 系统使用标识来设置用户的存储装载、容器注册表和数据存储。

    • 在这种情况下,系统将使用默认托管标识。
  2. 应用标识以便从已提交作业的代码中访问资源:

    • 在这种情况下,请提供与要用于检索凭据的托管标识对应的 client_id。
    • 或者,通过 DEFAULT_IDENTITY_CLIENT_ID 环境变量获取用户分配的标识的客户端 ID。

    例如,若要使用默认托管标识检索数据存储的令牌,请执行以下操作:

    client_id = os.environ.get('DEFAULT_IDENTITY_CLIENT_ID')
    credential = ManagedIdentityCredential(client_id=client_id)
    token = credential.get_token('https://storage.azure.com/')
    

若要使用托管标识配置计算群集,请使用以下方法之一:

适用于:Azure CLI ml 扩展 v2(当前)

az ml compute create -f create-cluster.yml

其中 create-cluster.yml 的内容如下:

$schema: https://azuremlschemas.azureedge.net/latest/amlCompute.schema.json 
name: basic-example
type: amlcompute
size: STANDARD_DS3_v2
min_instances: 0
max_instances: 2
idle_time_before_scale_down: 120
identity:
  type: user_assigned
  user_assigned_identities: 
    - resource_id: "identity_resource_id"

以下示例摘自某个 YAML 文件,它创建一个使用系统分配的托管标识的群集用于比较:

$schema: https://azuremlschemas.azureedge.net/latest/amlCompute.schema.json 
name: basic-example
type: amlcompute
size: STANDARD_DS3_v2
min_instances: 0
max_instances: 2
idle_time_before_scale_down: 120
identity:
  type: system_assigned

如果你有现有的计算群集,可以在用户托管标识和系统托管标识之间进行更改。 以下示例演示如何更改配置:

用户分配的托管标识

export MSI_NAME=my-cluster-identity
export COMPUTE_NAME=mycluster-msi

does_compute_exist()
{
  if [ -z $(az ml compute show -n $COMPUTE_NAME --query name) ]; then
    echo false
  else
    echo true
  fi
}

echo "Creating MSI $MSI_NAME"
# Get the resource id of the identity
IDENTITY_ID=$(az identity show --name "$MSI_NAME" --query id -o tsv | tail -n1 | tr -d "[:cntrl:]" || true)
if [[ -z $IDENTITY_ID ]]; then
    IDENTITY_ID=$(az identity create -n "$MSI_NAME" --query id -o tsv | tail -n1 | tr -d "[:cntrl:]")
fi
echo "MSI created: $MSI_NAME"
sleep 15 # Let the previous command finish: https://github.com/Azure/azure-cli/issues/8530


echo "Checking if compute $COMPUTE_NAME already exists"
if [ "$(does_compute_exist)" == "true" ]; then
  echo "Skipping, compute: $COMPUTE_NAME exists"
else
  echo "Provisioning compute: $COMPUTE_NAME"
  az ml compute create --name "$COMPUTE_NAME" --type amlcompute --identity-type user_assigned --user-assigned-identities "$IDENTITY_ID"
fi
az ml compute update --name "$COMPUTE_NAME" --identity-type user_assigned --user-assigned-identities "$IDENTITY_ID"

系统分配的托管标识

export COMPUTE_NAME=mycluster-sa

does_compute_exist()
{
  if [ -z $(az ml compute show -n $COMPUTE_NAME --query name) ]; then
    echo false
  else
    echo true
  fi
}

echo "Checking if compute $COMPUTE_NAME already exists"
if [ "$(does_compute_exist)" == "true" ]; then
  echo "Skipping, compute: $COMPUTE_NAME exists"
else
  echo "Provisioning compute: $COMPUTE_NAME"
  az ml compute create --name "$COMPUTE_NAME" --type amlcompute
fi

az ml compute update --name "$COMPUTE_NAME" --identity-type system_assigned

数据存储

当创建使用基于标识的数据访问的数据存储时,系统会使用你的 Azure 帐户(Microsoft Entra 令牌)来确认是否有权访问存储服务。 在基于身份的数据访问场景中,不会保存任何身份验证凭据。 只会将存储帐户信息存储在数据存储中。

相比之下,使用基于凭据的身份验证的数据存储将连接信息(如存储帐户密钥或 SAS 令牌)缓存在与工作区关联的密钥保管库中。 此方法的限制是,具有足够权限的其他工作区用户可以检索这些凭据,这可能会带来某些组织担心的安全问题。

有关如何对数据访问进行身份验证的详细信息,请参阅数据管理一文。 有关配置基于标识的数据访问的信息,请参阅创建数据存储

在以下两种情况下,你可以在 Azure 机器学习中应用基于标识的数据访问。 当使用机密数据且需要更精细的数据访问管理时,这些方案非常适合基于标识的访问:

  • 访问存储服务
  • 训练机器学习模型

基于标识的访问允许使用基于角色的访问控制 (RBAC) 来限制哪些标识(如用户或计算资源)有权访问数据。

访问存储服务

可以使用 Azure 机器学习数据存储通过基于标识的数据访问连接到存储服务。

使用基于标识的数据访问时,Azure 机器学习会提示你输入用于数据访问身份验证的 Microsoft Entra 令牌,而不是将凭据保存在数据存储中。 这样,你就可以在存储级别进行数据访问管理,并让凭据保密。

通过本地计算机或计算实例上的 Jupyter Notebook 以交互方式处理数据时,同一行为适用。

注意

使用基于凭据的身份验证来存储的凭据包括:订阅 ID、共享访问签名 (SAS) 令牌、存储访问密钥和服务主体信息,例如,客户端 ID 和租户 ID。

为确保安全地连接到 Azure 上的存储服务,Azure 机器学习会要求你具有相应数据存储的访问权限。

警告

不支持跨租户访问存储帐户。 如果方案需要跨租户访问,请联系 Azure 机器学习数据支持团队(别名 amldatasupport@microsoft.com),获取自定义代码解决方案的帮助。

基于标识的数据访问仅支持与以下存储服务的连接:

  • Azure Blob 存储
  • Azure Data Lake Storage Gen1
  • Azure Data Lake Storage Gen2

若要访问这些存储服务,必须至少具有存储帐户存储 Blob 数据读取者访问权限。 只有存储帐户所有者可以通过 Azure 门户更改访问级别

使用托管标识访问计算群集上训练作业的数据

某些机器学习方案涉及使用专用数据。 在这种情况下,数据科学家可能无法以 Microsoft Entra 用户身份直接访问数据。 在此方案中,计算的托管标识可用于数据访问身份验证。 在此方案中,只能从计算实例或执行训练作业的机器学习计算群集访问数据。 使用此方法,管理员授予计算实例或计算群集托管标识对存储的存储 Blob 数据读取者权限。 不需要为各个数据科学家分别授予访问权限。

若要启用使用计算托管标识的身份验证,请执行以下操作:

注意

为计算实例或群集创建的系统托管标识的名称在 Microsoft Entra ID 中的格式为 /workspace-name/computes/compute-name。

启用基于标识的身份验证后,在访问训练作业中的数据时,默认使用计算托管标识。 (可选)可以使用下一部分所述的步骤通过用户标识进行身份验证。

若要了解如何为存储配置 Azure RBAC,请参阅基于角色的访问控制

使用用户标识访问计算群集上训练作业的数据

适用于:Azure CLI ml 扩展 v2(当前)

Azure 机器学习计算群集上进行训练时,可以使用用户 Microsoft Entra 令牌向存储进行身份验证。

此身份验证模式使你可以:

  • 设置精细权限,其中不同的工作区用户有权访问不同的存储帐户或存储帐户中的不同文件夹。
  • 让数据科学家重新使用对存储系统的现有权限。
  • 审核存储访问,因为存储日志会显示用于访问数据的标识。

重要

此功能具有以下限制

  • 功能支持通过 Azure 机器学习 CLI 和 Python SDK V2 提交的试验,但不支持通过 ML Studio 提交的试验。
  • 用户标识和计算托管标识不能用于同一作业中的身份验证。
  • 对于管道作业,建议在将在计算上执行的单个步骤级别(而不是在根管道级别)设置用户标识。 (虽然根管道和步骤级别都支持标识设置,但如果同时设置两者,步骤级别设置会优先。但是,对于包含管道组件的管道,必须在将执行的各个步骤上设置标识。在根管道或管道组件级别设置的标识将不起作用。因此,为了简单起见,建议在单个步骤级别设置标识。)

以下步骤概述了如何使用用户标识设置数据访问权限,以便通过 CLI 在计算群集上训练作业。

  1. 向用户标识授予对存储资源的访问权限。 例如,向 StorageBlobReader 授予对要使用的特定存储帐户的访问权限,或授予对 Azure Data Lake Gen 2 存储中特定文件夹或文件的基于 ACL 的权限。

  2. 在没有存储帐户的缓存凭据的情况下,创建 Azure 机器学习数据存储。 如果数据存储具有缓存凭据(例如存储帐户密钥),则使用这些凭据而不是用户标识。

  3. 提交属性 identity 设置为 type: user_identity 的训练作业,如以下作业指定所示。 在训练作业期间,通过提交作业的用户标识对存储进行身份验证。

    注意

    如果 identity 属性未指定且数据存储没有缓存凭据,则计算托管标识会成为备用选项。

    command: |
    echo "--census-csv: ${{inputs.census_csv}}"
    python hello-census.py --census-csv ${{inputs.census_csv}}
    code: src
    inputs:
    census_csv:
        type: uri_file 
        path: azureml://datastores/mydata/paths/census.csv
    environment: azureml:AzureML-sklearn-1.0-ubuntu20.04-py38-cpu@latest
    compute: azureml:cpu-cluster
    identity:
    type: user_identity
    

以下步骤概述了如何使用用户标识设置数据访问权限,以便通过 Python SDK 在计算群集上训练作业。

  1. 如上所述为 CLI 授予数据访问权限并创建数据存储。

  2. 提交标识参数设置为 azure.ai.ml.UserIdentityConfiguration 的训练作业。 此参数设置使作业能够代表提交作业的用户访问数据。

    from azure.ai.ml import command
    from azure.ai.ml.entities import Data, UriReference
    from azure.ai.ml import Input
    from azure.ai.ml.constants import AssetTypes
    from azure.ai.ml import UserIdentityConfiguration
    
    # Specify the data location
    my_job_inputs = {
        "input_data": Input(type=AssetTypes.URI_FILE, path="<path-to-my-data>")
    }
    
    # Define the job
    job = command(
        code="<my-local-code-location>", 
        command="python <my-script>.py --input_data ${{inputs.input_data}}",
        inputs=my_job_inputs,
        environment="AzureML-sklearn-0.24-ubuntu18.04-py37-cpu:9",
        compute="<my-compute-cluster-name>",
        identity= UserIdentityConfiguration() 
    )
    # submit the command
    returned_job = ml_client.jobs.create_or_update(job)
    

重要

在启用用户标识身份验证的作业提交期间,代码快照通过校验和验证防止篡改。 如果你有现有的管道组件,并且打算在启用用户标识的情况下将其用于身份验证,可能需要重新上传它们。 否则作业可能会在校验和验证期间失败。

使用虚拟网络

默认情况下,Azure 机器学习无法与防火墙后面或虚拟网络中的存储帐户通信。

可将存储帐户配置为仅允许从特定虚拟网络进行访问。 要确保数据不会泄露到外部网络,还需要对此配置执行其他步骤。 基于凭据的数据访问同样具有此行为。 有关详细信息,请参阅如何防止数据外泄

如果存储帐户具有虚拟网络设置,则指定需要哪些标识类型和权限访问。 例如,对于数据预览和数据配置文件,虚拟网络设置确定用于对数据访问进行身份验证的标识类型。

  • 在只允许某些 IP 和子网访问存储的情况下,Azure 机器学习使用工作区 MSI 完成数据预览和配置文件。

  • 如果存储是 ADLS Gen 2 或 Blob,并且具有虚拟网络设置,则客户可以使用用户标识或工作区 MSI,具体取决于创建期间定义的数据存储设置。

  • 如果虚拟网络设置为“允许受信任服务列表中的 Azure 服务访问此存储帐户”,则使用工作区 MSI。

方案:没有管理员用户的 Azure 容器注册表

禁用 ACR 的管理员用户时,Azure 机器学习使用托管标识来生成和拉取 Docker 映像。 将 Azure 机器学习配置为在禁用管理员用户的情况下使用 ACR 时,有两个工作流:

  • 允许 Azure 机器学习创建 ACR 实例,然后禁用管理员用户。
  • 使用已禁用管理员用户的现有 ACR。

带有自动创建的 ACR 实例的 Azure 机器学习

  1. 创建新的 Azure 机器学习工作区。

  2. 执行需要 Azure 容器注册表的操作。 有关示例,请参阅教程:训练你的第一个模型

  3. 获取群集创建的 ACR 的名称。

    适用于:Azure CLI ml 扩展 v2(当前)

    az ml workspace show --name <my workspace name> \
    --resource-group <my resource group> \
    --subscription <my subscription id> \
    --query container_registry
    

    此命令返回类似于以下文本的值。 只需要文本的最后一部分,即 ACR 实例名称:

    /subscriptions/<subscription id>/resourceGroups/<my resource group>/providers/MicrosoftContainerReggistry/registries/<ACR instance name>
    
  4. 更新 ACR 以禁用管理员用户:

    az acr update --name <ACR instance name> --admin-enabled false
    

自带 ACR

如果订阅策略不允许使用 ACR 管理员用户,则应首先创建无管理员用户的 ACR,然后将其与工作区关联。 从 Azure CLI 创建 ACR,无需设置 --admin-enabled 参数,或从 Azure 门户创建,无需启用管理员用户。 然后,在创建 Azure 机器学习工作区时,指定 ACR 的 Azure 资源 ID。 下面的示例演示如何创建使用现有 ACR 的新 Azure 机器学习工作区:

适用于:Azure CLI ml 扩展 v2(当前)

az ml workspace create -n <workspace name> \
-g <workspace resource group> \
-l <region> \
--container-registry /subscriptions/<subscription id>/resourceGroups/<acr resource group>/providers/Microsoft.ContainerRegistry/registries/<acr name>

提示

若要获取 --container-registry 参数的值,请使用 az acr show 命令显示 ACR 的信息。 id 字段包含 ACR 的资源 ID。

此外,如果已禁用管理员用户的现有 ACR,可以通过更新它将其附加到工作区。 以下示例演示如何更新 Azure 机器学习工作区以使用现有 ACR:

适用于:Azure CLI ml 扩展 v2(当前)

az ml workspace update --update-dependent-resources \
--name <workspace name> \
--resource-group <workspace resource group> \
--container-registry /subscriptions/<subscription id>/resourceGroups/<acr resource group>/providers/Microsoft.ContainerRegistry/registries/<acr name>

使用托管标识创建计算以访问用于训练的 Docker 映像

若要访问工作区 ACR,请创建启用了系统分配的托管标识的机器学习计算群集。 可以在创建计算时从 Azure 门户或工作室启用该标识,也可以通过以下方法从 Azure CLI 启用。 有关详细信息,请参阅将托管标识用于计算群集

适用于:Azure CLI ml 扩展 v2(当前)

az ml compute create --name cpu-cluster --type <cluster name>  --identity-type systemassigned

托管标识在工作区 ACR 上自动被授予 ACRPull 角色,以允许拉取 Docker 映像进行训练。

注意

如果首先创建计算,则必须手动分配 ACRPull 角色,才能创建工作区 ACR。

使用 Docker 映像进行推理

如前面所述,在没有管理员用户的情况下配置 ACR 后,可以访问 Docker 映像进行推理,无需 Azure Kubernetes service (AKS) 中的管理密钥。 创建 AKS 或将其附加到工作区时,会自动为该群集的服务主体分配对工作区 ACR 的 ACRPull 访问权限。

注意

如果自带 AKS 群集,则群集必须已启用服务主体而不是托管标识。

方案:使用专用 Azure 容器注册表

默认情况下,Azure 机器学习使用来自 Azure 托管的公共存储库中的 Docker 基础映像。 然后,在这些映像上生成训练或推理环境。 有关详细信息,请参阅什么是 ML 环境?

若要在企业内部使用自定义基础映像,可以使用托管标识访问专用 ACR。 下面是两个用例:

  • 使用基础映像按原样进行训练。
  • 使用自定义映像作为基础生成 Azure 机器学习托管映像。

将 Docker 基础映像拉取到机器学习计算群集按原样进行训练

如前面所述,创建启用了系统分配的托管标识的机器学习计算群集。 然后,确定托管标识的主体 ID。

适用于:Azure CLI ml 扩展 v2(当前)

az ml compute show --name <cluster name> -n <workspace> -g <resource group>

或者,可以更新计算群集来分配用户分配的托管标识:

适用于:Azure CLI ml 扩展 v2(当前)

az ml compute update --name <cluster name> --user-assigned-identities <my-identity-id>

若要允许计算群集拉取基础映像,请在专用 ACR 上授予托管服务标识 ACRPull 角色

适用于:Azure CLI ml 扩展 v2(当前)

az role assignment create --assignee <principal ID> \
--role acrpull \
--scope "/subscriptions/<subscription ID>/resourceGroups/<private ACR resource group>/providers/Microsoft.ContainerRegistry/registries/<private ACR name>"

最后,创建环境,并在环境 YAML 文件中指定基础映像位置。

适用于:Azure CLI ml 扩展 v2(当前)

$schema: https://azuremlschemas.azureedge.net/latest/environment.schema.json
name: docker-image-example
image: pytorch/pytorch:latest
description: Environment created from a Docker image.
az ml environment create --file <yaml file>

现在可以在训练作业中使用环境。

从专用 ACR 生成 Azure 机器学习托管环境到基础映像以进行训练或推理

后续步骤