Kubernetes v1.36:陈旧性缓解与控制器的可观测性

发布: (2026年4月29日 GMT+8 02:35)
9 分钟阅读

Source: Kubernetes Blog

Kubernetes 控制器中的陈旧性

Kubernetes 控制器中的陈旧性是一个影响许多控制器的问题,可能以微妙的方式影响控制器的行为。
通常要等到为时已晚才被发现——当生产环境中的控制器已经采取了错误的操作时——因为控制器作者所做的一个基本假设被证明是错误的。

陈旧性导致的典型问题包括:

  • 控制器采取 错误的操作
  • 控制器在应该采取行动时 未采取行动
  • 控制器 响应过慢

我很高兴地宣布 Kubernetes v1.36 包含了帮助缓解控制器陈旧性并提供更好可观测性的全新特性。

什么是陈旧性?

陈旧性在控制器中来自于控制器缓存中对世界的过时视图。为了提供快速的用户体验,控制器通常维护一个本地缓存,存放集群状态。该缓存通过监听 Kubernetes API 服务器上控制器关心的对象的变化来填充。当控制器需要采取行动时,它首先检查缓存中的最新信息;如果缓存已过期,控制器会通过监听 API 服务器来更新缓存。此过程称为调和

缓存何时会变得过时?

  • 控制器重启 – 必须从头重建缓存,期间会有缓存陈旧的窗口。
  • API‑server 宕机 – 缓存无法刷新,控制器只能基于陈旧数据运行。
  • 其他边缘情况 – 如网络分区、Informer 延迟或大量事件突发。

在上述任何期间,控制器可能无法正确行动。

Source:

v1.36 版本的改进

Kubernetes v1.36 在 client‑gokube‑controller‑manager 中高度竞争的控制器实现上都带来了增强,利用了 client‑go 的新功能。

client‑go 改进

  • 原子 FIFO 处理(特性开关 AtomicFIFO)——基于现有的 FIFO 队列实现。

    • 队列现在能够原子地处理批量收到的操作(例如 informer 用来填充缓存的对象初始列表)。
    • 即使事件顺序错乱,也能保证队列保持一致状态。
  • 缓存自省——在 Store 接口上新增的方法:

// LastStoreSyncResourceVersion returns the latest resource version that the store has observed.
func (s *Store) LastStoreSyncResourceVersion() string
  • 控制器可以使用该方法获取缓存最近观察到的资源版本,从而为 kube‑controller‑manager 中的防陈旧特性提供依据。

kube‑controller‑manager 改进

v1.36 发行版默认让 四个 控制器使用新能力:

控制器特性开关
DaemonSetStaleControllerConsistencyDaemonSet
StatefulSetStaleControllerConsistencyStatefulSet
ReplicaSetStaleControllerConsistencyReplicaSet
JobStaleControllerConsistencyJob
  • 通过将相应的特性开关设为 false 可以关闭该功能。
  • 当特性开关开启时,控制器会在执行任何操作前先检查缓存的 最新资源版本
    • 如果缓存的版本 低于 控制器已经写入 API Server 的对象版本,则控制器 不执行操作——因为它的视图已经过时。

对 Informer 作者的使用建议

Informer 作者可以立即受益于这些改进。下面示例展示了 ReplicaSet informer 如何使用该新特性。

type ConsistencyStore interface {
    // WroteAt records that the given object was written at the given resource version.
    WroteAt(owningObj runtime.Object, uid types.UID,
            groupResource schema.GroupResource, resourceVersion string)

    // EnsureReady returns true if the cache is up‑to‑date for the given object.
    // It is used prior to taking any reconciliation action.
    EnsureReady(owningObj runtime.Object, uid types.UID,
                groupResource schema.GroupResource) bool
}
  • ReplicaSet 控制器会同时跟踪 ReplicaSet 本身的资源版本 以及 它管理的 Pod 的资源版本。
  • 对于特定的 ReplicaSet,控制器记录其 Pod 的最新写入资源版本以及对 ReplicaSet 本身的任何写入。
  • 如果缓存的最新版本低于控制器已经写入的版本,控制器会因为视图陈旧而不进行操作。

Informer 作者可以利用 ConsistencyStore 来:

  1. 记录写入WroteAt)——在写入发生时记录。
  2. 检查新鲜度EnsureReady)——在处理事件前进行检查。

这种模式确保控制器仅在信息是最新的情况下才执行操作,从而降低因状态陈旧导致的 bug 风险。

一致性存储接口

type ConsistencyStore interface {
    // WroteAt records the latest resource version that the controller has written
    // to the API server for a given object.
    // * `owningObj` – the object being reconciled.
    // * `uid` – UID of the owning object.
    // * `resourceVersion` – the resource version just written.
    // * `groupResource` – the GroupResource of the object.
    WroteAt(owningObj client.Object, uid types.UID,
        resourceVersion string, groupResource schema.GroupResource)

    // EnsureReady checks whether the cache is up‑to‑date for the given object.
    // It is called before reconciliation to decide whether to proceed.
    // Returns `true` if the cache is current, otherwise `false`.
    EnsureReady(namespacedName types.NamespacedName) bool

    // Clear removes the given object from the consistency store.
    // It is used when an object is deleted.
    Clear(namespacedName types.NamespacedName, uid types.UID)
}

函数说明

函数目的细节
WroteAt记录控制器写入的最新资源版本。- 在控制器向 API Server 写入对象后调用。
- 跟踪 owningObj、其 uid、写入的 resourceVersion 以及对象的 GroupResource
- 只存储版本信息,不保留对象本身。
EnsureReady在进行调和前验证缓存是否是最新的。- 在调和之前调用。
- 如果缓存反映了最新版本(由 WroteAt 记录),返回 true,否则返回 false
Clear当对象被删除时从存储中移除对应条目。- 防止存储无限增长。
- 使用对象的 UID 区分已删除的对象和同名的新创建对象。
- EnsureReady 并不依赖此函数,只关心最新的版本信息。

有了这三个函数,Informer 编写者即可在其控制器中实现 陈旧性缓解

可观测性

Kubernetes 在 v1.36 中为 kube‑controller‑manager 添加了相关的仪表化。
这些指标默认启用,并通过相同的功能门控进行控制。

指标

指标描述
stale_sync_skips_total控制器因缓存陈旧而跳过同步的次数。对使用陈旧缓解特性的每个控制器在其子系统下进行暴露。
store_resource_version暴露每个共享 informer 的最新资源版本。
标签: group, version, resource
允许您将 informer 缓存版本与 API 服务器的版本进行比较,以检测陈旧性。

这些指标可通过 kube‑controller‑manager 指标端点获取。

接下来是什么?

  • SIG API Machinery 将继续发展此功能,并在更多控制器中推广其采用。
  • 欢迎提供反馈——请在下方评论或在 Kubernetes GitHub repository 上打开 issue。
  • 正在与 controller‑runtime 合作,将这些语义暴露给所有使用它构建的控制器,使每个控制器都具备“read‑your‑own‑writes” 能力,而无需额外的实现工作。
0 浏览
Back to Blog

相关文章

阅读更多 »