为 Azure 托管磁盘配置客户管理的密钥

计算平面中的 Azure Databricks 计算工作负荷将临时数据存储在 Azure 托管磁盘上。 默认情况下,将使用 Microsoft 托管的密钥通过服务器端加密对托管磁盘上存储的数据进行静态加密。 本文介绍如何从 Azure 密钥保管库保管库为 Azure Databricks 工作区配置客户管理的密钥以用于托管磁盘加密。 有关使用 Azure 密钥保管库 HSM 中的密钥的说明,请参阅为 Azure 托管磁盘配置 HSM 客户管理的密钥

重要

  • 托管磁盘存储的客户管理的密钥适用于数据磁盘,但不适用于操作系统 (OS) 磁盘。
  • 托管磁盘存储的客户管理的密钥并适用于无服务器计算资源,例如无服务器 SQL 仓库模型服务。 无服务器计算资源使用的磁盘生存期较短,与无服务器工作负载的生命周期相关。 停止或纵向缩减计算资源时,VM 及其存储将被销毁。

要求

步骤 1:创建密钥保管库

可以通过多种方式创建密钥保管库,包括 Azure 门户、Azure CLI、Powershell 以及(可选)使用 ARM 模板。 以下部分介绍了使用 Azure CLI 和 Powershell 进行创建的过程。 如需了解其他方法,请参阅 Microsoft 文档

使用 Azure CLI

  1. 创建 Key Vault:

    az keyvault create --name <keyVaultName> --resource-group <resourceGroupName> --location <location> --sku <sku> --enable-purge-protection
    
  2. 获取保管库 URI:

    az keyvault show --name <key-vault-name>
    

    复制响应中的 vaultUri 值。

使用 PowerShell

创建新的保管库:

$keyVault = New-AzKeyVault -Name <key-vault-name> -ResourceGroupName <resource-group-name> -Location <location> -Sku <sku> -EnablePurgeProtection

获取现有的密钥保管库:

$keyVault = Get-AzKeyVault -VaultName <key-vault-name>

步骤 2:准备密钥

可以使用 Azure 门户、Azure CLI、Powershell 和 ARM 模板(可选)创建密钥或检索存储在 Azure 密钥保管库中的现有密钥。 本部分介绍使用 Azure CLI 和 Powershell 的过程。 如需了解其他方法,请参阅 Azure 密钥文档

使用 Azure CLI

可以创建密钥或检索现有密钥。

创建密钥:

  1. 运行以下命令:

    az keyvault key create \
    --name <key-name> \
    --vault-name <key-vault-name> \
    --protection software
    
  2. 记下输出中的以下值:

    • 密钥保管库名称:你的密钥保管库名称
    • 密钥名称:你的密钥名称
    • 密钥版本:你的密钥版本
    • 密钥保管库资源组:你的密钥保管库的资源组
  3. 获取密钥信息:

    az keyvault key show --vault-name <keyVaultName> --name <keyName>
    

    复制“kid”字段的值,即密钥 ID。

    完整的密钥 ID 格式通常为 https://<key-vault-name>.vault.azure.net/keys/<key-name>/<key-version>。 非公有云中的 Azure 密钥保管库密钥采用不同的格式。

检索现有密钥:

  1. 运行以下命令:

    az keyvault key show --name <key-name> --vault-name <key-vault-name>
    
  2. 记下现有密钥的以下详细信息:

    • 密钥保管库名称:你的密钥保管库名称。
    • 密钥名称:你的密钥名称。
    • 密钥版本:你的密钥版本。
    • 密钥保管库资源组:你的密钥保管库的资源组。
  3. 获取密钥信息:

    az keyvault key show --vault-name <keyVaultName> --name <keyName>
    

    复制“kid”字段的值,即密钥 ID。

    完整的密钥 ID 格式通常为 https://<key-vault-name>.vault.azure.net/keys/<key-name>/<key-version>。 非公有云中的 Azure 密钥保管库密钥采用不同的格式。

  4. 在继续操作之前,请再次运行 az keyvault key show --name <key name> 来确认是否已启用现有密钥。 输出将显示 "enabled": true

使用 PowerShell

  1. 如果打算创建密钥,则可能需要根据创建密钥的方式和时间设置访问策略。 例如,如果最近使用 PowerShell 创建了密钥保管库,则新密钥保管库可能缺少创建密钥所需的访问策略。 以下示例使用参数“EmailAddress”设置访问策略。 有关详细信息,请参阅 Microsoft 关于 Set-AzKeyVaultAccessPolicy 文章

    在新密钥保管库上设置访问策略:

    Set-AzKeyVaultAccessPolicy \
    -VaultName $keyVault.VaultName \
    -PermissionsToKeys all \
    -EmailAddress <email-address>
    
  2. 可以创建密钥或检索现有密钥:

    • 创建密钥:

      $key = Add-AzKeyVaultKey \
      -VaultName $keyVault.VaultName \
      -Name <key-name> \
      -Destination 'Software'
      
    • 检索现有密钥:

      $key = Get-AzKeyVaultKey \
      -VaultName $keyVault.VaultName \
      -Name <key-name>
      

步骤 3:停止所有计算资源

终止工作区中的所有计算资源(群集、池和 SQL 仓库)。

步骤 4:创建或更新工作区

若要使用托管磁盘的客户管理的密钥创建或更新工作区,请选择以下部署策略之一:

使用 Azure 门户(无模板)

本部分介绍如何在不使用模板的情况下,通过 Azure 门户中的使用托管磁盘的客户管理的密钥创建或更新工作区。

  1. 开始创建或更新工作区:

    使用密钥创建新工作区:

    1. 转到 Azure 门户主页,然后单击页面左上角的“创建资源”。
    2. 在搜索栏中键入 Azure Databricks,然后单击“Azure Databricks”。
    3. 在“Azure Databricks”小组件中选择“创建”。
    4. 在“基本信息”和“网络”选项卡上的窗体字段中输入值。
    5. 在“加密”选项卡中,选中“托管磁盘”部分中的“使用自己的密钥”复选框。

    初次向现有工作区添加密钥:

    1. 转到 Azure 门户的 Azure Databricks 主页
    2. 导航到现有的 Azure Databricks 工作区。
    3. 在左侧面板中打开“加密”选项卡。
    4. 在“客户管理的密钥”部分下,启用“托管磁盘”。
  2. 设置加密字段。

    显示“Azure Databricks”边栏选项卡的“托管磁盘”部分中的字段

    • 在“密钥标识符”字段中,粘贴你的 Azure 密钥保管库密钥的密钥标识符。
    • 在“订阅”下拉列表中,输入你的 Azure 密钥保管库密钥的订阅名称。
    • 若要启用密钥自动轮换,请启用“启用密钥自动轮换”。
  3. 填写剩余的选项卡,然后单击“查看 + 创建”(若要新建工作区)或“保存”(若要更新工作区)。

  4. 部署工作区后,导航到新的 Azure Databricks 工作区。

  5. 在 Azure Databricks 工作区的“概述”选项卡中,单击“托管资源组”。

  6. 在托管资源组的“概述”选项卡中,查找在此资源组中创建的“磁盘加密集”类型的对象。 复制磁盘加密集的名称。

  7. 在 Azure 门户中,转到配置此功能使用的密钥时所用的 Azure 密钥保管库。

  8. 在左侧面板中打开“访问策略”选项卡。 打开该选项卡后,单击页面顶部的“创建”。

  9. 在“权限”选项卡中的“密钥权限”部分下,启用“获取”、“解包密钥”和“包装密钥”。

  10. 单击“下一步”。

  11. 在“主体”选项卡上的搜索栏中,输入 Azure Databricks 工作区的托管资源组中的磁盘加密集名称。 选择结果并单击“下一步”。

    输入磁盘加密集的名称并选择结果

  12. 单击“查看 + 创建”选项卡,然后单击“创建”。

使用 Azure CLI(无模板)

对于新的和更新的工作区,请将以下参数添加到命令:

  • disk-key-name:密钥的名称
  • disk-key-vault:保管库的名称
  • disk-key-version:密钥版本
  • disk-key-auto-rotation:为密钥启用自动轮换(truefalse)。 这是一个可选字段。 默认为 false

在以下命令中,使用在 <key-vault-uri> 上一步中响应的保管库 URI 值。 此外,在上一步的响应中的值“kid”中可以找到密钥名称和密钥版本这两个值。

  1. 创建或更新工作区:

    • 示例 - 使用以下托管磁盘参数创建工作区:

      az databricks workspace create --name <workspace-name> \
      --resource-group <resource-group-name> \
      --location <location> \
      --sku premium --disk-key-name <key-name> \
      --disk-key-vault <key-vault-uri> \
      --disk-key-version <key-version> \
      --disk-key-auto-rotation <true-or-false>
      
    • 示例 - 使用以下托管磁盘参数更新工作区:

      az databricks workspace update \
      --name <workspace-name> \
      --resource-group <resource-group-name> \
      --disk-key-name <key-name> \
      --disk-key-vault <key-vault-uri> \
      --disk-key-version <key-version> \
      --disk-key-auto-rotation <true-or-false>
      

    在上述任一命令的输出中存在一个 managedDiskIdentity 对象。 保存此对象中属性“principalId”的值。 在之后的步骤中,会将此值用作主体 ID。

  2. 将具有密钥权限的访问策略添加到密钥保管库。 使用前面步骤中的保管库名称和主体 ID:

    az keyvault set-policy \
    --name <key-vault-name> \
    --object-id <principal-id> \
    --key-permissions get wrapKey unwrapKey
    

使用 Powershell(无模板)

对于新的和更新的工作区,请将以下参数添加到命令:

  • location:工作区位置
  • ManagedDiskKeyVaultPropertiesKeyName:密钥名称
  • ManagedDiskKeyVaultPropertiesKeyVaultUri:密钥保管库 URI
  • ManagedDiskKeyVaultPropertiesKeyVersion:密钥版本
  • ManagedDiskRotationToLatestKeyVersionEnabled:为密钥启用自动轮换(truefalse)。 这是一个可选字段。 默认值为 false。
  1. 创建或更新工作区:

    • 示例 - 使用以下托管磁盘参数创建工作区:

      $workspace = New-AzDatabricksWorkspace -Name <workspace-name> \
      -ResourceGroupName <resource-group-name> \
      -location $keyVault.Location \
      -Sku premium \
      -ManagedDiskKeyVaultPropertiesKeyName $key.Name \
      -ManagedDiskKeyVaultPropertiesKeyVaultUri $keyVault.VaultUri \
      -ManagedDiskKeyVaultPropertiesKeyVersion $key.Version -ManagedDiskRotationToLatestKeyVersionEnabled
      
    • 示例 - 使用以下托管磁盘参数更新工作区:

      $workspace = Update-AzDatabricksworkspace -Name <workspace-name> \
      -ResourceGroupName <resource-group-name> \
      -ManagedDiskKeyVaultPropertiesKeyName $key.Name \
      -ManagedDiskKeyVaultPropertiesKeyVaultUri $keyVault.VaultUri \
      -ManagedDiskKeyVaultPropertiesKeyVersion $key.Version -ManagedDiskRotationToLatestKeyVersionEnabled
      
  2. 将具有密钥权限的访问策略添加到密钥保管库:

    Set-AzKeyVaultAccessPolicy -VaultName $keyVault.VaultName \
    -ObjectId $workspace.ManagedDiskIdentityPrincipalId \
    -PermissionsToKeys wrapkey,unwrapkey,get
    

使用 ARM 模板(Azure 门户或 Azure CLI)

可以在 Azure 文档中浏览 Azure 快速入门模板。 有关 ARM 模板部署选项的列表,请参阅 ARM 模板文档

创建工作区时,也会在工作区的托管资源组中创建一个磁盘加密集资源。 该资源具有一个用于访问密钥保管库的系统分配的托管标识。 必须检索磁盘加密集的主体 ID,并向标识授予对你的密钥保管库的 GETWRAPUNWRAP 密钥权限,然后 Azure Databricks 计算才能使用此密钥来加密你的数据。

Databricks 建议在同一模板部署中创建或更新工作区并授予密钥保管库权限。 必须在授予密钥保管库权限之前创建或更新工作区,但存在一种例外情况。 如果更新现有托管磁盘客户管理的密钥工作区以使用新密钥保管库中的新密钥,则必须向现有磁盘加密集授予对新密钥保管库的访问权限,然后使用新的密钥配置更新工作区。

本部分中的示例模板执行以下两项操作:

  • 创建或更新工作区以添加托管磁盘客户管理的密钥设置
  • 向磁盘加密集授予对你的密钥保管库的访问权限

可以使用以下示例 ARM 模板,该模板执行两项操作:

  • 使用托管磁盘客户管理的密钥创建或更新工作区。
  • 创建密钥访问策略。

如果你已使用了某个 ARM 模板,可以将示例模板中的参数、资源和输出合并到现有模板中。

{
   "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
   "contentVersion": "1.0.0.0",
   "parameters": {
       "workspaceName": {
           "type": "string",
           "metadata": {
               "description": "The name of the Azure Databricks workspace to create"
           }
       },
       "pricingTier": {
           "type": "string",
           "defaultValue": "premium",
           "allowedValues": [
               "premium"
           ],
           "metadata": {
               "description": "The pricing tier of workspace"
           }
       },
       "apiVersion": {
           "type": "string",
           "defaultValue": "2023-02-01",
           "allowedValues": [
               "2023-02-01",
               "2022-04-01-preview"
           ],
           "metadata": {
               "description": "The API version to use to create the workspace resources"
           }
       },
       "keyVaultName": {
           "type": "string",
           "metadata": {
               "description": "The Key Vault name used for CMK"
           }
       },
       "keyName": {
           "type": "string",
           "metadata": {
               "description": "The key name used for CMK"
           }
       },
       "keyVersion": {
           "type": "string",
           "metadata": {
               "description": "The key version used for CMK"
           }
       },
       "keyVaultResourceGroupName": {
           "type": "string",
           "metadata": {
               "description": "The resource group name of the Key Vault used for CMK"
           }
       },
       "enableAutoRotation": {
           "type": "bool",
           "defaultValue": false,
           "allowedValues": [
               true,
               false
           ],
           "metadata": {
               "description": "Whether managed disk picks up new key versions automatically"
           }
       }
   },
   "variables": {
       "managedResourceGroupName": "[concat('databricks-rg-', parameters('workspaceName'), '-', uniqueString(parameters('workspaceName'), resourceGroup().id))]"
   },
   "resources": [
       {
           "type": "Microsoft.Databricks/workspaces",
           "name": "[parameters('workspaceName')]",
           "location": "[resourceGroup().location]",
           "apiVersion": "[parameters('apiVersion')]",
           "sku": {
               "name": "[parameters('pricingTier')]"
           },
           "properties": {
               "managedResourceGroupId": "[concat(subscription().id, '/resourceGroups/', variables('managedResourceGroupName'))]",
               "encryption": {
                   "entities": {
                       "managedDisk": {
                           "keySource": "Microsoft.Keyvault",
                           "keyVaultProperties": {
                               "keyVaultUri": "[concat('https://', parameters('keyVaultName'), environment().suffixes.keyvaultDns)]",
                               "keyName": "[parameters('keyName')]",
                               "keyVersion": "[parameters('keyVersion')]"
                           },
                           "rotationToLatestKeyVersionEnabled": "[parameters('enableAutoRotation')]"
                       }
                   }
               }
           }
       },
       {
           "type": "Microsoft.Resources/deployments",
           "apiVersion": "2020-06-01",
           "name": "addAccessPolicy",
           "resourceGroup": "[parameters('keyVaultResourceGroupName')]",
           "dependsOn": [
               "[resourceId('Microsoft.Databricks/workspaces', parameters('workspaceName'))]"
           ],
           "properties": {
               "mode": "Incremental",
               "template": {
                   "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
                   "contentVersion": "0.9.0.0",
                   "resources": [
                       {
                           "type": "Microsoft.KeyVault/vaults/accessPolicies",
                           "apiVersion": "2019-09-01",
                           "name": "[concat(parameters('keyVaultName'), '/add')]",
                           "properties": {
                               "accessPolicies": [
                                   {
                                       "objectId": "[reference(resourceId('Microsoft.Databricks/workspaces', parameters('workspaceName')), '2023-02-01').managedDiskIdentity.principalId]",
                                       "tenantId": "[reference(resourceId('Microsoft.Databricks/workspaces', parameters('workspaceName')), '2023-02-01').managedDiskIdentity.tenantId]",
                                       "permissions": {
                                           "keys": [
                                               "get",
                                               "wrapKey",
                                               "unwrapKey"
                                           ]
                                       }
                                   }
                               ]
                           }
                       }
                   ]
               }
           }
       }
   ],
   "outputs": {
       "workspace": {
           "type": "object",
           "value": "[reference(resourceId('Microsoft.Databricks/workspaces', parameters('workspaceName')))]"
       }
   }
}

