你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

将密钥管理服务 (KMS) etcd 加密添加到 Azure Kubernetes 服务 (AKS) 群集

本文介绍如何使用 Azure Key Vault 和 AKS 上的密钥管理服务 (KMS) 插件为公钥或私钥保管库启用静态加密。 可以使用 KMS 插件执行以下操作:

  • 使用密钥保管库中的密钥进行 etcd 加密。
  • 自带密钥。
  • 为存储在 etcd 中的机密提供静态加密。
  • 轮换密钥保管库中的密钥。

有关使用 KMS 的详细信息,请参阅使用 KMS 提供程序进行数据加密

先决条件

  • 具有活动订阅的 Azure 帐户。 免费创建帐户
  • Azure CLI 2.39.0 或更高版本。 使用 az --version 命令查找版本。 如需进行安装或升级,请参阅安装 Azure CLI

警告

从 2024 年 9 月 15 日起,新订阅或以前未使用此配置的订阅的私钥保管库不再支持 Konnectivity。 对于当前使用此配置或在过去 60 天内使用过它的订阅,支持将继续,直到 AKS 版本 1.30 停止社区支持。

KMS 支持用于公钥保管库的 Konnectivity 或 API 服务器 VNET 集成

KMS 支持用于私钥和公钥保管库的 API 服务器 VNet 集成

可以使用 kubectl get pods -n kube-system 来验证结果并显示 konnectivity-agent Pod 正在运行。 如果 Pod 正在运行,则表示 AKS 群集正在使用 Konnectivity。 使用 API 服务器 VNet 集成时,可以运行 az aks show --resource-group <resource-group-name> --name <cluster-name> 命令来验证 enableVnetIntegration 设置是否设置为 true

限制

将 KMS etcd 加密与 AKS 集成时存在以下限制:

  • 不支持删除密钥、密钥保管库或关联的标识。
  • KMS etcd 加密不适用于系统分配的托管标识。 在启用该功能之前,必须设置密钥保管库访问策略。 在创建群集之前,系统分配的托管标识不可用。 请考虑循环依赖项。
  • 不支持使用防火墙设置“允许从特定虚拟网络和 IP 地址进行公共访问”或“禁用公共访问”的 Azure Key Vault,因为它会阻止从 KMS 插件到密钥保管库的流量。
  • 启用了 KMS 的群集支持的最大机密数为 2,000。 但是,请务必注意,KMS v2 不受此限制的限制,它可以处理更多机密。
  • 不支持来自其他租户的自带 (BYO) Azure 密钥保管库。
  • 启用 KMS 后,无法更改关联的密钥保管库模式(公共模式与专用模式)。 若要更新密钥保管库模式,必须先禁用 KMS,然后再次启用它。
  • 如果群集已启用 KMS 并且具有私钥保管库,则必须使用 API 服务器 VNet 集成隧道。 不支持 Konnectivity。
  • 使用 Microsoft Azure 虚拟机规模集 API 将群集中的节点纵向缩减为零会解除分配节点。 然后,群集将出现故障并变得不可恢复。
  • 关闭 KMS 后,无法删除或过期密钥。 此类行为会导致 API 服务器停止工作。

为公共密钥保管库创建密钥保管库和密钥

以下部分介绍如何为公共密钥保管库启用 KMS。 可以在使用或不使用 Azure 基于角色的访问控制(Azure RBAC)的情况下使用公钥保管库。

警告

不支持删除密钥或密钥保管库,导致群集中的机密无法恢复。

如果需要恢复密钥保管库或密钥,请参阅使用软删除和清除保护进行 Azure Key Vault 恢复管理

  1. 使用 [az keyvault create][azure-keyvault-create] 命令通过 Azure RBAC 创建密钥保管库。 此示例命令还会将密钥保管库资源 ID 导出到环境变量。

    export KEY_VAULT_RESOURCE_ID=$(az keyvault create --name $KEY_VAULT --resource-group $RESOURCE_GROUP  --enable-rbac-authorization true --query id -o tsv)
    
  2. 使用 [az role assignment create][azure-role-assignment-create] 命令为自己分配创建密钥的权限。 此示例将 Key Vault Crypto Officer 角色分配给已登录用户。

    az role assignment create --role "Key Vault Crypto Officer" --assignee-object-id $(az ad signed-in-user show --query id -o tsv) --assignee-principal-type "User" --scope $KEY_VAULT_RESOURCE_ID
    
  3. 使用 [az keyvault key create][azure-keyvault-key-create] 命令创建密钥。

    az keyvault key create --name $KEY_NAME --vault-name $KEY_VAULT
    
  4. 获取密钥 ID,并使用 [az keyvault key show][azure-keyvault-key-show] 命令将其另存为环境变量。

    export KEY_ID=$(az keyvault key show --name $KEY_NAME --vault-name $KEY_VAULT --query 'key.kid' -o tsv)
    echo $KEY_ID
    

为公共密钥保管库创建用户分配的托管标识

  1. 使用 [az identity create][azure-identity-create] 命令创建用户分配的托管标识。

    az identity create --name $IDENTITY_NAME --resource-group $RESOURCE_GROUP
    
  2. 获取标识对象 ID,并使用 [az identity show][azure-identity-show] 命令将其另存为环境变量。

    export IDENTITY_OBJECT_ID=$(az identity show --name $IDENTITY_NAME --resource-group $RESOURCE_GROUP --query 'principalId' -o tsv)
    echo $IDENTITY_OBJECT_ID
    
  3. 获取标识资源 ID,并使用 [az identity show][azure-identity-show] 命令将其另存为环境变量。

    export IDENTITY_RESOURCE_ID=$(az identity show --name $IDENTITY_NAME --resource-group $RESOURCE_GROUP --query 'id' -o tsv)
    echo $IDENTITY_RESOURCE_ID
    

分配用于解密和加密公共密钥保管库的权限

以下部分介绍如何使用或不使用 Azure RBAC 分配公钥保管库的解密和加密权限。

  • 分配 Key Vault Crypto User 角色,以使用 [az role assignment create][azure-role-assignment-create] 命令授予解密和加密权限。

    az role assignment create --role "Key Vault Crypto User" --assignee-object-id $IDENTITY_OBJECT_ID --assignee-principal-type "ServicePrincipal" --scope $KEY_VAULT_RESOURCE_ID
    

为 AKS 群集上的公钥保管库启用 KMS

以下部分介绍如何在新的或现有的 AKS 群集上为公钥保管库启用 KMS。

使用公钥保管库和 KMS 创建 AKS 群集

  • 使用 az aks create 命令和参数 --enable-azure-keyvault-kms--azure-keyvault-kms-key-vault-network-access--azure-keyvault-kms-key-id 创建一个包含公钥库和 KMS 的 AKS 集群。

    az aks create \
        --name $CLUSTER_NAME \
        --resource-group $RESOURCE_GROUP \
        --assign-identity $IDENTITY_RESOURCE_ID \
        --enable-azure-keyvault-kms \
        --azure-keyvault-kms-key-vault-network-access "Public" \
        --azure-keyvault-kms-key-id $KEY_ID \
        --generate-ssh-keys
    

在现有 AKS 群集上启用公钥保管库和 KMS

  1. 使用az aks update命令和--enable-azure-keyvault-kms--azure-keyvault-kms-key-vault-network-access--azure-keyvault-kms-key-id参数在现有群集上的公钥保管库上启用 KMS。

    az aks update \
        --name $CLUSTER_NAME \
        --resource-group $RESOURCE_GROUP \
        --enable-azure-keyvault-kms \
        --azure-keyvault-kms-key-vault-network-access "Public" \
        --azure-keyvault-kms-key-id $KEY_ID
    
  2. 使用 kubectl get secrets 命令更新所有机密,以确保之前创建的机密不再加密。 对于较大的群集,可能需要按命名空间细分机密或创建更新脚本。 如果上一个更新 KMS 命令失败,仍运行以下命令以避免 KMS 插件出现意外状态。

    kubectl get secrets --all-namespaces -o json | kubectl replace -f -
    

轮换公共密钥保管库中的现有密钥

更改密钥 ID(包括更改密钥名称或密钥版本)后,可以轮换公钥保管库中的现有密钥。

警告

请记住在密钥轮换后更新所有机密。 如果未更新所有机密,则如果之前创建的密钥不存在或不再有效,则无法访问这些机密。

KMS 同时使用两个密钥。 第一次密钥轮换后,需要确保旧密钥和新密钥在下次密钥轮换之前有效(未过期)。 第二个密钥轮换后,可以安全地删除/过期最早的密钥。

使用新的 keyId 轮换 KMS 密钥版本后,请检查 AKS 资源 json 中的 securityProfile.azureKeyVaultKms.keyId。 确保使用新的密钥版本。

  1. 使用az aks update命令和--enable-azure-keyvault-kms--azure-keyvault-kms-key-vault-network-access--azure-keyvault-kms-key-id参数轮换现有密钥。

    az aks update \
        --name $CLUSTER_NAME \
        --resource-group $RESOURCE_GROUP \
        --enable-azure-keyvault-kms \
        --azure-keyvault-kms-key-vault-network-access "Public" \
        --azure-keyvault-kms-key-id $NEW_KEY_ID
    
  2. 使用 kubectl get secrets 命令更新所有机密,以确保之前创建的机密不再加密。 对于较大的群集,可能需要按命名空间细分机密或创建更新脚本。 如果上一个更新 KMS 命令失败,仍运行以下命令以避免 KMS 插件出现意外状态。

    kubectl get secrets --all-namespaces -o json | kubectl replace -f -
    

为私钥保管库创建密钥保管库和密钥

如果已为专用密钥保管库启用 KMS,则 AKS 会自动在节点资源组中创建专用终结点和专用链接。 密钥保管库通过专用端点与 AKS 群集连接。

警告

使用私钥保管库时,请记住以下信息:

  1. 使用带参数的 [az keyvault create][azure-keyvault-create] 命令 --public-network-access Disabled 创建私钥保管库。

    az keyvault create --name $KEY_VAULT --resource-group $RESOURCE_GROUP --public-network-access Disabled
    
  2. 使用 [az keyvault key create][azure-keyvault-key-create] 命令创建密钥。

    az keyvault key create --name $KEY_NAME --vault-name $KEY_VAULT
    

为专用密钥保管库创建用户分配的托管标识

  1. 使用 [az identity create][azure-identity-create] 命令创建用户分配的托管标识。

    az identity create --name $IDENTITY_NAME --resource-group $RESOURCE_GROUP
    
  2. 获取标识对象 ID,并使用 [az identity show][azure-identity-show] 命令将其另存为环境变量。

    export IDENTITY_OBJECT_ID=$(az identity show --name $IDENTITY_NAME --resource-group $RESOURCE_GROUP --query 'principalId' -o tsv)
    echo $IDENTITY_OBJECT_ID
    
  3. 获取标识资源 ID,并使用 [az identity show][azure-identity-show] 命令将其另存为环境变量。

    export IDENTITY_RESOURCE_ID=$(az identity show --name $IDENTITY_NAME --resource-group $RESOURCE_GROUP --query 'id' -o tsv)
    echo $IDENTITY_RESOURCE_ID
    

分配用于解密和加密专用密钥保管库的权限

以下部分介绍如何使用或不使用 Azure RBAC 分配私钥保管库的解密和加密权限。

  • 分配 Key Vault Crypto User 角色,以使用 [az role assignment create][azure-role-assignment-create] 命令授予解密和加密权限。

    az role assignment create --role "Key Vault Crypto User" --assignee-object-id $IDENTITY_OBJECT_ID --assignee-principal-type "ServicePrincipal" --scope $KEY_VAULT_RESOURCE_ID
    

对于专用密钥保管库,需要密钥保管库参与者角色才能在专用密钥保管库和群集之间创建专用链接。

  • 使用 [az role assignment create][azure-role-assignment-create] 命令分配 Key Vault 参与者角色。

    az role assignment create --role "Key Vault Contributor" --assignee-object-id $IDENTITY_OBJECT_ID --assignee-principal-type "ServicePrincipal" --scope $KEY_VAULT_RESOURCE_ID
    

为 AKS 群集上的私钥保管库启用 KMS

以下部分介绍如何在新的或现有的 AKS 群集上为私钥保管库启用 KMS。

使用私钥保管库和 KMS 创建 AKS 群集

  • 使用az aks create命令和--enable-azure-keyvault-kms--azure-keyvault-kms-key-id--azure-keyvault-kms-key-vault-network-access--azure-keyvault-kms-key-vault-resource-id参数创建一个包含私钥保管库和 KMS 的 AKS 群集。

    az aks create \
        --name $CLUSTER_NAME \
        --resource-group $RESOURCE_GROUP \
        --assign-identity $IDENTITY_RESOURCE_ID \
        --enable-azure-keyvault-kms \
        --azure-keyvault-kms-key-id $KEY_ID \
        --azure-keyvault-kms-key-vault-network-access "Private" \
        --azure-keyvault-kms-key-vault-resource-id $KEY_VAULT_RESOURCE_ID \
        --generate-ssh-keys
    

