创建限制条件

本页面介绍了如何定义政策控制器限制条件。

通过政策控制器,您可以通过定义一个或多个限制条件对象来强制执行 Kubernetes 集群的政策。安装限制条件后,系统会根据该限制条件检查对 API 服务器的请求,如果不符合,则请求会被拒绝。系统将在审核时间报告预先存在的不合规资源。

每个限制条件都有一个限制条件模板支持,该模板定义了限制条件的架构和逻辑。限制条件模板可以来自 Google、第三方,或者您也可以编写自己的模板。如需详细了解如何创建新模板,请参阅编写限制条件模板

准备工作

检查限制条件模板库

定义限制条件时,可以指定其扩展的限制条件模板。默认情况下,系统会安装 Google 开发的通用限制条件模板库,许多组织不需要直接在 Rego 中创建自定义限制条件模板。Google 提供的限制条件模板带有标签 configmanagement.gke.io/configmanagement

如需列出限制条件,请使用以下命令:

kubectl get constrainttemplates \
    -l="configmanagement.gke.io/configmanagement=config-management"

如需描述限制条件模板并检查其必需参数,请使用以下命令:

kubectl describe constrainttemplate CONSTRAINT_TEMPLATE_NAME

您还可以查看库中的所有限制条件模板

定义限制条件

您可以使用 YAML 定义限制条件,而无需了解或编写 Rego。相反,限制条件将调用限制条件模板并为其提供特定于该限制条件的参数。

如果您使用的是结构化代码库,我们建议您在 cluster/ 目录中创建自己的限制条件。

限制条件具有以下字段:

  • 小写的 kind 与限制条件模板的名称匹配。
  • metadata.name 是限制条件的名称。
  • match 字段定义限制条件应用于哪些对象。在对象纳入限制条件范围之前,必须匹配所有指定的条件。match 条件由以下子字段定义:
    • kinds 是限制条件适用的资源种类,由两个字段确定:apiGroups 是将匹配的 Kubernetes API 组列表,而 kinds 是将匹配的种类列表。“*” 匹配所有内容。如果至少一个 apiGroup 和一个 kind 条目匹配,则满足 kinds 条件。
    • scope 接受 *(集群或命名空间),用于确定是否选择集群级和/或命名空间级资源(默认为 *)。
    • namespaces 是对象可以属于的命名空间名称的列表。该对象必须至少属于这些命名空间之一。命名空间资源被视为属于它们自己的资源。
    • excludedNamespaces 是对象不能属于的命名空间的列表。
    • labelSelector 是对象必须满足的 Kubernetes 标签选择器。
    • namespaceSelector 是对象所属命名空间中的标签选择器。如果命名空间不满足该对象,则它将不匹配。命名空间资源被视为属于它们自己的资源。
  • parameters 字段根据限制条件模板需要定义限制条件的参数。

以下名为 ns-must-have-geo 的限制条件调用了名为 K8sRequiredLabels 的限制条件模板,该模板包含在 Google 提供的限制条件模板库中。限制条件定义了限制条件模板用来评估命名空间是否将 geo 标签设置为某个值的参数。

# ns-must-have-geo.yaml

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: ns-must-have-geo
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Namespace"]
  parameters:
    labels:
      - key: "geo"

如需创建限制条件,请使用 kubectl apply -f

kubectl apply -f ns-must-have-geo.yaml

审核限制条件

如果限制条件已正确配置和安装,则其 status.byPod[].enforced 字段会设置为 true,无论限制条件是配置为强制执行还是仅测试限制条件。

默认情况下,系统会强制执行限制条件,并且违反限制条件会阻止给定的集群操作。您可以将限制条件的 spec.enforcementAction 设置为 dryrun,以在 status.violations 字段中报告违规行为,而不会阻止操作。

如需详细了解审核,请参阅使用限制条件进行审核

同步限制条件时的注意事项

同步限制条件时请记住以下注意事项。

最终一致性