将该模板与所需的任何工具(包括 Azure 门户、CLI 或其他工具)配合使用。 包含有关以下模板部署策略的详细信息:

使用 Azure 门户应用 ARM 模板

若要在 Azure 门户中使用 ARM 模板创建或更新工作区,请执行以下操作:

  1. 登录 Azure 门户

  2. 单击“创建资源”,然后单击“模板部署(使用自定义模板进行部署)”。

  3. 在“自定义部署”页上,单击“在编辑器中生成自己的模板”。

  4. 将示例模板的内容粘贴到编辑器中。

    Azure 自定义部署门户的“编辑部署”页

  5. 单击“ 保存”。

  6. 输入参数值。

    若要更新现有工作区,请使用与用于创建工作区相同的参数。 首次添加客户管理的密钥时,请在 resources.properties.encryption.entities.managedDisk 下添加密钥相关的参数,如上面的模板中所示。 若要轮换密钥,请更改部分或全部密钥相关参数。

    重要

    如果你要更新工作区,模板中的资源组名称和工作区名称必须与现有工作区的资源组名称和工作区名称相同。

    Azure 自定义部署门户的“项目详细信息”页

  7. 单击“查看 + 创建”。

  8. 解决所有验证问题,然后单击“创建”。

重要

如果你要轮换密钥,请仅在工作区更新完成之后才删除旧密钥。

使用 Azure CLI 应用 ARM 模板

本部分介绍如何在 Azure CLI 中通过 ARM 模板使用密钥创建或更新工作区。

  1. 检查模板是否包含 resources.properties.encryption.entities.managedDisk 节及其相关参数 keyvaultNamekeyNamekeyVersionkeyVaultResourceGroupName。 如果不存在这些内容,请参阅本部分前面提供的示例模板,并将该节和参数合并到该模板中。

  2. 运行 az deployment group create 命令。 如果资源组名称和工作区名称与现有工作区的资源组名称和工作区名称相同,则此命令会更新现有工作区,而不是创建新工作区。 如果你要更新现有部署,请务必使用先前所用的同一资源组和工作区名称。

    az deployment group create --resource-group <existing-resource-group-name>  \
                               --template-file <file-name>.json \
                               --parameters workspaceName=<workspace-name> \
                                            keyvaultName=<key-vault-name> \
                                            keyName=<key-name> keyVersion=<key-version> \
                                            keyVaultResourceGroupName=<key-vault-resource-group>
    

    重要

    如果你要轮换密钥,只能在工作区更新完成之后删除旧密钥。

步骤 5:确认计算资源使用密钥(可选)

