使用网络隔离保护托管的联机终结点

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

在本文中,你将使用网络隔离来保护托管联机终结点。 你将创建一个托管联机终结点,以使用 Azure 机器学习工作区的专用终结点来保护入站通信。 你还将使用托管虚拟网络配置工作区,该虚拟网络仅允许部署的已批准的出站通信。 最后,你将创建一个部署,该部署使用工作区托管虚拟网络的专用终结点进行出站通信。

有关使用旧方法进行网络隔离的示例,请参阅 azureml-examples GitHub 存储库中的部署文件 deploy-moe-vnet-legacy.sh(对于使用泛型模型的部署)和 deploy-moe-vnet-mlflow-legacy.sh(对于使用 MLflow 模型的部署)。

先决条件

  • 若要使用 Azure 机器学习,必须有一个 Azure 订阅。 如果没有 Azure 订阅,请在开始前创建一个试用版订阅。 立即尝试试用版订阅

  • 安装和配置Azure CLI和 Azure CLI 的ml扩展。 有关详细信息,请参阅安装、设置和使用 CLI (v2)

    提示

    Azure 机器学习托管虚拟网络于 2023 年 5 月 23 日推出。 如果 ml 扩展版本较旧,可能需要进行更新,以顺利完成本文中的示例。 若要更新扩展,请使用以下 Azure CLI 命令:

    az extension update -n ml
    
  • 本文中的 CLI 示例假定你使用的是 Bash(或兼容的)shell。 例如,从 Linux 系统或者适用于 Linux 的 Windows 子系统

  • 必须有一个 Azure 资源组,你(或者你使用的服务主体)在此资源组中需要拥有 Contributor 访问权限。 如果你已配置了 ml 扩展,那么你就会有此类资源组。

  • 如果要使用用户分配的托管标识来创建和管理联机终结点和联机部署,则标识应具有适当的权限。 有关所需权限的详细信息,请参阅设置服务身份验证。 例如,你需要为标识分配对 Azure Key Vault 的适当 RBAC 权限。

从旧式网络隔离方法迁移到工作区托管虚拟网络

如果之前使用了旧方法进行托管联机终结点的网络隔离,并且想要迁移到使用工作区托管虚拟网络来保护终结点,可以执行以下步骤:

  1. 创建新的工作区并启用托管虚拟网络。 有关如何为工作区配置托管网络的详细信息,请参阅工作区托管虚拟网络隔离
  2. (可选)在工作区网络设置中,如果部署需要访问其他专用资源,而不是与工作区(默认添加)关联的存储帐户、Azure Key Vault 和 Azure 容器注册表 (ACR),请添加专用终结点类型的出站规则。
  3. (可选)如果打算使用 Azure 机器学习注册表,请配置专用终结点,以便与注册表、其存储帐户和 Azure 容器注册表进行出站通信。
  4. 在新工作区中创建联机终结点/部署。 可以利用 Azure 机器学习注册表直接从它们进行部署。 有关详细信息,请参阅从注册表部署
  5. 更新调用终结点的应用程序,以使用新联机终结点的评分 URI。
  6. 验证后,从旧工作区中删除联机终结点。

如果不需要在旧工作区中维护计算或保持联机终结点和部署在不停机的情况下提供服务,只需删除现有工作区中的所有计算,并更新工作区以启用工作区托管虚拟网络。

限制

  • 必须在 Azure 机器学习工作区上禁用 v1_legacy_mode 标志 (false)。 如果启用此标志,你将无法创建托管联机终结点。 有关详细信息,请参阅使用 v2 API 配置网络隔离

  • 如果你的 Azure 机器学习工作区具有 2022 年 5 月 24 日之前创建的专用终结点,则必须先重新创建该工作区的专用终结点,然后再将联机终结点配置为使用专用终结点。 有关为工作区创建专用终结点的详细信息,请参阅如何为 Azure 机器学习工作区配置专用终结点

    提示

    若要确认何时创建了工作区,可以检查工作区属性。

    在“工作室”中,转到 Directory + Subscription + Workspace 部分(“工作室”的右上角),然后选择 View all properties in Azure Portal。 从“概述”页的右上角选择 JSON 视图,然后选择最新的 API 版本。 在此页中,可以检查 properties.creationTime 的值。

    或者,将 az ml workspace showCLI 配合使用、将 my_ml_client.workspace.get("my-workspace-name")SDK 配合使用或对工作区将 curlREST API 配合使用。

  • 对联机终结点使用网络隔离时,你可以使用其他资源组(而非你的工作区中的资源组)中的工作区关联资源(Azure 容器注册表 [ACR]、存储帐户、密钥保管库和 Application Insights)。 但这些资源必须属于与工作区相同的订阅和租户。

注意

本文所述网络隔离适用于数据平面操作,即从评分请求(或模型服务)产生的操作。 控制平面操作(如创建、更新或检索身份验证密钥的请求)通过公用网络发送到 Azure 资源管理器。

