使用 Azure Policy 保护 Azure Kubernetes 服务 (AKS) 群集
可以使用 Azure Policy 在 Azure Kubernetes 服务 (AKS) 群集上应用和强制实施内置的安全策略。 Azure Policy 有助于强制执行组织标准并进行大规模的合规性评估。 安装适用于 AKS 的 Azure Policy 加载项后,可以将单个策略定义或名为“initiatives”的策略定义组(有时名为“policysets”)应用到群集。 请参阅适用于 AKS 的 Azure Policy 内置定义,查看 AKS 策略和计划定义的完整列表。
本文介绍如何将策略定义应用于群集,并验证是否在强制执行这些分配。
先决条件
- 本文假设你有现有 AKS 群集。 如果需要 AKS 群集,可以使用 Azure CLI、Azure PowerShell 或 Azure 门户 创建一个。
- 你需要在 AKS 群集上安装适用于 AKS 的 Azure Policy 加载项。
分配内置策略定义或计划
可以使用以下步骤在 Azure 门户中应用策略定义或计划:
- 导航到 Azure 门户中名为“Policy”的 Azure Policy 服务。
- 在“Azure Policy”页面的左侧窗格中,选择“定义”。
- 在“类别”下,选择
Kubernetes
。 - 选择要应用的策略定义或计划。 对于此示例,请选择基于 Linux 的工作负载的 Kubernetes 群集 Pod 安全基线标准计划。
- 选择“分配”。
- 将“范围”设置为启用了 Azure Policy 加载项的 AKS 群集的资源组。
- 选择“参数”页面并将“效果”从
audit
更新为deny
以阻止违反基线计划的新部署 。 还可以添加其他要从计算中排除的命名空间。 对于本示例,请保留默认值。 - 依次选择“查看 + 创建”>“创建”以提交策略分配 。
创建和分配自定义策略定义
自定义策略允许使用 Azure 定义规则。 例如,可以强制实施以下类型的规则:
- 安全做法
- 成本管理
- 组织特定的规则(例如命名或位置)
在创建自定义策略之前,请检查通用模式和示例列表,以确定是否已涵盖你的案例。
自定义策略定义是以 JSON 编写的。 若要详细了解如何创建自定义策略,请参阅 Azure Policy 定义结构和创建自定义策略定义。
注意
Azure Policy 现在利用名为 templateInfo 的新属性,可以使用该属性定义约束模板的源类型。 在策略定义中定义 templateInfo 时,无需定义 constraintTemplate 或 constraint 属性。 你仍需要定义 apiGroups 和 kinds。 有关详细信息,请参阅了解 Azure Policy 效果。
创建自定义策略定义后,请参阅分配策略定义,获取有关将策略分配到 Kubernetes 群集的分步演练。
验证 Azure Policy 是否正在运行
使用以下
kubectl get
命令来确认策略分配已应用于你的群集。kubectl get constrainttemplates
注意
策略分配可能需要最多 20 分钟来同步到每个群集。
输出应类似于以下示例输出:
NAME AGE k8sazureallowedcapabilities 23m k8sazureallowedusersgroups 23m k8sazureblockhostnamespace 23m k8sazurecontainerallowedimages 23m k8sazurecontainerallowedports 23m k8sazurecontainerlimits 23m k8sazurecontainernoprivilege 23m k8sazurecontainernoprivilegeescalation 23m k8sazureenforceapparmor 23m k8sazurehostfilesystem 23m k8sazurehostnetworkingports 23m k8sazurereadonlyrootfilesystem 23m k8sazureserviceallowedports 23m
验证对特权 pod 的拒绝
首先测试在使用 privileged: true
安全性上下文计划 Pod 时所发生的情况。 此安全性上下文会提升 Pod 的特权。 该计划不允许特权 pod,因此将拒绝请求,从而导致部署被拒绝。
创建名为
nginx-privileged.yaml
的文件并粘贴到以下 YAML 清单中。apiVersion: v1 kind: Pod metadata: name: nginx-privileged spec: containers: - name: nginx-privileged image: mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine securityContext: privileged: true
使用
kubectl apply
命令创建 Pod,并指定 YAML 清单的名称。kubectl apply -f nginx-privileged.yaml
与预期一致,未能计划 Pod,如以下示例输出所示:
Error from server ([denied by azurepolicy-container-no-privilege-00edd87bf80f443fa51d10910255adbc4013d590bec3d290b4f48725d4dfbdf9] Privileged container is not allowed: nginx-privileged, securityContext: {"privileged": true}): error when creating "privileged.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [denied by azurepolicy-container-no-privilege-00edd87bf80f443fa51d10910255adbc4013d590bec3d290b4f48725d4dfbdf9] Privileged container is not allowed: nginx-privileged, securityContext: {"privileged": true}
Pod 不会到达计划阶段,因此在继续之前,没有要删除的资源。
测试非特权 Pod 的创建
在上面的示例中,容器映像自动尝试使用根将 NGINX 绑定到端口 80。 策略计划拒绝了此请求,因此 Pod 无法启动。 现在,请尝试在没有特权访问权限的情况下运行同一 NGINX Pod。
创建名为
nginx-unprivileged.yaml
的文件并粘贴到以下 YAML 清单中。apiVersion: v1 kind: Pod metadata: name: nginx-unprivileged spec: containers: - name: nginx-unprivileged image: mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine
使用
kubectl apply
命令创建 Pod,并指定 YAML 清单的名称。kubectl apply -f nginx-unprivileged.yaml
使用
kubectl get pods
命令检查 Pod 的状态。kubectl get pods
输出应类似于以下示例输出,显示 Pod 已成功安排并且状态为“正在运行”:
NAME READY STATUS RESTARTS AGE nginx-unprivileged 1/1 Running 0 18s
此示例显示了只影响违反了集合中策略的部署的基线计划。 允许的部署将继续正常运行。
使用
kubectl delete
命令删除 NGINX 非特权 Pod,并指定 YAML 清单的名称。kubectl delete -f nginx-unprivileged.yaml
禁用策略或计划
可以使用以下步骤在 Azure 门户中删除基线计划:
- 导航到 Azure 门户上的“策略”窗格。
- 选择“分配” 。
- 选择基于 Linux 的工作负载的 Kubernetes 群集 Pod 安全基线标准计划旁边的 ... 按钮。
- 选择“删除分配”。
后续步骤
有关 Azure Policy 工作原理的详细信息,请参阅以下文章: