本文使用Azure CLI部署Azure Kubernetes 服务 (AKS)群集,并使用自动生成的安全策略配置机密容器(预览版)。 然后可以将应用程序部署为机密容器。 若要了解详细信息,请阅读 AKS 机密容器概述。
通常,AKS 机密容器入门涉及以下步骤。
- 使用 Azure CLI部署或升级 AKS 群集。
- 将批注添加到 Pod YAML 清单,以将 Pod 标记为使用机密容器。
- 将安全策略添加到 Pod YAML 清单。
- 在机密计算中部署应用程序。
重要
从 2025 年 11 月 30 日开始,Azure Kubernetes 服务(AKS)不再支持或提供 Azure Linux 2.0 安全更新。 Azure Linux 2.0 节点映像在 202512.06.0 版中被冻结。 从 2026 年 10 月 31 日开始,将删除节点映像,并且无法缩放节点池。 通过将 节点池升级到 受支持的 Kubernetes 版本或迁移到 osSku AzureLinux3,迁移到受支持的 Azure Linux 版本。 有关详细信息,请参阅 停用 GitHub 问题和Azure 更新停用公告。 若要随时了解公告和更新,请关注AKS 发行说明。
先决条件
- 最新版本的 Azure CLI。 可通过运行
az version查找版本,运行az upgrade升级版本。 如果需要安装或升级,请参阅 安装 Azure CLI。 -
aks-previewAzure CLI 扩展的最新版本。 -
confcom机密容器 Azure CLI 扩展的最新版本。 - 工作负载标识和联合标识凭据。 使用工作负载标识凭据,Kubernetes 应用程序可以使用基于带注释的服务帐户通过 Microsoft Entra ID 安全地访问 Azure 资源。 如果不熟悉 Microsoft Entra 工作负载 ID,请参阅 Microsoft Entra 工作负载 ID 概述并查看工作负载标识如何与 AKS 配合使用。
- 用于创建群集的标识具有合适的的最低权限。 有关 AKS 的访问和标识的详细信息,请参阅 Azure Kubernetes 服务 (AKS) 的访问和标识选项。
- 若要管理 Kubernetes 群集,请使用 Kubernetes 命令行客户端 kubectl。 可以使用 az aks install-cli 命令在本地安装 kubectl。
- AKS 上的机密容器提供用于证明和安全密钥发布的挎斗开放源代码容器。 该挎斗与 Azure 密钥保管库 等密钥管理服务 (KMS) 集成,以便在验证完成后将密钥发布到容器组。 部署 Azure 密钥保管库 托管 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 功能标志
az feature register运行以下命令以注册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:任何支持嵌套虚拟化并可用于 AMD SEV-SNP 受保护子 VM 的 Azure VM 大小都可以。
- --enable-workload-identity:启用创建 Microsoft Entra Workload ID,使 Pod 能够使用 Kubernetes 标识。
- --enable-oidc-issuer:启用 OpenID Connect (OIDC) 证书颁发者。 它允许 Microsoft Entra ID 或其他云提供商的标识和访问管理平台发现 API 服务器的公开签名密钥。
- --workload-runtime:指定 KataCcIsolation 以在节点池上启用机密容器功能。
az aks create --resource-group myResourceGroup --name myAKSCluster --os-sku AzureLinux --node-vm-size Standard_DC8as_cc_v5 --workload-runtime KataCcIsolation --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
在现有群集上启用机密容器
若要将此功能用于现有 AKS 群集,必须满足以下要求:
- 按照以下步骤注册
KataCcIsolationPreview功能标志。 - 在群集上启用工作负载标识 (如果尚未启用)。
添加启用了机密容器的节点池
使用以下命令通过创建节点池来托管机密容器(预览版)。
使用
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:任何支持嵌套虚拟化并可用于 AMD SEV-SNP 受保护子 VM 的 Azure 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_DC8as_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 密钥保管库 和机密的访问权限并将应用程序部署为机密容器之前,需要完成工作负载标识的配置。
若要配置工作负载标识,请执行部署和配置工作负载标识一文中所述的以下步骤:
- 检索 OIDC 颁发者 URL
- 创建托管标识
- 创建 Kubernetes 服务帐户
- 建立联合标识凭据
重要
若要继续本教程,请从“部署和配置工作负荷标识”一文中的“导出环境变量”部分设置环境变量。 将变量SERVICE_ACCOUNT_NAMESPACEkafka设置为,并在配置工作负荷标识之前运行命令kubectl create namespace kafka。
使用 kata-cc 和证明容器部署受信任的应用程序
以下步骤使用由Azure 托管硬件安全模块(Managed HSM)管理的加密密钥,为 Kafka 消息配置端到端加密。 仅当 Kafka 消费者在机密容器中运行,且其所在的 pod 中注入了 Azure 证明机密预配容器时,才会发放该密钥。
此配置基于以下三个组件:
- Kafka 群集:在群集上的 Kafka 命名空间中部署的简单 Kafka 群集。
- Kafka 生成者:作为 Vanilla Kubernetes Pod 运行的 Kafka 生成者,使用公钥将加密的用户配置的消息发送到 Kafka 主题。
- Kafka 使用者:使用 kata-cc 运行时运行的 Kafka 使用者 Pod,从安全密钥发布容器中检索私钥,以解密 Kafka 消息,并将消息呈现到 Web UI。
对于此预览版,建议出于测试和评估目的创建或使用现有的 Azure 密钥保管库 高级层资源来支持在硬件安全模块 (HSM) 中存储密钥。 不建议使用生产密钥保管库。 如果没有 Azure 密钥保管库,请参阅使用 Azure CLI 创建密钥保管库。
授予之前创建的托管标识以及帐户对密钥保管库的访问权限。 分配 标识 密钥保管库 Crypto Officer 和 密钥保管库 Crypto User Azure RBAC 角色。
注释
托管标识是分配给
USER_ASSIGNED_IDENTITY_NAME变量的值。若要添加角色分配,必须拥有
Microsoft.Authorization/roleAssignments/write和Microsoft.Authorization/roleAssignments/delete权限,例如 密钥保管库 数据访问权限管理员、用户访问权限管理员或所有者。你必须使用 密钥保管库“高级”SKU 才能支持受 HSM 保护的密钥。
运行以下命令来设置范围:
AKV_SCOPE=$(az keyvault show --name <AZURE_AKV_RESOURCE_NAME> --query id --output tsv)运行以下命令以分配 密钥保管库 Crypto Officer 角色。
az role assignment create --role "Key Vault Crypto Officer" --assignee "${USER_ASSIGNED_IDENTITY_NAME}" --scope $AKV_SCOPE运行以下命令以分配 密钥保管库 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复制以下 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.azk8s.cn/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.azk8s.cn/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.chinacloudapi.cn - name: SkrClientAKVEndpoint value: "myKeyVault.vault.azure.cn" - 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 密钥保管库 的 URL,不包括协议值https://。 当前值占位符值为myKeyVault.vault.azure.cn。 将 Pod 环境变量SkrClientMAAEndpoint的值更新为MAA_ENDPOINT的值。 可以通过运行命令MAA_ENDPOINT或命令echo $MAA_ENDPOINT来查找az attestation show --name "myattestationprovider" --resource-group "MyResourceGroup" --query 'attestUri' -o tsv | cut -c 9-的值。运行以下命令,为 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 密钥保管库 URL>值应为<your-unique-keyvault-name>.vault.azure.cnexport 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.azk8s.cn/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和producerYAML 清单。kubectl apply -f consumer.yamlkubectl 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 平台维护事件使用硬件隔离和控制。