你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用 Azure Policy 保护 Azure Kubernetes 服务 (AKS) 群集

可以使用 Azure Policy 在 Azure Kubernetes 服务 (AKS) 群集上应用和强制实施内置的安全策略。 Azure Policy 有助于强制执行组织标准并进行大规模的合规性评估。 安装适用于 AKS 的 Azure Policy 加载项后,可以将单个策略定义或名为“initiatives”的策略定义组(有时名为“policysets”)应用到群集。 请参阅适用于 AKS 的 Azure Policy 内置定义,查看 AKS 策略和计划定义的完整列表。

本文介绍如何将策略定义应用于群集,并验证是否在强制执行这些分配。

先决条件

分配内置策略定义或计划

可以使用以下步骤在 Azure 门户中应用策略定义或计划:

  1. 导航到 Azure 门户中名为“Policy”的 Azure Policy 服务。
  2. 在“Azure Policy”页面的左侧窗格中,选择“定义”。
  3. 在“类别”下,选择 Kubernetes
  4. 选择要应用的策略定义或计划。 对于此示例,请选择基于 Linux 的工作负载的 Kubernetes 群集 Pod 安全基线标准计划。
  5. 选择“分配”。
  6. 将“范围”设置为启用了 Azure Policy 加载项的 AKS 群集的资源组。
  7. 选择“参数”页面并将“效果”从 audit 更新为 deny 以阻止违反基线计划的新部署 。 还可以添加其他要从计算中排除的命名空间。 对于本示例,请保留默认值。
  8. 依次选择“查看 + 创建”>“创建”以提交策略分配 。

创建和分配自定义策略定义

自定义策略允许使用 Azure 定义规则。 例如,可以强制实施以下类型的规则:

  • 安全做法
  • 成本管理
  • 组织特定的规则(例如命名或位置)

在创建自定义策略之前,请检查通用模式和示例列表,以确定是否已涵盖你的案例。

自定义策略定义是以 JSON 编写的。 若要详细了解如何创建自定义策略,请参阅 Azure Policy 定义结构创建自定义策略定义

注意

Azure Policy 现在利用名为 templateInfo 的新属性,可以使用该属性定义约束模板的源类型。 在策略定义中定义 templateInfo时,无需定义 constraintTemplateconstraint 属性。 你仍需要定义 apiGroupskinds。 有关详细信息,请参阅了解 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,因此将拒绝请求,从而导致部署被拒绝。

  1. 创建名为 nginx-privileged.yaml 的文件并粘贴到以下 YAML 清单中。

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-privileged
    spec:
      containers:
        - name: nginx-privileged
          image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine
          securityContext:
            privileged: true
    
  2. 使用 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。

  1. 创建名为 nginx-unprivileged.yaml 的文件并粘贴到以下 YAML 清单中。

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-unprivileged
    spec:
      containers:
        - name: nginx-unprivileged
          image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine
    
  2. 使用 kubectl apply 命令创建 Pod,并指定 YAML 清单的名称。

    kubectl apply -f nginx-unprivileged.yaml
    
  3. 使用 kubectl get pods 命令检查 Pod 的状态。

    kubectl get pods
    

    输出应类似于以下示例输出,显示 Pod 已成功安排并且状态为“正在运行”:

    NAME                 READY   STATUS    RESTARTS   AGE
    nginx-unprivileged   1/1     Running   0          18s
    

    此示例显示了只影响违反了集合中策略的部署的基线计划。 允许的部署将继续正常运行。

  4. 使用 kubectl delete 命令删除 NGINX 非特权 Pod,并指定 YAML 清单的名称。

    kubectl delete -f nginx-unprivileged.yaml
    

禁用策略或计划

可以使用以下步骤在 Azure 门户中删除基线计划:

  1. 导航到 Azure 门户上的“策略”窗格。
  2. 选择“分配” 。
  3. 选择基于 Linux 的工作负载的 Kubernetes 群集 Pod 安全基线标准计划旁边的 ... 按钮。
  4. 选择“删除分配”。

后续步骤

有关 Azure Policy 工作原理的详细信息,请参阅以下文章: