了解用于 Kubernetes 群集的 Azure Policy

Azure Policy 将扩展 Gatekeeper v3,这是一个用于 Open Policy Agent (OPA) 的许可控制器 Webhook,它以集中、一致的方式对群集应用大规模操作和安全措施。 借助 Azure Policy,可以从一个位置管理和报告 Kubernetes 群集的符合性状态。 该加载项制定以下功能:

  • 检查 Azure Policy 服务对群集的策略分配。
  • 将策略定义作为约束模板部署到群集中,并约束自定义资源。
  • 向 Azure Policy 服务报告审核和符合性详细信息。

适用于 Kubernetes 的 Azure Policy 支持以下群集环境:

重要

Azure Policy 加载项 Helm 模型和 AKS 引擎的加载项已弃用。

概述

若要启用 Azure Policy 并将其用于 Kubernetes 群集,请执行以下操作:

  1. 配置 Kubernetes 群集并安装 Azure Kubernetes Service (AKS) 加载项

    注意

    有关安装的常见问题,请参阅故障排除 - Azure Policy 加载项

  2. 了解适用于 Kubernetes 的 Azure Policy 语言

  3. 向 Kubernetes 群集分配定义

  4. 等待验证

限制

以下一般限制适用于 Kubernetes 群集的 Azure Policy 加载项:

以下限制仅适用于 AKS 的 Azure Policy 加载项:

  • Azure Policy 附加产品评估自动排除的命名空间包括:kube-system 和 gatekeeper-system。

建议

下面是有关如何使用 Azure Policy 加载项的常规建议:

  • Azure Policy 附加产品需要三个 Gatekeeper 组件才能运行:一个审核 Pod 和两个 Webhook Pod 副本。 随着集群中 Kubernetes 资源和策略分配计数的增加,这些组件会消耗更多的资源,这就需要执行审核和强制操作。

    • 对于少于 500 个 Pod、最多 20 个约束的单个群集:每个组件 2 个 vCPU,350 MB 内存。
    • 对于超过 500 个 Pod、最多 40 个约束的单个群集:每个组件 3 个 vCPU,600 MB 内存。
  • 打开 Azure Policy 加载项的端口。 Azure Policy 加载项使用这些域和端口来提取策略定义和分配,并将群集的合规性情况报告回 Azure Policy。

    端口
    data.policy.core.chinacloudapi.cn 443
    store.policy.core.chinacloudapi.cn 443
    login.chinacloudapi.cn 443
    dc.services.visualstudio.com 443
  • Windows Pod 不支持安全上下文。 因此,某些 Azure Policy 定义(例如禁用根权限)不能在 Windows Pod 中升级,仅适用于 Linux Pod。

以下建议仅适用于 AKS 和 Azure Policy 加载项:

  • 使用具有 CriticalAddonsOnly 排斥的系统节点池来计划 Gatekeeper Pod。 有关详细信息,请参阅使用系统节点池
  • 保护来自 AKS 群集的出站流量。 有关详细信息,请参阅控制群集节点的出口流量
  • 如果群集启用了 aad-pod-identity,节点托管标识 (NMI) pod 将修改节点的 iptable,以拦截对 Azure 实例元数据终结点的调用。 此配置意味着对元数据终结点发出的任何请求都将被 NMI 拦截,即使 pod 不使用 aad-pod-identity。 可以将 AzurePodIdentityException CRD 配置为通知 aad-pod-identity 应在不使用 NMI 进行出任何处理的情况下,代理与 CRD 中定义的标签匹配的 pod 所发起的对元数据终结点的任何请求。 应通过配置 AzurePodIdentityException CRD 在 aad-pod-identity 中排除在 kubernetes.azure.com/managedby: aks 命名空间中具有 kubernetes.azure.com/managedby: aks 标签的系统 pod。 有关详细信息,请参阅禁用特定 pod 或应用程序的 aad-pod-identity。 若要配置例外情况,请安装 mic-exception YAML

为 AKS 安装 Azure Policy 加载项

在安装 Azure Policy 加载项或启用任何服务功能之前,订阅必须启用Microsoft.PolicyInsights资源提供程序。

  1. 需要安装和配置 Azure CLI 版本 2.12.0 或更高版本。 运行 az --version 即可查找版本。 如需进行安装或升级,请参阅安装 Azure CLI

  2. 注册资源提供程序和预览功能。

    • Azure 门户:

      注册Microsoft.PolicyInsights资源提供程序。 有关步骤,请参阅资源提供程序和类型

    • Azure CLI:

      # Log in first with az login
      az cloud set -n AzureChinaCloud
      az login
      
      # Provider register: Register the Azure Policy provider
      az provider register --namespace Microsoft.PolicyInsights
      
  3. 如果安装了有限预览策略定义,请在“策略”页下删除 AKS 群集中带有“禁用”按钮的加载项。

  4. AKS 群集必须是Azure Kubernetes 服务 (AKS) 中受支持的 Kubernetes 版本。 使用以下脚本验证 AKS 群集版本:

    # Log in first with az login
    az cloud set -n AzureChinaCloud
    az login
    
    # Look for the value in kubernetesVersion
    az aks list
    
  5. 安装 Azure CLI 2.12.0 或更高版本。 有关详细信息,请参阅安装 Azure CLI

完成先决条件后,立即在要管理的 AKS 群集中安装 Azure Policy 加载项。

  • Azure 门户

    1. 在 Azure 门户中,选择“所有服务”,然后搜索并选择“Kubernetes 服务”,以启动 AKS 服务。

    2. 选择 AKS 群集之一。

    3. 选择“Kubernetes 服务”页左侧的“策略”。

    4. 在主页中,选择“启用加载项”按钮。

  • Azure CLI

    # Log in first with az login
    az cloud set -n AzureChinaCloud
    az login
    
    az aks enable-addons --addons azure-policy --name MyAKSCluster --resource-group MyResourceGroup
    

若要验证加载项安装是否成功以及 azure-policy 和 gatekeeper Pod 是否正在运行,请运行以下命令 :

# azure-policy pod is installed in kube-system namespace
kubectl get pods -n kube-system

# gatekeeper pod is installed in gatekeeper-system namespace
kubectl get pods -n gatekeeper-system

最后,通过运行此 Azure CLI 命令,并将 <rg> 替换为资源组名称,将 <cluster-name> 替换为 AKS 群集名称 az aks show --query addonProfiles.azurepolicy -g <rg> -n <cluster-name>,来验证是否已安装最新的加载项。 结果应类似于以下输出:

{
  "config": null,
  "enabled": true,
  "identity": null
}

Policy 语言

用于管理 Kubernetes 的 Azure Policy 语言结构遵循现有策略定义。 使用 Microsoft.Kubernetes.Data资源提供程序模式,会使用效果审核拒绝来管理你的 Kubernetes 群集。 “审核”和“拒绝”必须提供特定于使用 OPA Constraint Framework 和 Gatekeeper v3 的详细信息属性。

作为策略定义中 details.templateInfo、details.constraint 或 details.constraintTemplate 属性的一部分,Azure Policy 将这些 CustomResourceDefinitions (CRD) 的 URI 或 Base64Encoded 值传递给加载项。 Rego 是 OPA 和 Gatekeeper 支持的语言,用于验证对 Kubernetes 群集的请求。 通过支持 Kubernetes 管理的现有标准,Azure Policy 可重用现有规则并将其与 Azure Policy 配对以获得统一的云符合性报告体验。 有关详细信息,请参阅什么是 Rego?

分配策略定义

若要为 Kubernetes 群集分配策略定义,系统必须为你分配适当的 Azure 基于角色的访问控制 (Azure RBAC) 策略分配操作。 Azure 内置角色“资源策略参与者”和“所有者”可进行这些操作。 若要了解详细信息,请参阅 Azure Policy 中的 Azure RBAC 权限

