可以使用Azure Policy在Azure Kubernetes 服务 (AKS)群集上应用和强制实施内置安全策略。 Azure Policy 可帮助你执行组织标准并大规模评估合规性。 安装适用于 AKS 的 Azure Policy 加载项后,可以将单个策略定义或名为“initiatives”的策略定义组(有时名为“policysets”)应用到群集。 有关 AKS 策略和计划定义的完整列表,请参阅 AKS 的Azure Policy内置定义。
本文介绍如何将策略定义应用于群集,并验证是否强制实施分配。
Prerequisites
- 本文假设您已有一个 AKS 群集。 如果需要 AKS 群集,可以使用 Azure CLI、Azure PowerShell 或 Azure 门户 创建一个。
- 你需要在 AKS 群集上安装适用于 AKS 的 Azure Policy 加载项。
在开始之前,需要安装和配置以下资源:
- 本文假设您已有一个 AKS 群集。 如果需要 AKS 群集,可以使用 Azure CLI、Azure PowerShell 或 Azure 门户 创建一个。
- 你需要在 AKS 群集上安装适用于 AKS 的 Azure Policy 加载项。
- Terraform 版本 1.6.0 或更高版本。
- Azure CLI 2.47.0 或更高版本。 若要安装或更新 Azure CLI,请参阅 “安装 Azure CLI”。
- Kubectl 已安装并配置。
分配内置策略定义或计划
可以使用以下步骤在 Azure 门户中应用策略定义或计划:
- 转到名为 Policy 的 Azure 门户中的 Azure Policy 服务。
- 在Azure Policy页的左窗格中,选择Definitions。
- 在“类别”下,选择
Kubernetes。 - 选择要应用的策略定义或计划。 对于此示例,请选择基于 Linux 的工作负载的 Kubernetes 群集 Pod 安全基线标准计划。
- 选择分配。
- 将“范围”设置为启用了 Azure Policy 加载项的 AKS 群集的资源组。
- 选择“参数”页,并将 效果 从
audit更新为deny,以阻止违反基线计划的新部署。 还可以添加其他要从计算中排除的命名空间。 对于本示例,请保留默认值。 - 依次选择“查看 + 创建”>“创建”以提交策略分配 。
为 Terraform 配置创建目录。
mkdir aks-use-azure-policy
cd aks-use-azure-policy
创建 Terraform 配置
创建名为 的文件 main.tf。
touch main.tf
main.tf打开该文件并添加以下配置。
配置 Terraform 提供商
如下配置:
- 定义 Terraform 版本。
- 配置 AzureRM 提供程序。
- 启用资源管理所需的Azure提供程序功能。
terraform {
required_version = ">= 1.6.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 4.0"
}
}
}
provider "azurerm" {
features {}
}
定义输入变量
使用以下变量在部署期间提供现有资源组和 AKS 群集的名称。
variable "resource_group_name" {
description = "Name of the resource group that contains the existing AKS cluster."
type = string
}
variable "aks_cluster_name" {
description = "Name of the existing AKS cluster."
type = string
}
引用现有的 AKS 群集
以下数据源检索有关现有资源组和 AKS 群集的信息。 Terraform 使用此数据来引用Azure中已存在的基础结构,而不是创建新资源。
data "azurerm_resource_group" "aks" {
name = var.resource_group_name
}
data "azurerm_kubernetes_cluster" "aks" {
name = var.aks_cluster_name
resource_group_name = data.azurerm_resource_group.aks.name
}
可选:创建和分配自定义策略定义
自定义策略定义部分是信息性的,不在本文的范围内。 自定义策略允许使用 Azure 定义规则。 例如,可以强制实施以下类型的规则:
- 安全做法。
- 成本管理。
- 组织特定的规则,例如命名约定或位置。
在创建自定义策略之前,请检查通用模式和示例列表,以确定是否已涵盖你的案例。
自定义策略定义是以 JSON 编写的。 若要详细了解如何创建自定义策略,请参阅 Azure Policy 定义结构和创建自定义策略定义。
注释
Azure Policy使用名为 templateInfo 的属性,该属性可用于定义约束模板的源类型。 在策略定义中定义 templateInfo 时,不能使用 constraintTemplate 或 约束 属性。 你仍需要定义 apiGroups 和 kinds。 有关详细信息,请参阅“了解Azure Policy效果”。
创建自定义策略定义后,请参阅为分步演练 分配策略定义 ,以便将策略分配给群集。
验证 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此示例显示了只影响违反了集合中策略的部署的基线计划。 允许的部署将继续正常运行。
使用
NGINX命令删除kubectl delete非特权 Pod,并指定您的 YAML 清单文件名。kubectl delete -f nginx-unprivileged.yaml
按照以下步骤,使用 Terraform 将内置 Azure Policy 策略计划分配给 AKS 群集。
获取内置的 Azure 策略计划
以下数据源获取用于 Kubernetes Pod 安全基线标准的 Azure Policy 内置计划。
data "azurerm_policy_set_definition" "aks_pod_security_baseline" {
display_name = "Kubernetes cluster pod security baseline standards for Linux-based workloads"
}
分配 Azure Policy 策略计划
以下资源将内置Azure Policy计划分配给包含 AKS 群集的资源组。
将策略效果设置为 Deny 阻止违反定义的策略规则的工作负荷。
resource "azurerm_resource_group_policy_assignment" "aks_pod_security_baseline" {
name = "aks-pod-security-baseline"
display_name = "Kubernetes cluster pod security baseline standards for Linux-based workloads"
resource_group_id = data.azurerm_resource_group.aks.id
policy_definition_id = data.azurerm_policy_set_definition.aks_pod_security_baseline.id
parameters = jsonencode({
effect = {
value = "Deny"
}
})
}
初始化 Terraform 配置
运行 terraform init 以初始化 Terraform 工作目录并下载所需的提供程序插件。
terraform init
格式化并验证配置
运行 terraform fmt 以格式化 Terraform 配置。
terraform fmt
运行 terraform validate 以验证 Terraform 配置语法。
terraform validate
应用 Terraform 配置
在部署配置之前,请提供以下变量的值:
resource_group_nameaks_cluster_name
运行 terraform apply 以部署 Azure Policy 分配。
terraform apply
出现提示时,请输入 yes 以确认部署。
验证 Azure Policy 的安装
部署完成后,请验证Azure Policy组件是否在 AKS 群集中运行。
kubectl get pods -n kube-system
验证 Gatekeeper 约束模板是否已成功安装。
kubectl get constrainttemplates
测试 Azure Policy 策略分配
创建名为 的文件 privileged-pod.yaml。
apiVersion: v1
kind: Pod
metadata:
name: privileged-pod
spec:
containers:
- name: nginx
image: nginx
securityContext:
privileged: true
将清单应用到群集。
kubectl apply -f privileged-pod.yaml
部署失败,因为 Azure Policy 分配项拒绝了违反已配置 Pod 安全基线标准的特权容器。
禁用策略或计划
使用以下步骤在 Azure 门户中删除基线计划:
- 转到Azure门户中的“策略”窗格。
- 选择任务。
- 选择
...计划所在行末尾的省略号()。 - 选择 “删除分配”。
若要从 AKS 群集中删除Azure Policy加载项,请参阅“删除加载项”。
后续步骤
有关 Azure Policy 工作原理的详细信息,请参阅以下文章: