大家好!这是Kyverno系列文章的第四篇,Kyverno是集群安全的精巧设计者。👷♀️
上一节我们明确理解了Policy和ClusterPolicy的区别。现在,我们将深入探讨在编写策略时定义“此策略将应用于哪些资源,在什么条件下?”的最核心模块:Match和Exclude。
这些模块的运用水平决定了策略的准确性和效率。今天只需投入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)
- Match – All & Any组合:
- kinds: [Pod] (AND) namespaces: [production, staging]
- 即,只有在production或staging命名空间中创建的Pod才受此策略监控。
- Exclude – 各种异常处理:
- 基于权限: 当拥有
system:masters权限的用户(管理员)创建资源时,此规则将被忽略。 - 基于命名空间: 核心系统命名空间如
kube-system、kyverno以及测试用的test-*命名空间不进行检查。 - 基于标签: 如果特定Pod明确带有
allow-unlabeled: "true"标签,则被视为例外。
- Validate – 模式匹配:
?*: 在Kyverno中,此通配符表示“必须存在非空字符串”。
🚀 测试方法
要验证此策略是否正常工作,请尝试创建以下两个文件:
- 失败案例: 尝试在production命名空间中部署没有
team标签的Pod → 创建被阻止 - 成功案例1: 在production命名空间中部署包含
team: dev, env: prod标签的Pod → 创建成功 - 成功案例2: 在test-zone命名空间中部署没有标签的Pod → 由于是排除(Exclude)对象,因此成功
- 成功案例3: 以管理员权限部署没有标签的Pod → 由于是排除(Exclude)对象,因此成功
##
##
🚀 5. 运维人员实用技巧 (Best Practices)
- 明确范围设置: 编写Match条件时应尽可能具体,确保策略仅应用于必要的资源。范围过广可能导致意想不到的副作用。
- 必须排除kube-system: 务必使用Exclude模块将Kyverno、kube-system、kube-public等集群系统相关命名空间从策略应用中排除。否则,可能会导致整个集群停止运行。
- 管理员异常处理: 使用
exclude.subjects为集群管理员(例如:system:masters组)设置例外,使其不受某些策略的约束,这会很方便。 - 检查background: true: 更改Match条件时,不要忘记
background: true设置,以检查策略是否应用于已部署的资源。
🌟 总结
今天,我们详细分析了Kyverno策略的核心瞄准镜——Match和Exclude模块,并学习了如何利用Any和All运算符创建复杂的条件。
如果您能熟练掌握这些模块,将获得强大的能力,能够精确地将所需的安全性规则应用于集群的特定部分。💪
下一次,我们将通过“变量(Variables)应用:Admission Review和ConfigMap数据引用”来探讨如何创建更动态和灵活的策略。如有任何疑问,请随时在评论中留言!😊
发表回复