使用 Unity Catalog 中的 Azure 托管标识访问存储

本文介绍如何使用 Azure 托管标识以 Unity Catalog 用户身份连接到存储容器。

什么是 Azure 托管标识?

可将 Unity Catalog 配置为使用 Azure 托管标识以 Unity Catalog 用户身份访问存储容器。 托管标识为应用程序提供一个标识,可以在连接到支持 Microsoft Entra ID(以前称为 Azure Active Directory)身份验证的资源时使用。

可使用 Unity Catalog 中的托管标识来支持两个主要用例:

  • 作为连接到元存储的托管存储帐户(存储托管表的位置)的标识。
  • 作为连接到其他外部存储帐户的标识(用于基于文件的访问,或用于通过外部表访问现有数据集)。

与使用服务主体配置 Unity Catalog 相比,使用托管标识配置 Unity Catalog 具有以下优势:

为 Unity Catalog 配置托管标识

若要配置与 Unity Catalog 配合使用的托管标识,首先要在 Azure 中为 Azure Databricks 创建一个访问连接器。 默认情况下,访问连接器使用系统分配的托管标识进行部署。 可以选择附加用户分配的托管标识。 然后,向托管标识授予对 Azure Data Lake Storage Gen2 帐户的访问权限,并在创建 Unity Catalog 元存储或存储凭据时使用访问连接器。

要求

创建访问连接器的 Azure 用户或服务主体必须:

  • 是 Azure 资源组的参与者或所有者。

向托管标识授予存储帐户访问权限的 Azure 用户或服务主体必须:

  • 是所有者,或者是在存储帐户中具有用户访问管理员 Azure RBAC 角色的用户。

步骤 1:创建 Azure Databricks 的访问连接器

Azure Databricks 访问连接器是一种第一方 Azure 资源,让你可以将托管标识连接到 Azure Databricks 帐户。

Azure Databricks 的每个访问连接器可以包含一个系统分配的托管标识或一个用户分配的托管标识。 如果要使用多个托管标识,请为每个标识创建一个单独的访问连接器。

使用系统分配的托管标识

  1. 以资源组的参与者或所有者身份登录 Azure 门户。

  2. 单击“+ 创建”或“创建新资源”。

  3. 搜索“Azure Databricks 访问连接器”并选择它。

  4. 单击“创建”。

  5. 在“基本信息”选项卡上,接受、选择或输入以下字段的值:

    • 订阅:这是将在其中创建访问连接器的 Azure 订阅。 默认为当前使用的 Azure 订阅。 它可以是租户中的任何订阅。
    • 资源组:这是要在其中创建访问连接器的 Azure 资源组。
    • 名称:输入表明连接器用途的名称。
    • 区域:这应该与将连接到的存储帐户所在的区域相同。
  6. 单击“查看 + 创建”。

  7. 看到“验证通过”消息后,单击“创建”。

    部署成功后,将使用系统分配的托管标识部署访问连接器。

  8. 部署完成后,单击“转到资源”。

  9. 记下“资源 ID”。

    资源 ID 的格式为:

    /subscriptions/12f34567-8ace-9c10-111c-aea8eba12345c/resourceGroups/<resource-group>/providers/Microsoft.Databricks/accessConnectors/<connector-name>
    

使用用户分配的托管标识

  1. 如果没有用户分配的托管标识,请新建一个并记下其资源 ID。

    请参阅管理用户分配的托管标识

  2. 以资源组的参与者或所有者身份登录 Azure 门户。

    资源组应与要连接的存储帐户位于同一区域。

  3. 搜索“部署自定义模板”并选择它。

  4. 选择“生成自己的模板”并将以下模板粘贴到编辑器中:

    {
     "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
     "contentVersion": "1.0.0.0",
     "parameters": {
         "connectorName": {
             "defaultValue": "testConnector",
             "type": "String",
             "metadata": {
                 "description": "The name of the Azure Databricks Access Connector to create."
             }
         },
         "accessConnectorRegion": {
             "defaultValue": "[resourceGroup().location]",
             "type": "String",
             "metadata": {
                 "description": "Location for the access connector resource."
             }
         },
         "userAssignedManagedIdentiy": {
             "type": "String",
             "metadata": {
                 "description": "The resource Id of the user assigned managed identity."
             }
         }
     },
     "resources": [
         {
             "type": "Microsoft.Databricks/accessConnectors",
             "apiVersion": "2023-05-01",
             "name": "[parameters('connectorName')]",
             "location": "[parameters('accessConnectorRegion')]",
             "identity": {
                 "type": "UserAssigned",
                 "userAssignedIdentities": {
                     "[parameters('userAssignedManagedIdentiy')]": {}
                 }
              }
          }
       ]
    }
    
  5. 在“基本信息”选项卡上,接受、选择或输入以下字段的值:

    • 订阅:要在其中创建访问连接器的 Azure 订阅。 默认为当前使用的 Azure 订阅。 它可以是租户中的任何订阅。
    • 资源组:与要连接到的存储帐户位于同一区域的资源组。
    • 名称:表明连接器用途的名称。
    • 区域:这应该与将连接到的存储帐户所在的区域相同。 如果资源组是在要连接到的存储帐户所在的同一区域中创建的,则你可以选择预先填充的值“[resourceGroup().location]”。
    • 用户分配的托管标识:要使用的用户分配的托管标识的资源 ID。
  6. 单击“查看 + 创建”。

  7. 看到“验证通过”消息后,单击“创建”。

  8. 部署完成后,单击“转到资源”。

  9. 记下“资源 ID”。

    资源 ID 的格式为:

    /subscriptions/12f34567-8ace-9c10-111c-aea8eba12345c/resourceGroups/<resource-group>/providers/Microsoft.Databricks/accessConnectors/<connector-name>
    

步骤 2:授予托管标识对存储帐户的访问权限

若要在此步骤中授予权限,必须在存储帐户上具有所有者或用户访问管理员 Azure RBAC 角色。

  1. 登录到 Azure Data Lake Storage Gen2 帐户。
  2. 转到“访问控制(IAM)”,单击“+ 添加”,然后选择“添加角色分配”。
  3. 选择“存储 Blob 数据参与者”角色并单击“下一步”。
  4. 在“访问权限分配对象”下,选择“托管标识”。
  5. 单击“+选择成员”,然后选择“Azure Databricks 的访问连接器”,或用户分配的托管标识
  6. 搜索连接器名称或用户分配的标识,将其选中,然后单击“查看并分配”。

或者,可以通过授予托管标识对特定容器的访问权限来限制对存储帐户的访问。 按照上述相同的步骤操作,但授予存储帐户的“存储 Blob 委托者角色”和容器的“存储 Blob 数据参与者”角色。

步骤 3:授予托管标识对文件事件的访问权限

授予托管标识对文件事件的访问权限,Azure Databricks 可以订阅云提供商发出的文件事件通知。 这使得文件处理更高效。 若要在此步骤中授予权限,必须在存储帐户上具有所有者或用户访问管理员 Azure RBAC 角色。

  1. 登录到 Azure Data Lake Storage Gen2 帐户。
  2. 转到“访问控制(IAM)”,单击“+ 添加”,然后选择“添加角色分配”。
  3. 选择“存储队列数据参与者”角色并单击“下一步”
  4. 在“访问权限分配对象”下,选择“托管标识”。
  5. 单击“+选择成员”,然后选择“Azure Databricks 的访问连接器”,或用户分配的托管标识
  6. 搜索连接器名称或用户分配的标识,将其选中,然后单击“查看并分配”。

通过此步骤,Azure Databricks 可自动设置文件事件。 如果不向 Azure Databricks 授予访问权限,使其无法代表你配置文件事件,则必须为每个位置手动配置文件事件。 若要授予此步骤中的权限,必须在托管标识和 Azure Data Lake Storage Gen2 帐户所属的资源组上拥有所有者或用户访问管理员 Azure RBAC 角色。

  1. 按照步骤 3:向托管标识授予对文件事件的访问权限的上述步骤,并将存储帐户参与者以及存储队列数据参与者角色分配给托管标识。
  2. 导航到 Azure Data Lake Storage Gen2 帐户位于的 Azure 资源组。
  3. 转到“访问控制(IAM)”,单击“+ 添加”,然后选择“添加角色分配”。
  4. 选择 EventGrid EventSubscription 参与者角色,然后单击“下一步”
  5. 在“访问权限分配对象”下,选择“托管标识”。
  6. 单击“+选择成员”,然后选择“Azure Databricks 的访问连接器”,或用户分配的托管标识
  7. 搜索连接器名称或用户分配的标识,将其选中,然后单击“查看并分配”。

