分享方式:


待用資料的 Azure HDInsight 雙重加密

本文討論 Azure HDInsight 叢集中待用資料的加密方法。 待用資料加密是指連結至 HDInsight 叢集虛擬機器的受控磁碟 (資料磁碟、OS 磁碟和暫存磁碟) 上的加密。

本文件未處理 Azure 儲存體帳戶中所儲存的資料。 您的叢集可能有一或多個連結的 Azure 儲存體帳戶,其中加密金鑰也可以由 Microsoft 管理或客戶管理,但加密服務不同。 如需 Azure 儲存體加密的詳細資訊,請參閱待用資料的 Azure 儲存體加密

簡介

Azure 中有三個主要受控磁碟角色:資料磁碟、OS 磁碟和暫存磁碟。 如需不同受控磁碟類型的詳細資訊,請參閱 Azure 受控磁碟簡介

HDInsight 支援兩個不同層中有多種加密類型:

  • 伺服器端加密 (SSE) - SSE 是由儲存體服務所執行。 在 HDInsight 中,SSE 用來加密 OS 磁碟和資料磁碟。 預設會啟用此功能。 SSE 是第 1 層加密服務。
  • 使用平台代控金鑰進行主機加密 - 與 SSE 類似,此加密類型是由儲存體服務所執行。 不過,它僅適用於暫存磁碟,預設不會予以啟用。 主機加密也是第 1 層加密服務。
  • 使用客戶自控金鑰進行待用加密 - 此加密類型可用於資料和暫存磁碟。 預設不會予以啟用,而且需要客戶透過 Azure 金鑰保存庫提供自己的金鑰。 待用加密是第 2 層加密服務。

下表摘要說明這些類型。

叢集類型 OS 磁碟 (受控磁碟) 資料磁碟 (受控磁碟) 暫存資料磁碟 (本機 SSD)
Kafka、具有加速寫入的 HBase 第 1 層: SSE 加密 預設 第 1 層: 依預設為 SSE 加密 ,第 2 層:使用 CMK 選擇性待用加密 第 1 層:使用 PMK 的主機選擇性加密,第 2 層:使用 CMK 選擇性待用加密
所有其他叢集 (Spark、Interactive、Hadoop、沒有加速寫入的 HBase) 第 1 層: SSE 加密 預設 N/A 第 1 層:使用 PMK 的主機選擇性加密,第 2 層:使用 CMK 選擇性待用加密

使用客戶自控金鑰進行待用加密

客戶自控金鑰是可在叢集建立期間免費處理的單步驟程序。 您只需要使用 Azure Key Vault 來授權受控身分識別,並在建立叢集時新增加密金鑰即可。

叢集每個節點上的資料磁碟和暫存磁碟都會使用對稱資料加密金鑰 (DEK) 進行加密。 DEK 會使用金鑰保存庫中的金鑰加密金鑰 (KEK) 來加以保護。 加密和解密程序完全由 Azure HDInsight 來處理。

針對連結至叢集 VM 的 OS 磁碟,只能使用一層加密 (PMK)。 如果客戶的案例需要 CMK 加密,則建議客戶避免將敏感性資料複製至 OS 磁碟。

如果儲存磁碟加密金鑰的金鑰保存庫上啟用金鑰保存庫防火牆,則必須將叢集部署所在區域的 HDInsight 區域資源提供者 IP 位址新增至金鑰保存庫防火牆設定。 這是必要作業,因為 HDInsight 不是受信任的 Azure 金鑰保存庫服務。

您可以使用 Azure 入口網站或 Azure CLI,在金鑰保存庫中安全地輪替金鑰。 金鑰輪替時,HDInsight 叢集會在幾分鐘內開始使用新的金鑰。 啟用虛刪除重要保護功能,以防範勒索軟體案例和意外刪除。 不支援沒有此保護功能的金鑰保存庫。

開始使用客戶管理的金鑰

為了建立已啟用客戶自控金鑰的 HDInsight 叢集,我們將逐步執行下列步驟:

  1. 建立 Azure 資源的受控身分識別
  2. 建立 Azure Key Vault
  3. 建立金鑰
  4. 建立存取原則
  5. 建立已啟用客戶自控金鑰的 HDInsight 叢集
  6. 輪替加密金鑰

下列其中一節會詳細說明每個步驟。

建立 Azure 資源的受控身分識別

建立使用者指派的受控身分識別,以向金鑰保存庫進行驗證。

如需特定步驟,請參閱建立使用者指派的受控身分識別。 如需受控身分識別如何在 Azure HDInsight 中運作的詳細資訊,請參閱 Azure HDInsight 中的受控身分識別。 將受控識別資源識別碼新增至 Key Vault 存取原則時,請務必儲存起來。

建立 Azure Key Vault

建立金鑰保存庫。 如需特定步驟,請參閱建立 Azure Key Vault

HDInsight 僅支援 Azure Key Vault。 如果您有自己的金鑰保存庫,則可以將自己的金鑰匯入 Azure Key Vault 中。 請記住,金鑰保存庫必須啟用「虛刪除」。 如需如何匯入現有金鑰的詳細資訊,請瀏覽關於金鑰、祕密和憑證

建立金鑰

  1. 從新的金鑰保存庫中,導覽至 [設定] > [金鑰] > [+ 產生/匯入]

    在 Azure 金鑰保存庫 中產生新的金鑰。

  2. 提供名稱,然後選取 [建立]。 維護預設 [金鑰類型] [RSA]

    會產生金鑰名稱。

  3. 當您返回 [金鑰] 頁面時,請選取您所建立的金鑰。

    金鑰儲存庫金鑰清單。

  4. 選取版本,以開啟 [金鑰版本] 頁面。 當您使用自己的金鑰進行 HDInsight 叢集加密時,需要提供金鑰 URI。 複製金鑰識別碼並將其儲存到某處,直到您準備好建立叢集為止。

    取得金鑰識別碼。

建立存取原則

  1. 從新的金鑰保存庫中,導覽至 [設定] > [存取原則] > [+ 新增存取原則]

    建立新的 Azure 金鑰保存庫 存取原則。

  2. 從 [新增存取原則] 頁面中,提供下列資訊:

    屬性 說明
    金鑰權限 選取 [取得]、[解除包裝金鑰] 和 [包裝金鑰]
    祕密權限 選取 [取得]、[設定] 和 [刪除]
    選取主體 選取您稍早建立的使用者指派的受控身分識別。

    設定 [選取 Azure 金鑰保存庫 存取原則的主體]。

  3. 選取 [新增]。

  4. 選取儲存

    儲存 Azure 金鑰保存庫 存取原則。

使用客戶自控金鑰磁碟加密來建立叢集

您現在可以開始建立新的 HDInsight 叢集。 客戶自控金鑰只能在叢集建立期間套用至新的叢集。 您無法從客戶自控金鑰叢集中移除加密,也無法將客戶自控金鑰新增至現有叢集。

從 2020 年 11 月發行版本開始,HDInsight 支援使用版本化和無版本金鑰 URI 來建立叢集。 如果您使用無版本金鑰 URI 來建立叢集,則 HDInsight 叢集將會嘗試在 Azure Key Vault 中更新金鑰時執行金鑰自動輪替。 如果您使用版本化金鑰 URI 來建立叢集,則必須執行手動金鑰輪替,如輪替加密金鑰中所討論。

針對在 2020 年 11 月發行版本之前所建立的叢集,您必須使用版本化金鑰 URI 來手動執行金鑰輪替。

支援磁碟加密的 VM 類型

大小 vCPU 記憶體:GiB
Standard_D4a_v4 4 16
Standard_D8a_v4 8 32
Standard_D16a_v4 16 64
Standard_D32a_v4 32 128
Standard_D48a_v4 48 192
Standard_D64a_v4 64 256
Standard_D96a_v4 96 384
標準 E64is_v3 64 432
Standard_E20s_V3 20 160
Standard_E2s_V3 2 16
Standard_E2a_v4 2 16
Standard_E4a_v4 4 32
Standard_E8a_v4 8 64
Standard_E16a_v4 16 128
Standard_E20a_v4 20 160
Standard_E32a_v4 32 256
Standard_E48a_v4 48 384
Standard_E64a_v4 64 512
Standard_E96a_v4 96 672
Standard_DS3_v2 4 14
Standard_DS4_v2 8 28
Standard_DS5_v2 16 56
標準 DS12_v2 4 28
標準 DS13_v2 8 56
標準 DS14_v2 16 112

使用 Azure 入口網站