准备你的系统

  1. 运行以下命令创建此示例使用的环境变量。 将 <YOUR_WORKSPACE_NAME> 替换为要用于你的工作区的名称。 将 <YOUR_RESOURCEGROUP_NAME> 替换为包含你的工作区的资源组。

    提示

    在创建新工作区之前,必须创建一个 Azure 资源组来包含它。 有关详细信息,请参阅管理 Azure 资源组

    export RESOURCEGROUP_NAME="<YOUR_RESOURCEGROUP_NAME>"
    export WORKSPACE_NAME="<YOUR_WORKSPACE_NAME>"
    
  2. 创建工作区。 参数 -m allow_only_approved_outbound 会为工作区配置托管虚拟网络,并阻止出站流量,但发往批准的目标的流量除外。

     az ml workspace create -g $RESOURCEGROUP_NAME -n $WORKSPACE_NAME -m allow_only_approved_outbound
    

    或者,如果你希望允许部署将出站流量发送到 Internet,请取消注释以下代码并改为运行它。

     # az ml workspace create -g $RESOURCEGROUP_NAME -n $WORKSPACE_NAME -m allow_internet_outbound
    

    有关如何创建新工作区或升级现有工作区以使用托管虚拟网络的详细信息,请参阅配置托管虚拟网络以允许 Internet 出站

    使用专用终结点配置工作区时,必须为工作区的 Azure 容器注册表配置为高级层,以允许通过专用终结点进行访问。 有关详细信息,请参阅 Azure 容器注册表服务层级。 此外,应使用 image_build_compute 属性设置工作区,因为部署创建涉及生成映像。 有关详细信息,请参阅配置映像生成

  3. 配置 CLI 的默认值,以避免多次传入工作区和资源组的值。

    az configure --defaults workspace=$WORKSPACE_NAME group=$RESOURCEGROUP_NAME
    
  4. 克隆示例存储库以获取终结点和部署的示例文件,然后转到存储库的 /cli 目录。

    git clone --depth 1 https://github.com/Azure/azureml-examples
    cd /cli
    

本教程中的命令位于 cli 目录中的文件 deploy-managed-online-endpoint-workspacevnet.sh 内,YAML 配置文件位于 endpoints/online/managed/sample/ 子目录中。

创建受保护的托管联机终结点

要创建安全的托管联机终结点,请在工作区中创建终结点,然后将终结点的 public_network_access 设置为 disabled 以控制入站通信。 然后,终结点必须使用工作区的专用终结点进行入站通信。

由于工作区配置为具有托管虚拟网络,因此终结点的任何部署都将使用托管虚拟网络的专用终结点进行出站通信。

  1. 设置终结点的名称。

     export ENDPOINT_NAME="<YOUR_ENDPOINT_NAME>"
    
  2. 创建禁用 public_network_access 的终结点以阻止入站流量。

     az ml online-endpoint create --name $ENDPOINT_NAME -f endpoints/online/managed/sample/endpoint.yml --set public_network_access=disabled
    

    如果禁用终结点的公用网络访问,则调用终结点的唯一方法是使用虚拟网络中可访问工作区的专用终结点。 有关详细信息,请参阅保护入站评分请求为 Azure 机器学习工作区配置专用终结点

    或者,如果你希望允许终结点接收来自 Internet 的评分请求,请取消注释以下代码并改为运行它。

     # az ml online-endpoint create --name $ENDPOINT_NAME -f endpoints/online/managed/sample/endpoint.yml
    
  3. 在工作区托管虚拟网络中创建部署。

     az ml online-deployment create --name blue --endpoint $ENDPOINT_NAME -f endpoints/online/managed/sample/blue-deployment.yml --all-traffic
    
  4. 获取部署的状态。

     az ml online-endpoint show -n $ENDPOINT_NAME
    
  5. 使用 CLI 通过评分请求测试终结点。

     az ml online-endpoint invoke --name $ENDPOINT_NAME --request-file endpoints/online/model-1/sample-request.json
    
  6. 获取部署日志。

     az ml online-deployment get-logs --name blue --endpoint $ENDPOINT_NAME
    
  7. 如果不再需要终结点,请将其删除。

     az ml online-endpoint delete --name $ENDPOINT_NAME --yes --no-wait
    
  8. 删除本文中创建的所有资源。 请将 <resource-group-name> 替换为此示例中使用的资源组名称:

    az group delete --resource-group <resource-group-name>
    

疑难解答

联机终结点创建失败,并显示 V1LegacyMode == true 消息

你可以针对 v1_legacy_mode 对 Azure 机器学习工作区进行配置,这将禁用 v2 API。 托管联机终结点是 v2 API 平台的一项功能,如果为工作区启用 v1_legacy_mode,该功能将无法正常使用。

若要禁用 v1_legacy_mode,请参阅使用 v2 进行网络隔离

重要

在禁用 v1_legacy_mode 之前,请与你的网络安全团队进行确认,因为他们可能出于某种原因启用了它。

使用基于密钥的身份验证创建联机终结点失败

使用以下命令列出工作区的 Azure 密钥保管库的网络规则。 请将 <keyvault-name> 替换为你的密钥保管库名称:

az keyvault network-rule list -n <keyvault-name>

此命令的响应类似于以下 JSON 代码:

{
    "bypass": "AzureServices",
    "defaultAction": "Deny",
    "ipRules": [],
    "virtualNetworkRules": []
}

如果 bypass 的值不是 AzureServices,请使用配置密钥保管库网络设置中的指导将其设置为 AzureServices

联机部署失败并出现映像下载错误

注意

对托管联机终结点使用旧版网络隔离方法时,此问题适用,其中 Azure 机器学习会为终结点下的每个部署创建一个托管虚拟网络。

  1. 检查部署的 egress-public-network-access 标志是否已“disabled”。 如果此标志已启用,并且容器注册表的可见性为“专用”,则预期会发生这种失败。

  2. 使用以下命令检查专用终结点连接的状态。 请将 <registry-name> 替换为你的工作区的 Azure 容器注册表名称:

    az acr private-endpoint-connection list -r <registry-name> --query "[?privateLinkServiceConnectionState.description=='Egress for Microsoft.MachineLearningServices/workspaces/onlineEndpoints'].{Name:name, status:privateLinkServiceConnectionState.status}"
    

    在响应代码中,验证 status 字段是否设置为 Approved。 如果不是,请使用以下命令进行批准。 请将 <private-endpoint-name> 替换为上一个命令返回的名称。

    az network private-endpoint-connection approve -n <private-endpoint-name>
    

无法解析评分终结点

  1. 验证发出评分请求的客户端是否为可以访问 Azure 机器学习工作区的虚拟网络。

  2. 对终结点主机名使用 nslookup 命令来检索 IP 地址信息,例如:

    nslookup endpointname.westcentralus.inference.ml.azure.com
    

    响应中包含地址,该地址应在虚拟网络提供的范围内。

    注意

    • 对于 Kubernetes 联机终结点,终结点主机名应为已在 Kubernetes 群集中指定的 CName(域名)
    • 如果终结点是 HTTP,则 IP 地址将包含在终结点 URI 中,可以从 Studio UI 中获取该 URI。
    • 有关获取终结点 IP 地址的更多方法,请参阅安全 Kubernetes 联机终结点
  3. 如果 nslookup 命令不解析主机名,请执行以下操作:

托管联机终结点

  1. 使用以下命令检查虚拟网络的专用域名服务器 (DNS) 区域中是否存在 A 记录。

    az network private-dns record-set list -z privatelink.api.azureml.ms -o tsv --query [].name
    

    结果应包含类似于 *.<GUID>.inference.<region> 的条目。

    1. 如果无推理值返回,请删除工作区的专用终结点,然后重新创建。 有关详细信息,请参阅如何配置专用终结点
  2. 如果具有专用终结点的工作区使用自定义 DNS 服务器,请运行以下命令来验证自定义 DNS 的解析是否正常工作。

dig endpointname.westcentralus.inference.ml.azure.com

Kubernetes 联机终结点

  1. 请检查 Kubernetes 群集中的 DNS 配置。

  2. 还可以使用以下命令检查 azureml-fe 是否按预期工作:

    kubectl exec -it deploy/azureml-fe -- /bin/bash
    (Run in azureml-fe pod)
    
    curl -vi -k https://localhost:<port>/api/v1/endpoint/<endpoint-name>/swagger.json
    "Swagger not found"
    

    对于 HTTP,请使用以下命令:

     curl https://localhost:<port>/api/v1/endpoint/<endpoint-name>/swagger.json
    "Swagger not found"
    
  3. 如果 curl HTTP 失败或超时,但 HTTP 有效,请检查证书是否有效。

  4. 如果在前面的过程中无法解析为 A 记录,请验证解析是否可以从 Azure DNS (168.63.129.16) 进行。

    dig @168.63.129.16 endpointname.westcentralus.inference.ml.azure.com
    
  5. 如果前面的命令执行成功,则可以排查自定义 DNS 上的专用链接的条件转发器问题。

无法为联机部署评分

  1. 运行以下命令以查看部署是否成功:

    az ml online-deployment show -e <endpointname> -n <deploymentname> --query '{name:name,state:provisioning_state}' 
    

    如果部署成功完成,则 state 的值将是 Succeeded

  2. 如果部署成功,请使用以下命令检查流量是否已分配到部署。 将 <endpointname> 替换为终结点的名称。

    az ml online-endpoint show -n <endpointname>  --query traffic
    

    此命令的响应应会列出分配到部署的流量百分比。

    提示

    如果在请求中使用 azureml-model-deployment 标头将此部署定为目标,则不必执行此步骤。

  3. 如果正确设置了流量分配或部署标头,请使用以下命令获取终结点的日志。 请将 <endpointname> 替换为终结点名称,将 <deploymentname> 替换为部署。

    az ml online-deployment get-logs  -e <endpointname> -n <deploymentname> 
    
  4. 浏览日志,确定在向部署提交请求时运行的评分代码是否有问题。

后续步骤