你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
使用机密容器和默认策略部署 AKS 群集
本文使用 Azure CLI 部署 Azure Kubernetes 服务 (AKS) 群集,并使用默认安全策略配置机密容器(预览版)。 然后可以将应用程序部署为机密容器。 若要了解详细信息,请参阅 AKS 机密容器概述。
通常,AKS 机密容器入门涉及以下步骤。
- 使用 Azure CLI 部署或升级 AKS 群集
- 将批注添加到 Pod YAML 清单,以将 Pod 标记为作为机密容器运行
- 将安全策略添加到 Pod YAML 清单
- 启用安全策略的强制实施
- 在机密计算中部署应用程序
先决条件
Azure CLI 版本 2.44.1 或更高版本。 可通过运行
az --version
查找版本,运行az upgrade
升级版本。 如果需要进行安装或升级,请参阅安装 Azure CLI。aks-preview
Azure CLI 扩展版本 0.5.169 或更高版本。confcom
机密容器 Azure CLI 扩展 0.3.3 或更高版本。 生成安全策略需要confcom
。在 Azure 订阅中注册
Preview
功能。AKS 支持版本 1.25.0 及更高版本的机密容器(预览版)。
工作负载标识和联合标识凭据。 使用工作负载标识凭据,Kubernetes 应用程序可以使用基于带注释的服务帐户通过 Microsoft Entra ID 安全地访问 Azure 资源。 如果不熟悉 Microsoft Entra 工作负载 ID,请参阅 Microsoft Entra 工作负载 ID 概述并查看工作负载标识如何与 AKS 配合使用。
用于创建群集的标识具有合适的的最低权限。 有关 AKS 的访问和标识的详细信息,请参阅 Azure Kubernetes 服务 (AKS) 的访问和标识选项。
若要管理 Kubernetes 群集,请使用 Kubernetes 命令行客户端 kubectl。 Azure Cloud Shell 随附
kubectl
。 可以使用 az aks install-cli 命令在本地安装 kubectl。AKS 上的机密容器提供用于证明和安全密钥发布的挎斗开放源代码容器。 该挎斗与 Azure Key Vault 等密钥管理服务 (KMS) 集成,以便在验证完成后将密钥发布到容器组。 部署 Azure Key Vault 托管 HSM(硬件安全模块)是可选的,但建议支持容器级完整性和证明。 请参阅预配和激活托管 HSM 以部署托管 HSM。
安装 aks-preview Azure CLI 扩展
重要
AKS 预览功能是可选择启用的自助功能。 预览功能是“按现状”和“按可用”提供的,不包括在服务级别协议和有限保证中。 AKS 预览功能是由客户支持尽最大努力部分覆盖。 因此,这些功能并不适合用于生产。 有关详细信息,请参阅以下支持文章:
若要安装 aks-preview 扩展,请运行以下命令:
az extension add --name aks-preview
运行以下命令以更新到已发布的最新扩展版本:
az extension update --name aks-preview
安装 confcom Azure CLI 扩展
若要安装 confcom 扩展,请运行以下命令:
az extension add --name confcom
运行以下命令以更新到已发布的最新扩展版本:
az extension update --name confcom
注册 KataCcIsolationPreview 功能标志
使用 KataCcIsolationPreview
命令注册 KataCcIsolationPreview
功能标志,如以下示例所示:
az feature register --namespace "Microsoft.ContainerService" --name "KataCcIsolationPreview"
状态显示为“已注册”需要几分钟时间。 使用 az feature show 命令验证注册状态:
az feature show --namespace "Microsoft.ContainerService" --name "KataCcIsolationPreview"
当状态反映为“已注册”时,使用 az provider register 命令刷新 Microsoft.ContainerService 资源提供程序的注册:
az provider register --namespace "Microsoft.ContainerService"
部署一个新群集
使用 az aks create 命令并指定以下参数创建 AKS 群集:
- --os-sku:AzureLinux。 在此预览版本中,只有 Azure Linux os-sku 支持此功能。
- --node-vm-size:属于第 2 代 VM 并支持嵌套虚拟化的任何 Azure VM 大小都有效。 例如 Standard_DC8as_cc_v5 VM。
- --enable-workload-identity:启用创建 Microsoft Entra 工作负载 ID,使 Pod 能够使用 Kubernetes 标识。
- --enable-oidc-issuer:启用 OpenID Connect (OIDC) 证书颁发者。 它允许 Microsoft Entra ID 或其他云提供商标识和访问管理平台发现 API 服务器的公钥签名密钥。
以下示例更新名为 myAKSCluster 的群集,并在 myResourceGroup 中创建单个系统节点池:
az aks create --resource-group myResourceGroup --name myAKSCluster --kubernetes-version <1.25.0 and above> --os-sku AzureLinux --node-vm-size Standard_DC4as_cc_v5 --node-count 1 --enable-oidc-issuer --enable-workload-identity --generate-ssh-keys
片刻之后,该命令将会完成,并返回有关群集的 JSON 格式信息。 在上一步骤中创建的群集包含单个节点池。 在下一步中,我们将第二个节点池添加到群集。
群集准备就绪后,使用 az aks get-credentials 命令获取群集凭据。
az aks get-credentials --resource-group myResourceGroup --name myAKSCluster
使用 az aks nodepool add 命令将用户节点池添加到在 myResourceGroup 的 nodepool2 中有两个节点的 myAKSCluster。 指定下列参数:
- --workload-runtime:指定 KataCcIsolation 以在节点池上启用机密容器功能。 使用此参数时,这些其他参数应满足以下要求。 否则,该命令将失败,并报告相应参数的问题。
- --os-sku:AzureLinux。 在此预览版本中,只有 Azure Linux os-sku 支持此功能。
- --node-vm-size:属于第 2 代 VM 并支持嵌套虚拟化的任何 Azure VM 大小都有效。 例如 Standard_DC8as_cc_v5 VM。
az aks nodepool add --resource-group myResourceGroup --name nodepool2 --cluster-name myAKSCluster --node-count 2 --os-sku AzureLinux --node-vm-size Standard_DC4as_cc_v5 --workload-runtime KataCcIsolation
片刻之后,该命令将会完成,并返回有关群集的 JSON 格式信息。
部署到现有群集
若要将此功能用于现有 AKS 群集,必须满足以下要求:
- 按照步骤注册 KataCcIsolationPreview 功能标志。
- 验证群集是否正在运行 Kubernetes 版本 1.25.0 及更高版本。
- 在群集上启用工作负载标识 (如果尚未启用)。
使用以下命令通过创建节点池来托管机密容器(预览版)。
使用 az aks nodepool add 命令将节点池添加到 AKS 群集。 指定下列参数:
- --resource-group:输入要在其中创建 AKS 群集的现有资源组的名称。
- --cluster-name:输入 AKS 群集的唯一名称,例如 myAKSCluster。
- --name:输入群集节点池的唯一名称,例如 nodepool2。
- --workload-runtime:指定 KataCcIsolation 以在节点池上启用该功能。 除了
--workload-runtime
参数外,这些其他参数应满足以下要求。 否则,该命令将失败,并报告相应参数的问题。 - --os-sku:AzureLinux。 在此预览版本中,只有 Azure Linux os-sku 支持此功能。
- --node-vm-size:属于第 2 代 VM 并支持嵌套虚拟化的任何 Azure VM 大小都有效。 例如 Standard_DC8as_cc_v5 VM。
以下示例将用户节点池添加到 myAKSCluster,其中有两个节点在 myResourceGroup 的 nodepool2 中:
az aks nodepool add --resource-group myResourceGroup --name nodepool2 –-cluster-name myAKSCluster --node-count 2 --os-sku AzureLinux --node-vm-size Standard_DC4as_cc_v5 --workload-runtime KataCcIsolation
片刻之后,该命令将会完成,并返回有关群集的 JSON 格式信息。
运行 az aks update 命令以在群集上启用机密容器(预览版)。
az aks update --name myAKSCluster --resource-group myResourceGroup
片刻之后,该命令将会完成,并返回有关群集的 JSON 格式信息。
群集准备就绪后,使用 az aks get-credentials 命令获取群集凭据。
az aks get-credentials --resource-group myResourceGroup --name myAKSCluster
配置容器
在配置对 Azure Key Vault 和机密的访问权限并将应用程序部署为机密容器之前,需要完成工作负载标识的配置。
若要配置工作负载标识,请执行部署和配置工作负载标识一文中所述的以下步骤:
- 检索 OIDC 颁发者 URL
- 创建托管标识
- 创建 Kubernetes 服务帐户
- 建立联合标识凭据
重要
你需要根据部署和配置工作负载标识一文中的“导出环境变量”部分来设置环境变量,以继续完成本教程。 请记得将变量 SERVICE_ACCOUNT_NAMESPACE
设置为 kafka
,并在配置工作负载标识之前执行命令 kubectl create namespace kafka
。
使用 kata-cc 和证明容器部署受信任的应用程序
以下步骤使用 Azure 托管硬件安全模块 (mHSM) 管理的加密密钥为 Kafka 消息配置端到端加密。 仅当 Kafka 使用者在机密容器中运行并且 Azure 证明机密预配容器注入到 Pod 中时,才会释放密钥。
此配置基于以下四个组件:
- Kafka 群集:在群集上的 Kafka 命名空间中部署的简单 Kafka 群集。
- Kafka 生成者:作为 Vanilla Kubernetes Pod 运行的 Kafka 生成者,使用公钥将加密的用户配置的消息发送到 Kafka 主题。
- Kafka 使用者:使用 kata-cc 运行时运行的 Kafka 使用者 Pod,配备了安全密钥发布容器,用于检索私钥,以解密 Kafka 消息并将消息呈现到 Web UI。
对于此预览版,建议出于测试和评估目的创建或使用现有的 Azure Key Vault 高级层资源来支持在硬件安全模块 (HSM) 中存储密钥。 不建议使用生产密钥保管库。 如果没有 Azure Key Vault,请参阅使用 Azure CLI 创建密钥保管库。
授予之前创建的托管标识以及帐户对密钥保管库的访问权限。 分配 标识 Key Vault Crypto Officer 和 Key Vault Crypto User Azure RBAC 角色。
注意
托管标识是分配给
USER_ASSIGNED_IDENTITY_NAME
变量的值。若要添加角色分配,必须拥有
Microsoft.Authorization/roleAssignments/write
和Microsoft.Authorization/roleAssignments/delete
权限,例如 Key Vault 数据访问权限管理员、用户访问权限管理员或所有者。你必须使用 Key Vault“高级”SKU 才能支持受 HSM 保护的密钥。
运行以下命令来设置范围:
AKV_SCOPE=$(az keyvault show --name <AZURE_AKV_RESOURCE_NAME> --query id --output tsv)
运行以下命令以分配 Key Vault Crypto Officer 角色。
az role assignment create --role "Key Vault Crypto Officer" --assignee "${USER_ASSIGNED_IDENTITY_NAME}" --scope $AKV_SCOPE
运行以下命令以分配 Key Vault Crypto User 角色。
az role assignment create --role "Key Vault Crypto User" --assignee "${USER_ASSIGNED_IDENTITY_NAME}" --scope $AKV_SCOPE
运行以下命令,在 kafka 命名空间中安装 Kafka 群集:
kubectl create -f 'https://strimzi.io/install/latest?namespace=kafka' -n kafka
运行以下命令以应用
kafka
群集 CR 文件。kubectl apply -f https://strimzi.io/examples/latest/kafka/kafka-persistent-single.yaml -n kafka
使用 GitHub 中工作负载的 bash 脚本来准备 RSA 加密/解密密钥。 将文件另存为
setup-key.sh
。运行以下命令,将
MAA_ENDPOINT
环境变量设置为证明 URI 的 FQDN。export MAA_ENDPOINT="$(az attestation show --name "myattestationprovider" --resource-group "MyResourceGroup" --query 'attestUri' -o tsv | cut -c 9-)"
检查证明 URI 的 FQDN 是否采用了正确的格式(MAA_ENDPOINT不应包含前缀“https://”):
echo $MAA_ENDPOINT
注意
若要设置 Microsoft Azure 证明,请参阅快速入门:使用 Azure CLI 设置 Azure 证明。
复制以下 YAML 清单并将其另存为
consumer.yaml
。apiVersion: v1 kind: Pod metadata: name: kafka-golang-consumer namespace: kafka labels: azure.workload.identity/use: "true" app.kubernetes.io/name: kafka-golang-consumer spec: serviceAccountName: workload-identity-sa runtimeClassName: kata-cc-isolation containers: - image: "mcr.microsoft.com/aci/skr:2.7" imagePullPolicy: Always name: skr env: - name: SkrSideCarArgs value: ewogICAgImNlcnRjYWNoZSI6IHsKCQkiZW5kcG9pbnRfdHlwZSI6ICJMb2NhbFRISU0iLAoJCSJlbmRwb2ludCI6ICIxNjkuMjU0LjE2OS4yNTQvbWV0YWRhdGEvVEhJTS9hbWQvY2VydGlmaWNhdGlvbiIKCX0gIAp9 command: - /bin/skr volumeMounts: - mountPath: /opt/confidential-containers/share/kata-containers/reference-info-base64 name: endor-loc - image: "mcr.microsoft.com/acc/samples/kafka/consumer:1.0" imagePullPolicy: Always name: kafka-golang-consumer env: - name: SkrClientKID value: kafka-encryption-demo - name: SkrClientMAAEndpoint value: sharedeus2.eus2.test.attest.azure.net - name: SkrClientAKVEndpoint value: "myKeyVault.vault.azure.net" - name: TOPIC value: kafka-demo-topic command: - /consume ports: - containerPort: 3333 name: kafka-consumer resources: limits: memory: 1Gi cpu: 200m volumes: - name: endor-loc hostPath: path: /opt/confidential-containers/share/kata-containers/reference-info-base64 --- apiVersion: v1 kind: Service metadata: name: consumer namespace: kafka spec: type: LoadBalancer selector: app.kubernetes.io/name: kafka-golang-consumer ports: - protocol: TCP port: 80 targetPort: kafka-consumer
注意
更新 Pod 环境变量
SkrClientAKVEndpoint
的值以匹配 Azure Key Vault 的 URL,不包括协议值https://
。 当前值占位符值为myKeyVault.vault.azure.net
。 将 Pod 环境变量SkrClientMAAEndpoint
的值更新为MAA_ENDPOINT
的值。 可以通过运行命令echo $MAA_ENDPOINT
或命令az attestation show --name "myattestationprovider" --resource-group "MyResourceGroup" --query 'attestUri' -o tsv | cut -c 9-
来查找MAA_ENDPOINT
的值。运行以下命令,为 Kafka 使用者 YAML 清单生成安全策略,并获取存储在
WORKLOAD_MEASUREMENT
变量中的安全策略的哈希:export WORKLOAD_MEASUREMENT=$(az confcom katapolicygen -y consumer.yaml --print-policy | base64 -d | sha256sum | cut -d' ' -f1)
若要生成 RSA 非对称密钥对(公钥和私钥),请使用以下命令运行
setup-key.sh
脚本。<Azure Key Vault URL>
值应为<your-unique-keyvault-name>.vault.azure.net
export MANAGED_IDENTITY=${USER_ASSIGNED_CLIENT_ID} bash setup-key.sh "kafka-encryption-demo" <Azure Key Vault URL>
注意
Bash 脚本
setup-key.sh
需要环境变量MANAGED_IDENTITY
。执行 bash 脚本后,公钥将另存为
kafka-encryption-demo-pub.pem
。
重要
如果收到错误
ForbiddenByRbac
,则你可能需要等待最多 24 小时,因为托管标识的后端服务将每个资源 URI 的缓存保留最多 24 小时。 另请参阅:Azure RBAC 故障排除。为验证密钥是否已成功上传到密钥保管库,请运行以下命令:
az account set --subscription <Subscription ID> az keyvault key list --vault-name <KeyVault Name> -o table
复制以下 YAML 清单并将其另存为
producer.yaml
。apiVersion: v1 kind: Pod metadata: name: kafka-producer namespace: kafka spec: containers: - image: "mcr.microsoft.com/acc/samples/kafka/producer:1.0" name: kafka-producer command: - /produce env: - name: TOPIC value: kafka-demo-topic - name: MSG value: "Azure Confidential Computing" - name: PUBKEY value: |- -----BEGIN PUBLIC KEY----- MIIBojAN***AE= -----END PUBLIC KEY----- resources: limits: memory: 1Gi cpu: 200m
注意
将以
-----BEGIN PUBLIC KEY-----
开头且以-----END PUBLIC KEY-----
字符串结尾的值更新为在上一步中创建的kafka-encryption-demo-pub.pem
中的内容。使用之前保存的文件部署
consumer
和producer
YAML 清单。kubectl apply -f consumer.yaml
kubectl apply -f producer.yaml
使用以下命令获取 Web 服务的 IP 地址:
kubectl get svc consumer -n kafka
将使用者服务的外部 IP 地址复制并粘贴到浏览器中,并观察解密的消息。
命令的输出类似于以下示例:
Welcome to Confidential Containers on AKS! Encrypted Kafka Message: Msg 1: Azure Confidential Computing
还应尝试通过删除
skr container
和kata-cc runtime class
规范以常规 Kubernetes Pod 的形式运行使用者。由于未使用 kata-cc 运行时类运行使用者,因此不再需要该策略。删除整个策略,并在重新部署工作负载后在浏览器中再次观察消息。 消息显示为 base64 编码的已加密文本,因为无法检索私钥。 无法检索密钥,因为使用者不再在机密环境中运行,并且缺少
skr container
,从而无法解密消息。
清理
完成此功能的评估后,为避免 Azure 费用,请清理不必要的资源。 如果在评估或测试过程中部署了新群集,则可以使用 az aks delete 命令删除该群集。
az aks delete --resource-group myResourceGroup --name myAKSCluster
如果在现有群集上启用了机密容器(预览版),则可以使用 kubectl delete pod 命令删除 Pod。
kubectl delete pod pod-name
后续步骤
- 详细了解如何对 AKS 群集中的节点使用 Azure 专用主机,以便对 Azure 平台维护事件使用硬件隔离和控制。