Kyverno策略的精巧设计: Match/Exclude与Any/All完整指南 🎯

大家好!这是Kyverno系列文章的第四篇,Kyverno是集群安全的精巧设计者。👷‍♀️

上一节我们明确理解了Policy和ClusterPolicy的区别。现在,我们将深入探讨在编写策略时定义“此策略将应用于哪些资源,在什么条件下?”的最核心模块:MatchExclude

这些模块的运用水平决定了策略的准确性和效率。今天只需投入10分钟,即可成为Kyverno策略编写大师!🚀


🏗️ 1. Match和Exclude模块:策略的瞄准镜 🎯

Match和Exclude作为过滤器,决定了Kyverno策略将应用于哪些资源(Match),以及将排除哪些资源(Exclude)。两者结构相同,定义在策略的spec.rules之下。

🔹 Match模块(包含条件)

定义策略将应用于的资源的条件。所有指定的条件都必须匹配,策略才会触发。

🔸 Exclude模块(排除条件)

即使资源匹配Match条件,如果它也匹配Exclude条件,则将从策略应用中排除。这对于处理特定异常情况非常有用。


💻 2. 基于资源的Match / Exclude:最基本的过滤

这是最常用的过滤方式,基于资源的种类、名称、命名空间、标签等。

① kinds: 指定资源种类 📦

明确指定策略将应用于哪种Kubernetes资源。

  • Pod, Deployment, ConfigMap, Secret等

② names: 指定资源名称 📛

用于仅对特定名称的资源应用或排除策略。

  • 支持使用通配符( extit)(例如:test- extit等)

③ namespaces: 指定命名空间 🏘️

用于仅对特定命名空间内的资源应用或排除策略。

  • 排除kube-system等重要系统命名空间时必不可少!

④ labelSelector: 基于标签的过滤 🏷️

根据资源上附加的标签进行过滤。

⑤ annotationSelector: 基于注解的过滤 📝

根据资源上附加的注解进行过滤。

代码中的基于资源的过滤示例

YAML

# 示例: 在"production"命名空间中名为"nginx"的Pod中,
#       排除带有"env: dev"标签的Pod并应用策略
rules:
- name: example-policy
  match:
    any:
    - resources:
        kinds: ["Pod"]
        namespaces: ["production"]
        names: ["nginx-*"]
  exclude:
    any:
    - resources:
        labelSelector:
          matchLabels:
            env: dev

👥 3. 基于用户和角色的Match / Exclude:基于行为者的过滤

根据哪个用户、哪个服务账户或哪个组创建资源来应用策略。

① users: 指定特定用户 🧑‍💻

基于特定用户(例如:kubernetes-admin)或服务账户(例如:system:serviceaccount:default:default)。

② roles: 基于角色(Role)的指定 🎭

基于拥有特定Role或ClusterRole的用户。

③ clusterRoles: 基于集群角色(ClusterRole)的指定 👑

基于拥有集群范围ClusterRole的用户。

代码中的基于用户/角色的过滤示例

YAML

# 示例: 排除"kube-admin"用户创建的资源的策略
#       (管理员例外处理)
rules:
- name: exclude-admin-user
  exclude:
    any:
    - subjects:
      - kind: User
        name: kube-admin
    - subjects:
      - kind: Group # Kubernetes组 (例如: system:masters)
        name: system:masters

🤝 4. 利用Any和All运算符处理复杂逻辑

在Match和Exclude模块中组合多个条件时,使用Any和All运算符。这与逻辑运算中的OR和AND概念相同。

🔹 Any: OR条件(只要有一个为真即为True)

any下所列条件中,只要有一个匹配,则整个any模块为True。

YAML

# 示例: 如果"production"或"staging"命名空间中有一个匹配,则Match
match:
  any:
  - resources:
      namespaces: ["production"]
  - resources:
      namespaces: ["staging"]

🔸 All: AND条件(所有都必须为真才为True)

all下所列条件全部匹配,则整个all模块为True。

YAML

# 示例: 匹配是"Pod"且带有"app=nginx"标签的资源
match:
  all:
  - resources:
      kinds: ["Pod"]
  - resources:
      labelSelector:
        matchLabels:
          app: nginx

💡 Any和All的混合使用

可以嵌套这两个运算符来创建复杂的条件。

YAML