若要确认是否已为工作区启用托管磁盘客户管理的密钥功能,请执行以下操作:

  1. 通过执行以下操作之一来检索 Azure Databricks 工作区详细信息:

    • Azure 门户

      1. Azure 门户中单击“工作区”,然后单击你的工作区名称。
      2. 在工作区页上,单击“JSON 视图”。
      3. 单击等于或高于 2022-04-01-preview 的 API 版本。
    • Azure CLI

      运行以下命令:

      az databricks workspace show --resource-group <resource group name> --name <workspace name>
      

      托管磁盘加密参数位于 properties 下。 例如:

      "properties": {
           "encryption": {
               "entities": {
                   "managedDisk": {
                     "keySource": "Microsoft.Keyvault",
                     "keyVaultProperties": {
                         "keyVaultUri": "<key-vault-uri>",
                         "keyName": "<key-name>",
                         "keyVersion": "<key-version>"
                     },
                     "rotationToLatestKeyVersionEnabled": "<rotation-enabled>"
                 }
            }
        }
      
    • PowerShell

      Get-AzDatabricksWorkspace -Name <workspace-name> -ResourceGroupName <resource-group-name> |
        Select-Object -Property ManagedDiskKeySource,
         ManagedDiskKeyVaultPropertiesKeyVaultUri,
         ManagedServicesKeyVaultPropertiesKeyName,
         ManagedServicesKeyVaultPropertiesKeyVersion,
         ManagedDiskRotationToLatestKeyVersionEnabled
      

      查看输出中返回的属性的值:

      ManagedDiskKeySource                           : Microsoft.Keyvault
      ManagedDiskKeyVaultPropertiesKeyVaultUri       : <key-vault-uri>
      ManagedServicesKeyVaultPropertiesKeyName       : <key-name>
      ManagedServicesKeyVaultPropertiesKeyVersion    : <key-version>
      ManagedDiskRotationToLatestKeyVersionEnabled   : <rotation-enabled>
      
  2. 为工作区创建任何计算资源以用于测试:

    如果计算资源无法成功启动,原因通常是需要为磁盘加密集授予适当的密钥保管库访问权限。

  3. Azure 门户中单击“工作区”,然后单击你的工作区名称。

  4. 在工作区页上,单击你的工作区所在托管资源组的名称。

  5. 在资源组页上的“资源”下,单击某个虚拟机的名称。

  6. 在虚拟机页左侧的“设置”下,单击“磁盘”。

    在磁盘页上的“数据磁盘”下,确认磁盘的“加密”字段包含 SSE with CMK 值。

步骤 6:启动先前已终止的计算资源

  1. 确保工作区更新已完成。 如果只是在模板中更改了密钥,则更新过程通常在 5 分钟内即可完成,否则可能需要更多时间。
  2. 手动启动先前已终止的所有计算资源。

如果任何计算资源无法成功启动,原因通常是需要为磁盘加密集授予密钥保管库访问权限。

稍后轮换密钥

在已有密钥的现有工作区上,有两种类型的密钥轮换:

  • 自动轮换:如果工作区的 rotationToLatestKeyVersionEnabled 设置为 true,则磁盘加密集将检测密钥版本更改并指向最新密钥版本。
  • 手动轮换:可以使用新密钥更新现有托管磁盘客户管理的密钥工作区。 按照上述说明进行操作,就像最初向现有工作区添加密钥一样。

故障排除

群集失败,显示“KeyVaultAccessForbidden

问题:群集无法启动并出现以下错误:

Cloud Provider Launch Failure: KeyVaultAccessForbidden

为在工作区的受管理资源组中创建的磁盘加密集授予对你的密钥保管库的访问权限。 所需的权限:GETWRAPKEYUNWRAPKEY

重新参阅步骤 4:创建或更新工作区的子部分,了解你的部署类型并特别注意具有特定权限的密钥保管库访问策略更新。

缺少密钥参数

问题:缺少托管磁盘客户管理的密钥参数。

确认 ARM 模板为 Microsoft.Databricks/workspaces 资源使用了正确的 API 版本。 托管磁盘客户管理的密钥功能仅适用于 2022-04-01-preview 或更高的 API 版本。 如果使用其他 API 版本,则会创建或更新工作区,但同时会忽略托管磁盘参数。

工作区更新失败,显示“ApplicationUpdateFail

问题:对启用托管磁盘的工作区执行工作区更新或修补操作失败并出现以下错误:

Failed to update application: `<workspace name>`, because patch resource group failure. (Code: ApplicationUpdateFail)

向磁盘加密集授予对你的密钥保管库的访问权限,然后执行工作区更新操作(例如添加标记)。

缺少访问策略

问题是以下错误:

ERROR CODE: BadRequest MESSAGE: Invalid value found at accessPolicies[14].ObjectId: <objectId>

具有上述对象 ID 的访问策略在密钥保管库无效。 必须删除该策略,才能将新的访问策略添加到密钥保管库。

丢失的密钥不可恢复

丢失的密钥不可恢复。 如果你丢失或撤销了密钥并且无法恢复密钥,则 Azure Databricks 计算资源将不再可以正常工作。 工作区的其他功能不受影响。

资源