3. 缓存数据结构:缓存键设计原理、缓存值存储格式、TTL与失效策略

Kyverno 配置缓存的底层实现基于 Go 标准库 sync.Map 与自定义的 LRU(Least Recently Used)淘汰逻辑。理解缓存的数据结构是巡检命中率与排查故障的前提。本章从键设计、值存储、TTL 与失效三个维度展开。

3.1 缓存键设计原理

缓存键(Key)采用 复合字符串 拼接方式,确保在集群范围内唯一标识一条策略规则与资源的匹配结果。键的生成遵循以下模板:

cacheKey = policyNamespace + "/" + policyName + "/" + ruleName + "/" + resourceGVK + "/" + resourceName

各字段说明:

字段 来源 示例值 作用
policyNamespace 策略所在命名空间(集群策略为空字符串) kyverno 区分同名策略在不同命名空间
policyName 策略名称 require-labels 定位具体策略
ruleName 策略内规则名称 check-team-label 定位规则级别
resourceGVK 资源的 Group/Version/Kind v1/Pod 区分不同资源类型
resourceName 资源名称 nginx-pod-7f8b9 区分同名资源在不同命名空间
巡检要点: 当缓存命中率异常偏低时,优先检查 resourceGVK 字段是否因 CRD 版本升级导致 GVK 字符串变化(例如 v1beta1 → v1),这会直接导致键不匹配,产生缓存未命中。

3.2 缓存值存储格式

缓存值(Value)是一个结构体,包含策略引擎执行后的完整结果。其核心字段如下:

type CacheEntry struct {
    Result      bool          // 策略是否通过(true=通过,false=拒绝)
    Message     string        // 引擎返回的详细消息
    MatchedRules []string     // 匹配到的规则名称列表
    Timestamp   time.Time     // 缓存写入时间
    TTL         time.Duration // 剩余生存时间
    ResourceVersion string   // 资源对象版本号(用于后续校验)
}

存储格式特点:

  • Result + Message:直接缓存策略判定结果,避免重复执行 CEL 或 JMESPath 表达式。
  • ResourceVersion:记录缓存生成时的资源版本,用于后续 乐观锁校验。若资源实际版本号与缓存中的版本号不一致,则缓存失效。
  • MatchedRules:记录命中哪些规则,便于调试时快速定位。
故障排查案例: 某次巡检发现缓存命中率 100%,但策略执行结果与预期不符。排查发现 ResourceVersion 字段在缓存写入后未被更新,导致旧版本结果被重复使用。解决方案:在资源更新事件中强制清除对应缓存条目。

3.3 TTL 与失效策略

Kyverno 缓存采用 两级失效机制:基于时间的 TTL 失效 + 基于事件的主动失效。

3.3.1 TTL 配置

参数 默认值 说明
--cacheTTL 5m(5 分钟) 缓存条目最大生存时间,超过后自动失效
--cacheCleanupInterval 1m(1 分钟) 后台清理协程扫描间隔,删除过期条目

TTL 从缓存写入时开始计时,到期后条目标记为 “过期”,在下一次清理周期中被删除。过期条目被访问时,Kyverno 会重新执行策略引擎并更新缓存。

3.3.2 事件驱动失效

以下事件会触发缓存条目的 主动失效:

  • 资源更新/删除:对应资源的 ResourceVersion 变化,缓存条目立即失效。
  • 策略更新:策略内容(规则表达式、参数)变更,所有关联该策略的缓存条目失效。
  • 命名空间变更:命名空间标签或注解变化,影响策略匹配范围,相关缓存失效。
  • 手动清除:通过 kyverno cache clear 命令或 API 接口强制清空缓存。
常见陷阱: 当集群中存在大量高频更新的资源(如 ConfigMap 或 Secret)时,事件驱动失效可能导致缓存频繁重建,实际命中率下降。此时应适当增大 --cacheTTL 值(如 15m),并配合 --cacheCleanupInterval 调整清理频率。

3.4 缓存数据结构总览

下图展示了缓存键、值、TTL 与失效策略的整体关系:

Kyverno 缓存数据结构总览 缓存键(Key) policyNamespace + "/" + policyName + "/" + ruleName + "/" + resourceGVK + "/" + resourceName 示例:kyverno/require-labels/ check-team-label/v1/Pod/nginx-pod 唯一标识一条策略规则与资源的匹配 缓存值(Value) Result: bool(通过/拒绝) Message: string(引擎消息) MatchedRules: []string Timestamp: time.Time TTL: time.Duration ResourceVersion: string 缓存策略执行结果 + 版本校验信息 TTL 与失效策略 基于时间的 TTL 失效 --cacheTTL: 5m(默认) --cacheCleanupInterval: 1m 后台协程定期扫描过期条目 过期后重新执行策略引擎 适用于低频变更资源 基于事件的主动失效 资源更新/删除 → 版本号变化 策略更新 → 规则表达式变更 命名空间变更 → 匹配范围变化 手动清除 → kyverno cache clear 适用于高频变更资源 TTL 字段控制

3.5 缓存失效流程

下图展示了缓存条目从写入到失效的完整生命周期:

缓存失效生命周期 策略引擎执行 写入缓存 TTL 到期(后台清理) 事件触发(资源/策略变更) 缓存条目删除
最佳实践: 对于变更频繁的资源(如 Deployment 的 replicas 字段),建议将 --cacheTTL 设置为 1m 以减少过期数据使用时间;对于稳定资源(如 Namespace),可设置为 30m 以提升命中率。