# 示例: 位于"production"命名空间中且是"Pod"或"Deployment"的资源
match:
  all: # AND条件
  - resources:
      namespaces: ["production"]
  - any: # OR条件
    - resources:
        kinds: ["Pod"]
    - resources:
        kinds: ["Deployment"]

🛡️ Kyverno综合策略示例 (ClusterPolicy)

此策略包含复杂的逻辑,它在整个集群中1) 阻止创建没有特定标签的Pod,但2) 将管理员组、特定命名空间或带有特定标签的资源作为例外处理。

YAML

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: comprehensive-pod-security
  annotations:
    policies.kyverno.io/title: "Match, Exclude, and Complex Logic Example"
    policies.kyverno.io/description: "Example policy using any/all logic with resource and subject filters."
spec:
  # 'Enforce'在违反规则时立即阻止创建。
  validationFailureAction: Enforce
  # 即使对于已运行的资源,也会执行后台扫描。
  background: true
  rules:
  - name: check-team-and-env-labels
    # [Match块] 策略应用目标设置
    match:
      all: # 以下条件必须'全部'满足 (AND)
      - resources:
          kinds:
          - Pod
      - any: # 以下条件中'至少一个'满足即可 (OR)
        - resources:
            namespaces:
            - production
            - staging
    
    # [Exclude块] 策略排除目标设置
    exclude:
      any: # 如果以下条件中'至少一个'适用,则排除策略应用 (OR)
      - subjects:
        - kind: Group
          name: system:masters # 集群管理员组例外
      - resources:
          namespaces:
          - kube-system
          - kyverno
          - "test-*" # 排除所有以'test-'开头的命名空间
          labelSelector:
            matchLabels:
              allow-unlabeled: "true" # 如果存在特定标签则例外

    # [Validate块] 实际验证规则
    validate:
      message: "The labels 'team' and 'env' are mandatory for production/staging pods."
      pattern:
        metadata:
          labels:
            team: "?*" # 'team' 标签必须存在
            env: "?*"  # 'env' 标签必须存在

📋 代码详细分析 (Logic Breakdown)

  1. Match – All & Any组合:
  • kinds: [Pod] (AND) namespaces: [production, staging]
  • 即,只有在production或staging命名空间中创建的Pod才受此策略监控。
  1. Exclude – 各种异常处理:
  • 基于权限: 当拥有system:masters权限的用户(管理员)创建资源时,此规则将被忽略。
  • 基于命名空间: 核心系统命名空间如kube-systemkyverno以及测试用的test-*命名空间不进行检查。
  • 基于标签: 如果特定Pod明确带有allow-unlabeled: "true"标签,则被视为例外。
  1. Validate – 模式匹配:
  • ?*: 在Kyverno中,此通配符表示“必须存在非空字符串”。

🚀 测试方法

要验证此策略是否正常工作,请尝试创建以下两个文件:

  • 失败案例: 尝试在production命名空间中部署没有team标签的Pod → 创建被阻止
  • 成功案例1: 在production命名空间中部署包含team: dev, env: prod标签的Pod → 创建成功
  • 成功案例2: 在test-zone命名空间中部署没有标签的Pod → 由于是排除(Exclude)对象,因此成功
  • 成功案例3: 以管理员权限部署没有标签的Pod → 由于是排除(Exclude)对象,因此成功

##

##

🚀 5. 运维人员实用技巧 (Best Practices)

  1. 明确范围设置: 编写Match条件时应尽可能具体,确保策略仅应用于必要的资源。范围过广可能导致意想不到的副作用。
  2. 必须排除kube-system: 务必使用Exclude模块将Kyverno、kube-system、kube-public等集群系统相关命名空间从策略应用中排除。否则,可能会导致整个集群停止运行。
  3. 管理员异常处理: 使用exclude.subjects为集群管理员(例如:system:masters组)设置例外,使其不受某些策略的约束,这会很方便。
  4. 检查background: true: 更改Match条件时,不要忘记background: true设置,以检查策略是否应用于已部署的资源。

🌟 总结

今天,我们详细分析了Kyverno策略的核心瞄准镜——MatchExclude模块,并学习了如何利用AnyAll运算符创建复杂的条件。

如果您能熟练掌握这些模块,将获得强大的能力,能够精确地将所需的安全性规则应用于集群的特定部分。💪

下一次,我们将通过“变量(Variables)应用:Admission Review和ConfigMap数据引用”来探讨如何创建更动态和灵活的策略。如有任何疑问,请随时在评论中留言!😊



Comments

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注