使用 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 群集的分步演练。
使用以下
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
首先测试在使用 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 不会到达计划阶段,因此在继续之前,没有要删除的资源。
在上面的示例中,容器映像自动尝试使用根将 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 工作原理的详细信息,请参阅以下文章: