创建限制条件

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

概览

政策控制器允许您通过定义一个或多个限制条件对象来执行 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。相反,限制条件将调用限制条件模板并为其提供特定于该限制条件的参数。

  • 小写的 kind 与限制条件模板的名称匹配。
  • metadata.name 是限制条件的名称。
  • match 字段定义限制条件应用于哪些对象。在对象成为限制条件范围之前,必须匹配所有指定的条件。match 条件由以下子字段定义:
    • kinds 是限制条件适用的资源类型,由两个字段确定:apiGroups 是将匹配的 Kubernetes API 组列表,而 kinds 是将匹配的类型列表。“*” 匹配所有内容。如果至少一个 apiGroup 和一个 kind 条目匹配,则满足 kinds 条件。
    • 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 字段中报告违规行为,而不会阻止操作。

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

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

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

最终一致性

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

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

最小化重命名命名空间或更改其标签的需求,并测试影响重命名或重新标记的命名空间的限制条件以确保它们按预期工作。

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

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

将以下 YAML 清单保存到文件中,并用 kubectl 进行应用。清单将政策控制器配置为监视命名空间和 Ingresses。在 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,以至于允许准入控制器来检测重复的主机名。

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

如果您了解这些风险,并且仍然希望启用对参照限制条件的支持,请在 Operator 对象中将 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

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。这样可以防止 Operator 自动重新安装库。

要移除所有限制条件模板和所有限制条件:

kubectl delete constrainttemplate --all

恢复限制条件模板库

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

后续步骤