使用托管标识访问 Unity Catalog 根存储帐户

本部分介绍如何在创建 Unity Catalog 元存储时向托管标识授予对根存储帐户的访问权限。

要了解如何升级现有 Unity Catalog 元存储以使用托管标识,请参阅升级现有 Unity Catalog 元存储以使用托管标识访问其根存储

  1. 以 Azure Databricks 帐户管理员身份登录到 Azure Databricks 帐户控制台
  2. 点击Catalog icon目录
  3. 单击“创建元存储”。
  4. 输入以下字段的值:
    • 元存储的名称。

    • 将在其中部署元存储的区域。

      为了获得最佳性能,请将访问连接器、工作区、元存储和云存储位置放在同一云区域中。

    • ADLS Gen 2 路径:输入你将用作元存储根存储的存储容器的路径。

      前缀 abfss:// 会自动添加。

    • 访问连接器 ID:按以下格式输入 Azure Databricks 访问连接器的资源 ID:

      /subscriptions/12f34567-8ace-9c10-111c-aea8eba12345c/resourceGroups/<resource-group>/providers/Microsoft.Databricks/accessConnectors/<connector-name>
      
    • (可选)托管标识 ID:如果你使用用户分配的托管标识创建了访问连接器,请输入托管标识的资源 ID。

  5. 单击“创建”。
  6. 出现提示时,选择工作区以链接到元存储。

使用托管标识访问在 Unity Catalog 中托管的外部存储

Unity Catalog 允许你使用存储凭据和外部位置访问存储帐户中的现有数据。 存储凭据存储托管标识,外部位置定义存储路径和对存储凭据的引用。 可使用此方法授予和控制对云存储中现有数据的访问权限,以及在 Unity Catalog 中注册外部表。

存储凭据可以包含托管标识或服务主体。 使用托管标识的好处是允许 Unity Catalog 访问受网络规则保护的存储帐户(而使用服务主体无法实现此目的),并且无需管理和轮换机密。

要使用托管标识创建存储凭据并将该存储凭据分配给外部位置,请遵循使用 Unity Catalog 连接到云对象存储中的说明。

如果 Azure Databricks 工作区部署在自己的 Azure 虚拟网络中(也称为 “VNet 注入”),并且你使用存储防火墙来保护 Azure Data Lake Storage Gen2 帐户,则必须:

  1. 启用 Azure Databricks 工作区以访问 Azure 存储。
  2. 支持托管标识访问 Azure 存储。

步骤 1. 启用 Azure Databricks 工作区以访问 Azure 存储

必须配置网络设置,以支持 Azure Databricks 工作区访问 Azure Data Lake Storage Gen2。 然后,可以在 Azure Data Lake Storage Gen2 上配置专用终结点或者从虚拟网络访问,以允许从子网连接到 Azure Data Lake Storage Gen2 帐户。

有关说明,请参阅授予 Azure Databricks 工作区对 Azure Data Lake Storage Gen2 的访问权限

步骤 2:支持托管标识访问 Azure 存储

只有在为 Azure 存储帐户禁用了“允许受信任的服务列表中的 Azure 服务访问此存储帐户”时,才需要执行此步骤。 如果启用了该配置,那么:

以下说明包括用于禁用此配置的步骤。 可以使用 Azure 门户或 Azure CLI。

使用 Azure 门户

  1. 登录到 Azure 门户,查找并选择 Azure 存储帐户,然后转到“网络”选项卡。

  2. 将“公共网络访问”设置为“从选定的虚拟网络和 IP 地址启用”。

    作为一种选项,可以改为将“公共网络访问”设置为“已禁用”。 托管标识可用于绕过对公共网络访问的检查。

  3. 在“资源实例”下,选择 Microsoft.Databricks/accessConnectors 的“资源类型”,然后选择 Azure Databricks 访问连接器。

  4. 在“异常”下,清除“允许受信任的服务列表中的 Azure 服务访问此存储帐户”复选框。

