Kyverno

Kyverno选择资源

2022-09-27  本文已影响0人  王勇1024

策略配置

策略中所有规则的通用配置。

策略包含一个或多个规则,以及适用于策略中所有规则的以下常见设置:

使用 kubectl explain policy.spec 获取有关策略 schema 的命令行帮助。

选择资源

使用 match 和 exclude 过滤和选择资源。

matchexclude 控制策略应用于哪些资源。

matchexclude 子句具有相同的结构,并且每个子句只能包含以下两个元素之一:

资源过滤器

可以在 any 或 all 子句下指定以下资源过滤器。

注意:直接在 matchexclude 下指定资源过滤器已被标记为弃用,并将在未来的版本中删除。 强烈建议您在 anyall 块下指定它们。

必须在 match.(any/all).resources.kindsexclude 块中指定至少一个元素。使用 resources 元素时必须指定 kind 属性。在 match.(any/all).resources.kinds 字段中可以指定通配符(*)。

此外,用户可以在策略规则的 match / exclude 声明中使用 kind 指定 group 和 apiVersion。

支持的格式:

为了解决 kind 命名冲突,需指定 API group 和 version。例如,Kubernetes API、Calico 和 Antrea 都注册了一个名为 NetworkPolicy 的 Kind。

这些可以区分为:

通配符支持的格式:

注意:

可以使用 /. 作为父资源和子资源之间的分隔符。例如,Pods/statusPods.status 会匹配到子资源。

当 Kyverno 收到 AdmissionReview 请求(即,来自 validation 或 mutation webhook)时,它首先检查资源和用户信息是否匹配或是否应从处理中排除。如果两项检查都通过,则将规则逻辑应用于变更、验证或生成资源。

match 声明

在任意 rule 声明中,必须有一个 match 语句作为即将应用的规则的过滤器。尽管 match 声明可能会很复杂,并有多个不同的元素,但至少要有一个。match 声明中最常见的元素类型是 Kubernetes 类型过滤器,例如 Pods, Deployments, Services, Namespaces 等。matchexclude声明中还不支持变量替换。match 声明也需要一个 anyall 表达式来实现更灵活的多条件处理。

在这个片段中,match 语句匹配所有名称为“staging”或在“prod”命名空间中的 Service。

spec:
  rules:
  - name: no-LoadBalancer
    match:
      any:
      - resources:
          kinds: 
          - Service
          names: 
          - "staging"
      - resources:
          kinds: 
          - Service
          namespaces:
          - "prod"

通过 match 声明中多个元素组合,您可以更有选择性地选择要处理的资源。此外,还支持通配符以实现更好的控制。例如,通过添加 resources.names 字段,前面的 match 声明可以进一步筛选名称以“prod-”开头名称是“staging”的Service。resources.names 可接收一组名称,

将匹配所有具有任何一个这些名称的资源。

spec:
  rules:
  - name: no-LoadBalancer
    match:
      any:
      - resources:
          names: 
          - "prod-*"
          - "staging"
          kinds:
          - Service
      - resources:
          kinds:
          - Service
        subjects:
        - kind: User
          name: dave

match.any[0] 会匹配到名称以“prod-”开头是“staging”的、而不是以“dev-”或其它前缀开头的 Service。match.any[1] 会匹配到所有由用户 dave 创建的 Service,而不管 Service 名称。由于这两个是在 any 关键字下指定的,所以,整个规则会作用在所有名称以“prod-”开头是“staging”的由用户 dave 创建的 Service。matchexclude 声明中都支持通配符,从而使选择更加灵活。

注意:Kyverno 也支持 resources.name ,允许你传入单个名称,而不是一个列表,但是 resources.name 已被弃用,取而代之的是 resources.names,并将在未来的版本中删除。

在这个片段中,match 声明只会匹配 group 为 networking.k8s.io,version 是 v1,kind 是 NetworkPolicy 的资源。通过在 match 声明中添加 Group、Version、Kind,您可以更有选择性地选择要处理的资源。

spec:
  rules:
  - name: no-LoadBalancer
    match:
      any:
      - resources:
          kinds:
          - networking.k8s.io/v1/NetworkPolicy

通过在 version/kind 格式中指定 kind,仅匹配资源种类的特定版本。

spec:
  rules:
  - name: no-LoadBalancer
    match:
      any:
      - resources:
          kinds:
          - v1/NetworkPolicy

Kyverno 1.5.0之后,kinds 字段支持通配符,允许您匹配集群中的每种资源类型。选择器标签支持以下路径中的键和值的通配符(* 或?)。

支持的格式:

在以下策略中,检查所有资源类型是否存在具有键 app.kubernetes.io/name 标签。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-labels
spec:
  validationFailureAction: audit
  background: false
  rules:
  - name: check-for-labels
    match:
      any:
      - resources:
          kinds:
          - "*"
    preconditions:
      any:
      - key: "{{ request.operation }}"
        operator: Equals
        value: CREATE
    validate:
      message: "The label `app.kubernetes.io/name` is required."
      pattern:
        metadata:
          labels:
            app.kubernetes.io/name: "?*"

注意

请记住,在匹配所有类型 (*) 时,您编写的策略必须适用于所有类型。这种通配符匹配的典型用途是 metadata 对象中的元素。

下面是 match 声明的其它一些示例。

匹配有指定标签的 Deployment 或 StatefulSet

这个示例是选择有一个有 app=critical 标签的 Deployment StatefulSet。

resources 块中的条件检查逻辑遵循“跨类型取和,列表内取或”。例如,如果规则匹配包含 kind 列表和 namespace 列表,如果请求包含任何一个 (OR) kind AND 任何一个 (OR) namespace,则将评估该规则。clusterRoles、roles 和 subjects 中的条件总数用逻辑 OR 评估,因为每个请求只能有这些值的一个实例。

下面的片段中,kinds 和 selector 是对等/兄弟元素,所以会被 AND 在一起。

spec:
  rules:
    - name: match-critical-app
      match:
        any:
        # kinds 和 namespaceSelector 是 AND 关系
        - resources:
            # kinds 列表内是 OR 的关系
            kinds:
            - Deployment
            - StatefulSet
            selector:
              matchLabels:
                app: critical

可以利用此模式对资源的选择进行非常细粒度的控制,例如,下面的片段中 match 包含了resources、subjects、roles 和 clusterRoles 多种元素。

match 声明进阶

spec:
  # validationFailureAction 当策略执行失败时,控制准入控制器的行为:
  # - 'enforce':中断资源的创建或变更
  # - 'audit':允许资源更新并上报策略违规行为
  validationFailureAction: enforce
  # 每个策略都有一个按声明顺序应用的规则列表
  rules:
    # Rules 必须有唯一的名称
    - name: "check-pod-controller-labels"
      # 每个规则会匹配其 "match" 字段在声明中指定的资源
      match:
        resources:
          kinds: # 必需,kind 列表
          - Deployment
          - StatefulSet
          # 可选的,资源名称。 支持通配符 (* 和 ?)
          names: 
          - "mongo*"
          - "postgres*"
          # 可选的,namespace 列表。支持通配符 (* 和 ?)
          namespaces:
          - "dev*"
          - test
          # 可选的,标签选择器。值支持通配符(* 和 ?)
          selector:
              matchLabels:
                  app: mongodb
              matchExpressions:
                  - {key: tier, operator: In, values: [database]}
        # 可选的,要匹配的用户或 service accounts
        subjects:
        - kind: User
          name: mary@somecorp.com
        # 可选的,要匹配的 roles
        roles:
        # 可选的,要匹配的 clusterroles
        clusterRoles: 
        - cluster-admin

注意

尽管上面的代码片段对于显示您可以使用的匹配类型很有用,但大多数策略在其匹配语句中使用一个或几个不同的元素。

使用标签匹配命名空间中的 Deployments

这个例子使用 namespaceSelector 匹配 namespace 中包含 type=connector 或 type=compute 标签的Deployments。

这里, kinds 和 namespaceSelector 是 match.resources 下的对等元素,并使用逻辑 AND 操作进行评估。

spec:
  rules:
    - name: check-min-replicas
      match:
        any:
        # AND across resources and selector
        - resources:
            # OR inside list of kinds
            kinds:
            - Deployment
            namespaceSelector:
              matchExpressions:
                - key: type 
                  operator: In
                  values: 
                  - connector
                  - compute

组合 match 和 exclude

策略规则选择的资源,必须满足所有 match 和 exclude 条件。换句话说,match 和 exclude 条件是按逻辑 AND 评估的。exclude 块中的元素遵循与 match 块中相同的规范。

排除 cluster-admin ClusterRole

这是一个匹配所有非 cluster-admin ClusterRole 创建的 Pod 的规则。

spec:
  rules:
    - name: match-pods-except-cluster-admin
      match:
        any:
        - resources:
            kinds:
            - Pod
      exclude:
        any:
        - clusterRoles:
          - cluster-admin

排除 kube-system namespace

这个规则会匹配除 kube-system namespace 外的所有 Pod。

注意:从 Kyverno 1.3.0 开始支持按名称排除指定的 namespace。

spec:
  rules:
    - name: match-pods-except-admin
      match:
        any:
        - resources:
            kinds:
            - Pod
      exclude:
        any:
        - resources:
            namespaces:
            - kube-system

匹配标签并排除用户和角色

下面的示例会匹配所有包含 app=critical 标签、并排除有 ClusterRole cluster-admin 或用户 John 创建的资源。

注意

由于 roles 和 clusterRoles 是由 Kyverno 从 AdmissionReview 内部构建的,包含这些声明的规则必须定义 background: false,因为 AdmissionReview 在 background 模式不可用。

spec:
  rules:
    - name: match-criticals-except-given-rbac
      match:
        any:
        - resources:
            kind:
            - Pod
            selector:
              matchLabels:
                app: critical
      exclude:
        any:
        - clusterRoles:
          - cluster-admin
        - subjects:
          - kind: User
            name: John

匹配标签并排除用户

上述示例的变体,此代码段使用 any 和 all 声明来排除多个用户。

spec:
  validationFailureAction: enforce
  background: false
  rules:
    - name: match-criticals-except-given-users
      match:
        all:
        - resources:
            kinds:
            - Pod
            selector:
              matchLabels:
                app: critical
      exclude:
        any:
        - subjects:
          - kind: User
            name: susan
          - kind: User
            name: dave

使用 Annotation 匹配所有 Pod

匹配所有包含 imageregistry: "https://hub.docker.com/" 注解的 Pod。

spec:
  rules:
    - name: match-pod-annotations
      match:
        any:
        - resources:
            annotations:
              imageregistry: "https://hub.docker.com/"
            kinds:
              - Pod
上一篇下一篇

猜你喜欢

热点阅读