通过以下步骤,使用 Azure 门户查找用于管理群集的内置策略定义。 如果使用某自定义策略定义,请按名称或创建时使用的类别来搜索该定义。

  1. 在 Azure 门户中启动 Azure Policy 服务。 在左窗格中选择“所有服务”,然后搜索并选择“策略” 。

  2. 在“Azure Policy”页面的左侧窗格中,选择“定义”。

  3. 从“类别”下拉列表框中,使用“全选”清除筛选器,然后选择“Kubernetes” 。

  4. 选择策略定义,然后选择“分配”按钮。

  5. 将“范围”设置为将应用策略分配的 Kubernetes 群集的管理组、订阅或资源组。

    注意

    为 Kubernetes 定义分配 Azure Policy 时,“范围”必须包括群集资源。

  6. 为策略分配提供可以用于轻松识别它的“名称”和“说明”。

  7. 策略实施设置为下面的一个值:

    • 已启用 - 在群集上强制实施策略。 拒绝带有冲突的 Kubernetes 许可请求。

    • 已禁用 - 不在群集上强制实施策略。 不拒绝带有冲突的 Kubernetes 许可请求。 符合性评估结果仍可用。 向运行群集推出新策略定义时,已禁用选项可用于测试策略定义,因为不拒绝带有冲突的许可请求。

  8. 选择下一步

  9. 设置参数值

    • 若要从策略评估中排除 Kubernetes 命名空间,请在参数“命名空间排除”中指定命名空间的列表。 建议排除以下内容:kube-system、gatekeeper-system 和 azure-arc。
  10. 选择“查看 + 创建”。

或者,使用分配策略 - 门户快速入门来查找和分配 Kubernetes 策略。 搜索 Kubernetes 策略定义,而不是示例audit vms

重要

内置策略定义适用于 Kubernetes 类别的 Kubernetes 群集。 有关内置策略定义的列表,请参阅 Kubernetes 示例

策略评估

加载项每 15 分钟使用 Azure Policy 服务签入一次,查看策略分配中的更改。 在此刷新周期内,加载项将检查更改。 这些更改将触发约束模板和约束的创建、更新或删除。

在 Kubernetes 群集中,如果命名空间具有适合群集的标签,则不拒绝带有冲突的许可请求。 符合性评估结果仍可用。

注意

虽然群集管理员可能有权创建和更新 Azure Policy 加载项安装的约束模板和约束资源,但这些情况不受支持,因为手动更新会被覆盖。 Gatekeeper 会继续评估在安装加载项和分配 Azure Policy 策略定义之前已存在的策略。

每隔 15 分钟,加载项就会调用对群集的完全扫描。 在收集完全扫描的详细信息和 Gatekeeper 对群集尝试更改的所有实时评估后,加载项将结果报告回 Azure Policy,以便像所有 Azure Policy 分配一样包含在符合性详细信息中。 在审核周期中,仅返回活动策略分配的结果。 审核结果也可以视为已失败约束的“状态”字段中列出的冲突。 有关不符合资源的详细信息,请参阅资源提供程序模式的组件详细信息

注意

适用于 Kubernetes 群集的 Azure Policy 中的每个符合性报告都包含过去 45 分钟内的所有冲突。 时间戳指示发生冲突的时间。

一些其他注意事项:

  • 如果将群集订阅注册到 Microsoft Defender for Cloud,则 Microsoft Defender for Cloud Kubernetes 策略会自动应用于群集。

  • 将拒绝策略应用于带有现有 Kubernetes 资源的群集时,任何不符合新策略的预先存在的资源都将继续运行。 如果在其他节点上重新计划了不符合的资源,则 Gatekeeper 会阻止资源创建。

  • 如果群集具有用于验证资源的拒绝策略,则在创建部署时,用户不会收到拒绝消息。 例如,考虑包含副本集和 Pod 的 Kubernetes 部署。 用户执行kubectl describe deployment $MY_DEPLOYMENT时,不会返回拒绝消息作为事件的一部分。 但是,kubectl describe replicasets.apps $MY_DEPLOYMENT 会返回与拒绝关联的事件。

注意

策略评估期间可能包含 Init 容器。 若要查看是否包含 Init 容器,请查看 CRD 中的以下或类似声明:

input_containers[c] {
   c := input.review.object.spec.initContainers[_]
}

约束模板冲突

如果约束模板具有相同的资源元数据名称,但策略定义引用不同位置的源,则策略定义被视为冲突。 示例:两个策略定义引用存储在不同源位置(例如 Azure Policy 模板存储区 (store.policy.core.chinacloudapi.cn) 和 GitHub)的同一 template.yaml 文件。

如果策略定义及其约束模板在分配时未安装于群集并存在冲突,会将其报告为冲突,且在冲突解决之前不会将其安装到群集中。 同样,群集上与新分配策略定义冲突的任何现有策略定义和它们的约束模板都会继续正常工作。 如果更新现有分配,但未能同步约束模板,则群集也会标记为冲突。 有关所有冲突消息,请参阅 AKS 资源提供程序模式符合性原因

日志记录

作为 Kubernetes 控制器/容器,azure-policy 和 gatekeeper Pod 在 Kubernetes 群集中保留日志。 通常,azure-policy 日志可用于解决有关将策略引入群集和合规性报告的问题。 gatekeeper-controller-manager pod 日志可用于解决运行时拒绝问题。 gatekeeper-audit pod 日志可用于对现有资源的审核进行故障排除。 日志可以在 Kubernetes 群集的“见解”页中公开。 有关详细信息,请参阅使用适用于容器的 Azure Monitor 监视 Kubernetes 群集性能

若要查看加载项日志,请使用 kubectl

# Get the azure-policy pod name installed in kube-system namespace
kubectl logs <azure-policy pod name> -n kube-system

# Get the gatekeeper pod name installed in gatekeeper-system namespace
kubectl logs <gatekeeper pod name> -n gatekeeper-system

有关详细信息,请参阅 Gatekeeper 文档中的调试 Gatekeeper

查看 Gatekeeper 项目

在外接程序下载策略分配并在群集上安装约束模板和约束后,会通过 Azure 策略信息(如策略分配 ID)和策略定义 ID 进行注释。 若要配置客户端以查看外接程序相关项目,请使用以下步骤:

  1. 为群集设置kubeconfig

    对于 Azure Kubernetes 服务群集,请使用以下 Azure CLI:

    # Set context to the subscription
    az account set --subscription <YOUR-SUBSCRIPTION>
    
    # Save credentials for kubeconfig into .kube in your home folder
    az aks get-credentials --resource-group <RESOURCE-GROUP> --name <CLUSTER-NAME>
    
  2. 测试群集连接。

    运行 kubectl cluster-info 命令。 成功运行后,每项服务都会使用其运行位置的 URL 进行响应。

查看外接程序约束模板

若要查看外接程序下载的约束模板,请运行 kubectl get constrainttemplates。 以 k8sazure 开头的约束模板是由外接程序安装的约束模板。

获取 Azure Policy 映射

若要确定下载到群集的约束模板与策略定义之间的映射,请使用 kubectl get constrainttemplates <TEMPLATE> -o yaml。 结果类似于以下输出:

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
    annotations:
    azure-policy-definition-id: /subscriptions/<SUBID>/providers/Microsoft.Authorization/policyDefinitions/<GUID>
    constraint-template-installed-by: azure-policy-addon
    constraint-template: <URL-OF-YAML>
    creationTimestamp: "2021-09-01T13:20:55Z"
    generation: 1
    managedFields:
    - apiVersion: templates.gatekeeper.sh/v1beta1
    fieldsType: FieldsV1
...

<SUBID> 是订阅 ID,<GUID> 是映射的策略定义的 ID。 <URL-OF-YAML> 是外接程序下载的要安装在群集上的约束模板的源位置。

获得外接程序的已下载约束模板的名称后,可以使用该名称查看相关约束。 使用 kubectl get <constraintTemplateName> 获取列表。 附加产品安装的约束以 azurepolicy- 开头。

查看约束详细信息

该约束包含有关冲突以及与策略定义和分配之间的映射的详细信息。 要查看详细信息,请使用kubectl get <CONSTRAINT-TEMPLATE> <CONSTRAINT> -o yaml。 结果类似于以下输出:

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sAzureContainerAllowedImages
metadata:
  annotations:
    azure-policy-assignment-id: /subscriptions/<SUB-ID>/resourceGroups/<RG-NAME>/providers/Microsoft.Authorization/policyAssignments/<ASSIGNMENT-GUID>
    azure-policy-definition-id: /providers/Microsoft.Authorization/policyDefinitions/<DEFINITION-GUID>
    azure-policy-definition-reference-id: ""
    azure-policy-setdefinition-id: ""
    constraint-installed-by: azure-policy-addon
    constraint-url: <URL-OF-YAML>
  creationTimestamp: "2021-09-01T13:20:55Z"
spec:
  enforcementAction: deny
  match:
    excludedNamespaces:
    - kube-system
    - gatekeeper-system
    - azure-arc
  parameters:
    imageRegex: ^.+azurecr.io/.+$
status:
  auditTimestamp: "2021-09-01T13:48:16Z"
  totalViolations: 32
  violations:
  - enforcementAction: deny
    kind: Pod
    message: Container image nginx for container hello-world has not been allowed.
    name: hello-world-78f7bfd5b8-lmc5b
    namespace: default
  - enforcementAction: deny
    kind: Pod
    message: Container image nginx for container hello-world has not been allowed.
    name: hellow-world-89f8bfd6b9-zkggg

对加载项进行故障排除

有关如何对适用于 Kubernetes 的加载项进行故障排除的详细信息,请参阅 Azure Policy 故障排除一文的 Kubernetes 部分

有关 Azure Policy 相关问题,请转到:

删除加载项

从 AKS 删除加载项

若要从 AKS 群集中删除 Azure Policy 加载项,请使用 Azure 门户或 Azure CLI:

  • Azure 门户

    1. 在 Azure 门户中,选择“所有服务”,然后搜索并选择“Kubernetes 服务”,以启动 AKS 服务。

    2. 选择要在其中禁用 Azure Policy 加载项的 AKS 群集。

    3. 选择“Kubernetes 服务”页左侧的“策略”。

    4. 在主页中,选择“禁用加载项”按钮。

  • Azure CLI

    # Log in first with az login
    az cloud set -n AzureChinaCloud
    az login
    
    az aks disable-addons --addons azure-policy --name MyAKSCluster --resource-group MyResourceGroup
    

Azure Policy 加载项收集的诊断数据

适用于 Kubernetes 的 Azure Policy 加载项收集有限的群集诊断数据。 该诊断数据是与软件和性能相关的重要技术数据。 可通过以下方式使用该数据:

  • 使 Azure Policy 加载项保持最新
  • 使 Azure Policy 加载项保持安全、可靠和高性能
  • 改进 Azure Policy 加载项 - 通过对加载项使用的聚合分析

加载项收集的信息不是个人数据。 当前正在收集以下详细信息:

  • Azure Policy 加载项代理版本

  • 群集类型

  • 群集区域

  • 群集资源组

  • 群集资源 ID

  • 群集订阅 ID

  • 群集 OS(示例:Linux)

  • 群集所在城市

  • 群集所在州/省/自治区/直辖市

  • 群集所在国家/地区

  • 在策略评估的代理安装期间,Azure Policy 加载项遇到异常/错误

  • Azure Policy 加载项未安装的 Gatekeeper 策略数

后续步骤