使用 Azure CLI

  1. 安装 Azure CLI登录

    若要使用 Microsoft Entra ID 服务主体进行登录,请参阅使用 Microsoft Entra ID 服务主体登录 Azure CLI

    若要使用 Azure Databricks 用户帐户登录,请参阅使用 Azure Databricks 用户帐户登录 Azure CLI

  2. 将网络规则添加到存储帐户:

    az storage account network-rule add \
    --subscription <subscription id of the resource group> \
    --resource-id <resource Id of the access connector for Azure Databricks> \
    --tenant-id <tenant Id> \
    -g <name of the Azure Storage resource group> \
    --account-name <name of the Azure Storage resource> \
    

    按以下格式添加资源 ID:

    /subscriptions/12f34567-8ace-9c10-111c-aea8eba12345c/resourceGroups/<resource-group>/providers/Microsoft.Databricks/accessConnectors/<connector-name>
    
  3. 创建网络规则后,转到 Azure 门户中的 Azure 存储帐户,然后在资源类型为 Microsoft.Databricks/accessConnectors 的“资源实例”下的“网络”选项卡中查看托管标识。

  4. 在“异常”下,清除“允许受信任的服务列表中的 Azure 服务访问此存储帐户”复选框。

  5. (可选)将“公共网络访问”设置为“已禁用”。 托管标识可用于绕过对公共网络访问的检查。

    标准方法是将此值设置为“从选定的虚拟网络和 IP 地址启用”。

升级现有 Unity Catalog 元存储以使用托管标识访问其根存储

如果你具有使用服务主体创建的 Unity Catalog 元存储,并且希望将其升级为使用托管标识,则可以使用 API 调用对其进行更新。

  1. 创建 Azure Databricks 访问连接器,并使用为 Unity Catalog 配置托管标识中的说明向其分配对用于 Unity Catalog 元存储根存储的存储容器的权限。

    可以使用系统分配的托管标识或用户分配的托管标识创建访问连接器。

    记下访问连接器的资源 ID。 如果使用了用户分配的托管标识,也请记下其资源 ID。

  2. 作为帐户管理员,登录到分配给元存储的 Azure Databricks 工作区。

    你不必是工作区管理员。

    记下工作区 URL,它是 URL 的第一部分,位于 https:// 之后,包括 databricks.azure.cn

  3. 生成个人访问令牌

  4. 将个人访问令牌添加到主目录中的 .netrc 文件。 这可以防止在 shell 的命令历史记录中显示个人访问令牌,从而提高安全性。 请参阅令牌管理 API

  5. 运行以下 cURL 命令以重新创建存储凭据。

    替换占位符值替:

    • <databricks-instance>:生成个人访问令牌的工作区的 URL
    • <credential-name>:存储凭据的名称。
    • <access-connector-id>:Azure Databricks 访问连接器的资源 ID,其格式为 /subscriptions/12f34567-8ace-9c10-111c-aea8eba12345c/resourceGroups/<resource-group>/providers/Microsoft.Databricks/accessConnectors/<connector-name>
    • <managed-identity-id>:如果使用用户分配的托管标识创建了访问连接器,请指定托管标识的资源 ID。
    curl -n -X POST --header 'Content-Type: application/json' https://<databricks-instance>/api/2.0/unity-catalog/storage-credentials --data "{
      \"name\": \"<credential-name>\",
      \"azure_managed_identity\": {
        \"access_connector_id\": \"<access-connector-id>\",
        \"managed_identity_id\": \"<managed-identity-id>\"
      }
    }"
    
  6. 记下响应中的存储凭据 ID。

  7. 运行以下 cURL 命令以检索 metastore_id,其中 <databricks-instance> 是生成个人访问令牌的工作区的工作区 URL

    curl -n GET--header 'Content-Type: application/json' https://<databricks-instance>/api/2.0/unity-catalog/metastore_summary
    
  8. 运行以下 cURL 命令,以使用新的根存储凭据更新元存储。

    替换占位符值替:

    • <databricks-instance>:生成个人访问令牌的工作区的 URL
    • <metastore-id>:在上一步中检索到的元存储 ID。
    • <storage-credential-id>:存储凭据 ID。
    curl -n -X PATCH --header 'Content-Type: application/json' https://<databricks-instance>/api/2.0/unity-catalog/metastores/<metastore-id> --data
    "{\"storage_root_credential_id\": \"<storage-credential-id>\"}"