在叢集建立期間,您可以透過下列方式來使用版本化金鑰或無版本金鑰:

  • 版本化 - 在叢集建立期間,請提供完整「金鑰識別碼」,包括金鑰版本。 例如: https://contoso-kv.vault.azure.net/keys/myClusterKey/46ab702136bc4b229f8b10e8c2997fa4
  • 無版本 - 在叢集建立期間,只提供「金鑰識別碼」。 例如: https://contoso-kv.vault.azure.net/keys/myClusterKey

您也需要將受控身分識別指派給叢集。

建立新的叢集。

使用 Azure CLI

下列範例顯示如何使用 Azure CLI 來建立已啟用磁碟加密的新 Apache Spark 叢集。 如需詳細資訊,請參閱 Azure CLI az hdinsight createencryption-key-version 是選用參數。

az hdinsight create -t spark -g MyResourceGroup -n MyCluster \
-p "HttpPassword1234!" --workernode-data-disks-per-node 2 \
--storage-account MyStorageAccount \
--encryption-key-name SparkClusterKey \
--encryption-key-version 00000000000000000000000000000000 \
--encryption-vault-uri https://MyKeyVault.vault.azure.net \
--assign-identity MyMSI

使用 Azure Resource Manager 範本

下列範例顯示如何使用 Azure Resource Manager 範本來建立已啟用磁碟加密的新 Apache Spark 叢集。 如需相關資訊,請參閱什麼是 ARM 範本?。 Resource Manager 範本屬性 diskEncryptionKeyVersion 是選用項目。

此範例使用 PowerShell 來呼叫範本。

$templateFile = "azuredeploy.json"
$ResourceGroupName = "MyResourceGroup"
$clusterName = "MyCluster"
$password = ConvertTo-SecureString 'HttpPassword1234!' -AsPlainText -Force
$diskEncryptionVaultUri = "https://MyKeyVault.vault.azure.net"
$diskEncryptionKeyName = "SparkClusterKey"
$diskEncryptionKeyVersion = "00000000000000000000000000000000"
$managedIdentityName = "MyMSI"

New-AzResourceGroupDeployment `
  -Name mySpark `
  -TemplateFile $templateFile `
  -ResourceGroupName $ResourceGroupName `
  -clusterName $clusterName `
  -clusterLoginPassword $password `
` -sshPassword $password `
  -diskEncryptionVaultUri $diskEncryptionVaultUri `
  -diskEncryptionKeyName $diskEncryptionKeyName `
  -diskEncryptionKeyVersion $diskEncryptionKeyVersion `
  -managedIdentityName $managedIdentityName

資源管理範本的內容 azuredeploy.json

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "0.9.0.0",
  "parameters": {
    "clusterName": {
      "type": "string",
      "metadata": {
        "description": "The name of the HDInsight cluster to create."
      }
    },
    "clusterLoginUserName": {
      "type": "string",
      "defaultValue": "admin",
      "metadata": {
        "description": "These credentials can be used to submit jobs to the cluster and to log into cluster dashboards."
      }
    },
    "clusterLoginPassword": {
      "type": "securestring",
      "metadata": {
        "description": "The password must be at least 10 characters in length and must contain at least one digit, one non-alphanumeric character, and one upper or lower case letter."
      }
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "The location where all azure resources will be deployed."
      }
    },
    "sshUserName": {
      "type": "string",
      "defaultValue": "sshuser",
      "metadata": {
        "description": "These credentials can be used to remotely access the cluster."
      }
    },
    "sshPassword": {
      "type": "securestring",
      "metadata": {
        "description": "The password must be at least 10 characters in length and must contain at least one digit, one non-alphanumeric character, and one upper or lower case letter."
      }
    },
    "headNodeSize": {
      "type": "string",
      "defaultValue": "Standard_D12_v2",
      "metadata": {
        "description": "The VM size of the head nodes."
      }
    },
    "workerNodeSize": {
      "type": "string",
      "defaultValue": "Standard_D13_v2",
      "metadata": {
        "description": "The VM size of the worker nodes."
      }
    },
    "diskEncryptionVaultUri": {
      "type": "string",
      "metadata": {
        "description": "The Key Vault DNSname."
      }
    },
    "diskEncryptionKeyName": {
      "type": "string",
      "metadata": {
        "description": "The Key Vault key name."
      }
    },
    "diskEncryptionKeyVersion": {
      "type": "string",
      "metadata": {
        "description": "The Key Vault key version for the selected key."
      }
    },
    "managedIdentityName": {
      "type": "string",
      "metadata": {
        "description": "The user-assigned managed identity."
      }
    }
  },
  "variables": {
    "defaultStorageAccount": {
      "name": "[uniqueString(resourceGroup().id)]",
      "type": "Standard_LRS"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "name": "[variables('defaultStorageAccount').name]",
      "location": "[parameters('location')]",
      "apiVersion": "2019-06-01",
      "sku": {
        "name": "[variables('defaultStorageAccount').type]"
      },
      "kind": "Storage",
      "properties": {}
    },
    {
      "apiVersion": "2018-06-01-preview",
      "name": "[parameters('clusterName')]",
      "type": "Microsoft.HDInsight/clusters",
      "location": "[parameters('location')]",
      "properties": {
        "clusterVersion": "3.6",
        "osType": "Linux",
        "tier": "standard",
        "clusterDefinition": {
          "kind": "spark",
          "componentVersion": {
            "Spark": "2.3"
          },
          "configurations": {
            "gateway": {
              "restAuthCredential.isEnabled": true,
              "restAuthCredential.username": "[parameters('clusterLoginUserName')]",
              "restAuthCredential.password": "[parameters('clusterLoginPassword')]"
            }
          }
        },
        "storageProfile": {
          "storageaccounts": [
            {
              "name": "[replace(replace(reference(resourceId('Microsoft.Storage/storageAccounts', variables('defaultStorageAccount').name), '2019-06-01').primaryEndpoints.blob,'https://',''),'/','')]",
              "isDefault": true,
              "container": "[parameters('clusterName')]",
              "key": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('defaultStorageAccount').name), '2019-06-01').keys[0].value]"
            }
          ]
        },
        "computeProfile": {
          "roles": [
            {
              "name": "headnode",
              "minInstanceCount": 1,
              "targetInstanceCount": 2,
              "hardwareProfile": {
                "vmSize": "[parameters('headNodeSize')]"
              },
              "osProfile": {
                "linuxOperatingSystemProfile": {
                  "username": "[parameters('sshUserName')]",
                  "password": "[parameters('sshPassword')]"
                },
              },
            },
            {
              "name": "workernode",
              "targetInstanceCount": 1,
              "hardwareProfile": {
                "vmSize": "[parameters('workerNodeSize')]"
              },
              "osProfile": {
                "linuxOperatingSystemProfile": {
                  "username": "[parameters('sshUserName')]",
                  "password": "[parameters('sshPassword')]"
                },
              },
            }
          ]
        },
        "minSupportedTlsVersion": "1.2",
        "diskEncryptionProperties": {
          "vaultUri": "[parameters('diskEncryptionVaultUri')]",
          "keyName": "[parameters('diskEncryptionKeyName')]",
          "keyVersion": "[parameters('diskEncryptionKeyVersion')]",
          "msiResourceId": "[resourceID('Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('managedIdentityName'))]"
        }
      },
      "identity": {
        "type": "UserAssigned",
        "userAssignedIdentities": {
          "[resourceID('Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('managedIdentityName'))]": {}
        }
      }
    }
  ]
}

輪替加密金鑰

您可以使用 Azure 入口網站 或 Azure CLI 來變更執行中叢集上所使用的加密金鑰。 針對此作業,叢集必須同時存取目前金鑰和預定的新金鑰,否則輪替金鑰作業將會失敗。 針對在 2020 年 11 月發行版本之後所建立的叢集,您可以選擇是否要讓新的金鑰具有版本。 針對在 2020 年 11 月發行版本之前所建立的叢集,您必須在輪替加密金鑰時使用版本化金鑰。

使用 Azure 入口網站

若要輪替金鑰,您需要基底金鑰保存庫 URI。 完成該作業之後,請移至入口網站中的 [HDInsight 叢集屬性] 區段,然後按一下 [磁碟加密金鑰 URL] 下的 [變更金鑰]。 輸入新的金鑰 URL,然後提交以輪替金鑰。

輪替磁碟加密金鑰。

使用 Azure CLI

下列範例顯示如何輪替現有 HDInsight 叢集的磁碟加密金鑰。 如需詳細資訊,請參閱 Azure CLI az hdinsight rotate-disk-encryption-key

az hdinsight rotate-disk-encryption-key \
--encryption-key-name SparkClusterKey \
--encryption-key-version 00000000000000000000000000000000 \
--encryption-vault-uri https://MyKeyVault.vault.azure.net \
--name MyCluster \
--resource-group MyResourceGroup

客戶自控金鑰加密常見問題集

HDInsight 叢集如何存取我的金鑰保存庫?

HDInsight 會使用您與 HDInsight 叢集相關聯的受控身分識別來存取您的 Azure Key Vault 執行個體。 您可以在叢集建立之前或建立期間,建立這個受控識別。 您也需要對受控識別授與權限,使其能夠存取金鑰儲存所在的金鑰保存庫。

此功能是否適用於 HDInsight 上的所有叢集?

客戶自控金鑰加密適用於所有叢集類型,但 Spark 2.1 和 2.2 除外。

我是否可以使用多個金鑰來加密不同的磁碟或資料夾?

否,所有受控磁碟和資源磁碟都是透過相同的金鑰進行加密。

如果叢集無法存取金鑰保存庫或金鑰,則會發生什麼情況?

如果叢集無法存取金鑰,則將會在 Apache Ambari 入口網站中顯示警告。 在此狀態下,「變更金鑰」作業將會失敗。 還原金鑰存取之後,Ambari 警告將會消失,而且可以成功執行金鑰輪替這類作業。

金鑰存取 Ambari 警示。

如果金鑰已刪除,要如何復原叢集?

因為只支援已啟用「虛刪除」的金鑰,所以如果在金鑰保存庫中復原金鑰,則叢集應該就能重新存取金鑰。 若要復原 Azure Key Vault 金鑰,請參閱 Undo-AzKeyVaultKeyRemovalaz-keyvault-key-recover

如果擴大叢集,則新的節點是否將順暢地支援客戶自控金鑰?

是。 叢集在擴大期間需要存取金鑰保存庫中的金鑰。 使用相同的金鑰來加密叢集中的受控磁碟和資源磁碟。

我的位置是否提供客戶自控金鑰?

HDInsight 客戶自控金鑰適用於所有公用雲端和國家雲端。

使用平台代控金鑰進行主機加密

在 Azure 入口網站中啟用

在 Azure 入口網站建立叢集期間,可以啟用主機加密。

注意

啟用主機加密時,您無法將應用程式從 Azure 市集新增至 HDInsight 叢集。

在主機啟用加密。

此選項會使用 PMK 來啟用 HDInsight VM 暫存資料磁碟的主機加密。 只有有限區域中的特定 VM SKU 才支援主機加密,而 HDInsight 支援下列節點設定和 SKU

若要了解 HDInsight 叢集的正確 VM 大小,請參閱為 Azure HDInsight 叢集選取正確的 VM 大小。 啟用主機加密時的 Zookeeper 節點預設 VM SKU 將會是 DS2V2。

使用 PowerShell 啟用

下列程式碼片段顯示如何建立新的 Azure HDInsight 叢集,而此叢集已使用 PowerShell 啟用主機加密。 其使用 -EncryptionAtHost $true 參數來啟用此功能。

$storageAccountResourceGroupName = "Group"
$storageAccountName = "yourstorageacct001"
$storageAccountKey = Get-AzStorageAccountKey `
    -ResourceGroupName $storageAccountResourceGroupName `
    -Name $storageAccountName | %{ $_.Key1 }
$storageContainer = "container002"
# Cluster configuration info
$location = "East US 2"
$clusterResourceGroupName = "Group"
$clusterName = "your-hadoop-002"
$clusterCreds = Get-Credential
# If the cluster's resource group doesn't exist yet, run:
# New-AzResourceGroup -Name $clusterResourceGroupName -Location $location
# Create the cluster
New-AzHDInsightCluster `
    -ClusterType Hadoop `
    -ClusterSizeInNodes 4 `
    -ResourceGroupName $clusterResourceGroupName `
    -ClusterName $clusterName `
    -HttpCredential $clusterCreds `
    -Location $location `
    -DefaultStorageAccountName "$storageAccountName.blob.core.contoso.net" `
    -DefaultStorageAccountKey $storageAccountKey `
    -DefaultStorageContainer $storageContainer `
    -SshCredential $clusterCreds `
    -EncryptionAtHost $true `

啟用使用 Azure CLI

下列程式碼片段顯示如何建立新的 Azure HDInsight 叢集,而此叢集已使用 Azure CLI 啟用主機加密。 其使用 --encryption-at-host true 參數來啟用此功能。

az hdinsight create -t spark -g MyResourceGroup -n MyCluster \\
-p "yourpass" \\
--storage-account MyStorageAccount --encryption-at-host true

下一步