您可以向 Git 代码库提交限制条件,并可以使用 ClusterSelectorNamespaceSelector 来限制其效果。由于同步最终是一致的,因此请牢记以下注意事项:

  • 如果集群操作触发了一个限制条件,该限制条件的 NamespaceSelector 引用了尚未同步的命名空间,则系统将强制执行该限制条件并阻止操作。换句话说,缺少的命名空间“失败关闭”。
  • 如果您更改命名空间的标签,则缓存可能会在短时间内包含过时的数据。

尽量减少重命名命名空间或更改其标签的需求,并测试影响重命名或重新添加标签的命名空间的限制条件以确保它们按预期工作。

为参照限制条件配置政策控制器

在启用参照限制条件之前,必须创建一个 Config,用于告知政策控制器要监视的对象种类,例如命名空间。

将以下 YAML 清单保存到文件中,并用 kubectl 进行应用。该清单将政策控制器配置为监视命名空间和 Ingress。在 spec.sync.syncOnly 下用 groupversionkind 创建一个条目,其中包含要监视的每种对象类型的值。

apiVersion: config.gatekeeper.sh/v1alpha1
kind: Config
metadata:
  name: config
  namespace: "gatekeeper-system"
spec:
  sync:
    syncOnly:
      - group: ""
        version: "v1"
        kind: "Namespace"
      - group: "extensions"
        version: "v1beta1"
        kind: "Ingress"

启用参照限制条件

参照限制条件引用其定义中的另一个对象。例如,您可以创建一个限制条件,该限制条件要求集群中的 Ingress 对象具有唯一的主机名。如果限制条件的限制条件模板在其 Rego 中包含字符串 data.inventory,则该限制条件是参照限制条件。

默认情况下,在政策控制器中停用参照限制条件。参照限制条件只能保证最终保持一致,这会带来风险:

  • 在过载的 API 服务器上,政策控制器的缓存内容可能会过时,从而导致参照限制条件“打开失败”,这意味着强制措施似乎在起作用但并非如此。例如,您创建具有重复主机名的 Ingress 速度可能太快了,以至于准入控制器无法检测重复的主机名。

  • 限制条件的安装顺序以及缓存的更新顺序都是随机的。

如果您了解这些风险,但仍想启用对参照限制条件的支持,则可以在 Google Cloud Console 中启用参照限制条件。如需了解详情,请参阅安装 Policy Controller

您还可以在 config-management.yaml 文件中将 policyController.referentialRulesEnabled 设置为 true

apiVersion: configmanagement.gke.io/v1
kind: ConfigManagement
metadata:
  name: config-management
  namespace: config-management-system
spec:
  clusterName: my-cluster
  channel: dev
  policyController:
    enabled: true
    referentialRulesEnabled: true

列出所有限制条件

如需列出集群上安装的所有限制条件,请使用以下命令:

kubectl get constraint

移除限制条件

如需查找使用某个限制条件模板的所有限制条件,请使用以下命令列出与该限制条件模板的 metadata.name 具有相同 kind 的所有对象:

kubectl get CONSTRAINT_TEMPLATE_NAME

要移除限制条件,请指定其 kindname

kubectl delete CONSTRAINT_TEMPLATE_NAME CONSTRAINT_NAME

如果要删除限制条件所使用的限制条件模板,请记下限制条件的 kind

如果移除限制条件,则 API 服务器将限制条件标记为已删除后,限制条件将立即停止强制执行。

移除所有限制条件模板

spec.policyController.templateLibraryInstalled 设置为 false。这可以防止 Anthos Config Management 自动重新安装库。

如需移除所有限制条件模板和所有限制条件,请使用以下命令:

kubectl delete constrainttemplate --all

恢复限制条件模板库

如果停用了限制条件模板库或卸载了所有限制条件模板,则可以通过在 Anthos Config Management 配置中将 spec.policyController.templateLibraryInstalled 设置为 true 来恢复它。

问题排查

创建限制条件模板时出错

如果您看到提及 disallowed ref 的错误,请确认您已启用参照限制条件。例如,如果您在未启用参照限制条件的情况下在限制条件模板中使用 data.inventory,则该错误会如下所示:

admission webhook "validation.gatekeeper.sh" denied the request: check refs failed on module {templates["admission.k8s.gatekeeper.sh"]["MyTemplate"]}: disallowed ref data.inventory...

后续步骤