更新现有的 AKS 群集以启用专用密钥保管库的 KMS etcd 加密

  1. 使用az aks update命令和--enable-azure-keyvault-kms--azure-keyvault-kms-key-id--azure-keyvault-kms-key-vault-network-access--azure-keyvault-kms-key-vault-resource-id参数在现有群集上的私钥保管库上启用 KMS。

    az aks update \
        --name $CLUSTER_NAME \
        --resource-group $RESOURCE_GROUP \
        --enable-azure-keyvault-kms \
        --azure-keyvault-kms-key-id $KEY_ID \
        --azure-keyvault-kms-key-vault-network-access "Private" \
        --azure-keyvault-kms-key-vault-resource-id $KEY_VAULT_RESOURCE_ID
    
  2. 使用 kubectl get secrets 命令更新所有机密,以确保之前创建的机密不再加密。 对于较大的群集,可能需要按命名空间细分机密或创建更新脚本。 如果上一个更新 KMS 命令失败,仍运行以下命令以避免 KMS 插件出现意外状态。

    kubectl get secrets --all-namespaces -o json | kubectl replace -f -
    

在私有密钥库中轮换现有密钥

更改密钥 ID(包括更改密钥名称或密钥版本)后,可以轮换私钥保管库中的现有密钥。

警告

请记住在密钥轮换后更新所有机密。 如果未更新所有机密,则如果之前创建的密钥不存在或不再有效,则无法访问这些机密。

轮换密钥后,仍会缓存上一个密钥 (key1),不应删除它。 如果要立即删除上一个密钥 (key1),则需要轮换密钥两次。 然后缓存 key2 和 key3,并且可以删除 key1,而不会影响现有群集。

使用新的 keyId 轮换 KMS 密钥版本后,请检查 AKS 资源 json 中的 securityProfile.azureKeyVaultKms.keyId。 确保使用新的密钥版本。

  1. 使用az aks update命令和--enable-azure-keyvault-kms--azure-keyvault-kms-key-id--azure-keyvault-kms-key-vault-network-access--azure-keyvault-kms-key-vault-resource-id参数轮换私钥保管库中的现有密钥。

    az aks update \
        --name $CLUSTER_NAME \
        --resource-group $RESOURCE_GROUP  \
        --enable-azure-keyvault-kms \
        --azure-keyvault-kms-key-id $NEW_KEY_ID \
        --azure-keyvault-kms-key-vault-network-access "Private" \
        --azure-keyvault-kms-key-vault-resource-id $KEY_VAULT_RESOURCE_ID
    
  2. 使用 kubectl get secrets 命令更新所有机密,以确保之前创建的机密不再加密。 对于较大的群集,可能需要按命名空间细分机密或创建更新脚本。 如果上一个更新 KMS 命令失败,仍运行以下命令以避免 KMS 插件出现意外状态。

    kubectl get secrets --all-namespaces -o json | kubectl replace -f -
    

在 AKS 群集上禁用 KMS

  1. 在关闭 KMS 之前,请使用 [az aks list][az-aks-list] 命令验证群集上是否启用了 KMS。

    az aks list --query "[].{Name:name, KmsEnabled:securityProfile.azureKeyVaultKms.enabled, KeyId:securityProfile.azureKeyVaultKms.keyId}" -o table
    
  2. 确认后,可以使用带参数的az aks update--disable-azure-keyvault-kms命令禁用 KMS。

    az aks update --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --disable-azure-keyvault-kms
    
  3. 使用 kubectl get secrets 命令更新所有机密,以确保之前创建的机密不再加密。 对于较大的群集,可能需要按命名空间细分机密或创建更新脚本。 如果上一个更新 KMS 命令失败,仍运行以下命令以避免 KMS 插件出现意外状态。

    kubectl get secrets --all-namespaces -o json | kubectl replace -f -
    

后续步骤

有关将 KMS 与 AKS 配合使用的详细信息,请参阅以下文章: