深入理解 client-go 与 controller-runtime:从 informer 到调谐的性能之道

前言 开发 Kubernetes CRD 资源时,绕不开 client-go 的 informer 机制。使用 client-go 本身并不困难——根据 kubebuilder 官网生成调谐框架,然后在 Reconcile方法中添加业务逻辑即可。 然而,只停留在“能用”的层面,很难理解其中的玄妙,出了问题心里没底。有时候代码正常工作了,自己也不清楚为什么能工作(笔者遇到过好几次)。 ...

2026-07-12 · xhy

client-go DeltaFIFO 精讲

0. 介绍 client-go list&watch 精讲 介绍过 Reflector 通过 list&watch 实时获取 Kubernetes 资源的信息。并且作为生产者将资源信息存到 DeltaFIFO 中。 那么消费者是在哪里定义的呢?本文围绕 DeltaFIFO 继续介绍是哪个模块消费了 DeltaFIFO 中的资源。 ...

2024-08-21 · xhy

client-go event handler 精讲

1. 介绍 client-go DeltaFIFO 介绍了从 DeltaFIFO 中取出的资源将被放到 indexer ,接着交由 processorListener 处理。 本文继续看 processorListener 是如何处理 DeltaFIFO pop 的资源的。 2. 启动 handler processorListener 的启动在 sharedIndexInformer.Run() 方法定义: func (s *sharedIndexInformer) Run(stopCh <-chan struct{}) { ... // 开启协程运行 sharedIndexInformer.processor.run 方法 wg.StartWithChannel(processorStopCh, s.processor.run) ... } func (p *sharedProcessor) run(stopCh <-chan struct{}) { func() { p.listenersLock.RLock() defer p.listenersLock.RUnlock() for listener := range p.listeners { // 开启协程运行 processorListener.run p.wg.Start(listener.run) // 开启协程运行 processorListener.pop p.wg.Start(listener.pop) } p.listenersStarted = true }() <-stopCh ... } sharedProcessor.run 的重点在 processorListener.pop 和 processorListener.run,分别介绍如下。 ...

2024-08-21 · xhy

client-go indexer 精讲

1. 介绍 indexer 是 client-go 中的缓存,不同于普通缓存,indexer 是带索引的缓存。 在 client-go DeltaFIFO 精讲 中介绍到 DeltaFIFO 中的元素被加入到 threadSafeMap 中,这个 map 实际是 indexer 的一部分。 indexer 在 client-go 定义为接口,实现该 indexer 接口的是 cache 对象: ...

2024-08-21 · xhy

client-go list & watch 精讲

1. 介绍 client-go 架构 通过 client-go 可以实现访问 kubernetes 资源的实时性,可靠性和顺序性。那么 client-go 是 如何实现的呢? 2. list & watch client-go 通过 list&watch 机制实现实时访问 kubernetes 资源,满足实时性。接下来从源码层面解析 client-go 的 list& watch 机制。 ...

2024-08-21 · xhy

client-go workqueue 精讲

1. 介绍 传递到 event handler 的资源一般不会立即处理,而是先放到 workqueue 中。这是因为业务的处理速度要比资源的更新速度慢。 通过 workqueue 可解耦业务的处理逻辑和资源更新逻辑。 ...

2024-08-21 · xhy

Kubernetes: client-go 源码剖析(二)

上接 Kubernetes: client-go 源码剖析(一) 运行 informer 运行 informer 将 Reflector,informer 和 indexer 组件关联以实现 informer 流程图的流程。 Reflector List&Watch 运行 informer: 1informer.Run(stopCh) 2 3// client-go/tools/cache/shared_informer.go 4func (s *sharedIndexInformer) Run(stopCh <-chan struct{}) { 5 func() { 6 ... 7 // 创建 DeltaFIFO 队列 8 fifo := NewDeltaFIFOWithOptions(DeltaFIFOOptions{ 9 KnownObjects: s.indexer, 10 EmitDeltaTypeReplaced: true, 11 Transformer: s.transform, 12 }) 13 14 cfg := &Config{ 15 Queue: fifo, 16 ListerWatcher: s.listerWatcher, 17 ObjectType: s.objectType, 18 ObjectDescription: s.objectDescription, 19 FullResyncPeriod: s.resyncCheckPeriod, 20 RetryOnError: false, 21 ShouldResync: s.processor.shouldResync, 22 Process: s.HandleDeltas, 23 WatchErrorHandler: s.watchErrorHandler, 24 } 25 26 // 根据 Config 创建 informer 的 controller 27 s.controller = New(cfg) 28 s.controller.(*controller).clock = s.clock 29 s.started = true 30 }() 31 32 ... 33 // goroutine 运行 processor 34 wg.StartWithChannel(processorStopCh, s.processor.run) 35 36 ... 37 // 运行 controller 38 s.controller.Run(stopCh) 39} 首先,创建队列 Delta FIFO: ...

2023-12-16 · xhy

Kubernetes: client-go 源码剖析(一)

前言 在看 kube-scheduler 组件的过程中遇到了 kube-scheduler 对于 client-go 的调用,泛泛的理解调用过程总有种隔靴搔痒的感觉,于是调转头先把 client-go 理清楚在回来看 kube-scheduler。 为什么要看 client-go,并且要深入到原理,源码层面去看。很简单,因为它很重要。重要在两方面: ...

2023-12-16 · xhy