kubernetes中list-watch机制

Kubernetes 中的 List-Watch 是一种用于实现组件间异步数据同步和解耦的核心机制。

核心概念List:

调用资源的 list API 获取当前所有资源的全量(静态)数据,基于 HTTP 短链接实现。Watch:调用资源的 watch API 监听后续资源的变更事件(如创建、更新、删除),基于 HTTP 长链接(Chunked Transfer)实现。

工作流程与优势

  • 初始化全量获取:组件启动时先通过 List 获取资源的全部当前状态,建立基础数据集。
  • 增量实时监听:全量获取完成后,无缝转入 Watch 状态,只接收和处理发生变化的增量数据,保证了消息的实时性、顺序性和可靠性。
  • 高效解耦:通过该机制,像 知乎专栏上的K8S设计精髓解析 所述,各组件与 API Server 之间保持异步通信,大幅降低了系统耦合度。

详细解读(摘自github):

当kubectl创建了ReplicaSet对象后,controller-manager都是通过list-watch这种方式得到了最新的ReplicaSet对象,并执行自己的逻辑来创建Pod对象

其他的几个组件,Scheduler/Kubelet也是一样,通过list-watch得知变化并进行处理。

list-watch机制

kubernetes系统的采取Level Trigger而非Edge Trigger的设计理念,所以各组件只需要感知数据最新的状态,而不需要担心错过数据的变化过程。

list-watach机制需要满足以下需求:

实时性(即数据变化时,相关组件越快感知越好)

保证消息的顺序性(即消息要按发生先后顺序送达目的组件。很难想象在Pod创建消息前收到该Pod删除消息时组件应该怎么处理)

保证消息不丢失或者有可靠的重新获取机制(比如说kubelet和kube-apiserver间网络闪断,需要保证网络恢复后kubelet可以收到网络闪断期间产生的消息)

list-watch由list和watch组成,list调用资源的list API罗列资源,基于HTTP短链接实现。 watch调用资源的watch API监听资源变更事件,基于HTTP 长链接实现。

当客户端调用 watch API 时,apiserver 在 response 的 HTTP Header 中设置 Transfer-Encoding 的值为 chunked,表示采用分块传输编码,客户端收到该信息后,便和服务端该链接,并等待下一个数据块,即资源的事件信息。

为了满足1,2要求, kubernetes中为每一个REST数据加了一个ResourceVersion字段,并且该字段的值由ETCD来保证全局单调递增(当ETCD中写入一个数据时,全局ResourceVersion就加1)。这样就保证了不同时刻的数据ResourceVersion不同,并且后产生数据的ResourceVersion较之前数据的ResourceVersion大。这样客户端发起watch请求时,只需要带上请求数据在本地缓存中的最新ResourceVersion,而服务端就根据ResourceVersion从小到大把 大于客户端ResourceVersion的数据按顺序推送给客户端即可。这样就保证了推送数据的顺序性。

list-watch流程

为了满足3要求, watch请求开始之前,先发起一次list请求,获取集群中当前所有该类数据(同时得到最新的ResourceVersion),之后基于最新的ResourceVersion发起watch请求, 当watch出错时(比如说网络闪断造成客户端和服务端数据不同步),重新发起一次list请求获取所有数据,再重新基于最新ResourceVersion来watch.

informer机制

K8S 的 informer 模块封装 list-watch API,用户只需要指定资源,编写事件处理函数,AddFunc, UpdateFunc 和 DeleteFunc 等。如下图所示,informer 首先通过 list API 罗列资源,然后调用 watch API 监听资源的变更事件,并将结果放入到一个 FIFO 队列,队列的另一头有协程从中取出事件,并调用对应的注册函数处理事件。Informer 还维护了一个只读的 Map Store 缓存,主要为了提升查询的效率,降低 apiserver 的负载。

参考文献:kubernetes中list-watch机制

相关推荐
分布式存储与RustFS11 小时前
Terraform 状态文件老在本地丢、并发还撞锁:把 state 锁进 RustFS
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
csdn_aspnet11 小时前
macOS 10 、Docker 玩轉 MySQL
运维·mysql·macos·docker·容器·mac
对象存储与RustFS12 小时前
Jenkins 的构建产物别堆在控制器磁盘:用 RustFS 当它的 S3 工件仓库
后端·docker·云原生
罗小爬EX1 天前
Helm 从概念到实战:以一个普通 Web 应用为例
云原生·helm
java_logo1 天前
Docker 部署 DeepSeek Harness(moelin):轻松搭建带登录的本地 AI Agent 平台
运维·docker·容器·ai agent·deepseek·harness·轩辕镜像
xbzb1 天前
容器 IP 每次重建都变?docker network 五种模式与自定义网桥固定地址
网络·docker·容器·ip·network·固定
打工仔折腾 AI1 天前
Changedetection.io 网页变动监控:Docker 部署、通知配置与公网暴露实践
运维·人工智能·后端·python·docker·容器·性能优化
fengkai45451 天前
Prometheus+K8s弹性伸缩综合项目
运维·kubernetes·k8s·prometheus·hpa·vpa
分布式存储与RustFS2 天前
镜像仓库的层别只堆本地盘:用 RustFS 给 Harbor 当 S3 后端
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
分布式存储与RustFS2 天前
工作流脚本和依赖 JAR 散在各节点本地盘:用 DolphinScheduler 资源中心接到 RustFS
运维·云原生·开源·对象存储·分布式存储·s3·性能基准