千家信息网

Controller实现ReplicaSetController的示例分析

发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,这篇文章给大家介绍Controller实现ReplicaSetController的示例分析,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Controller的实现基本上都是通过
千家信息网最后更新 2025年02月02日Controller实现ReplicaSetController的示例分析

这篇文章给大家介绍Controller实现ReplicaSetController的示例分析,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

Controller的实现基本上都是通过SharedInformer的结构去监听etcd上某种资源的变更,然后再执行对应的业务逻辑。

以ReplicaSetController为例,介绍一个controller如何与整个manager组合在一起。

controller启动

controllers都是在NewControllerInitializers()方法中引入到manager里的:

func NewControllerInitializers() map[string]InitFunc {

controllers := map[string]InitFunc{}

....

controllers["replicaset"] = startReplicaSetController

....

return controllers

}

startReplicaSetController是启动函数,如下:

func startReplicaSetController(ctx ControllerContext) (bool, error) {

if !ctx.AvailableResources[schema.GroupVersionResource{Group: "extensions", Version: "v1beta1", Resource: "replicasets"}] {

return false, nil

}

// 获取监听ReplicaSets/Pods的Informer

go replicaset.NewReplicaSetController(

ctx.InformerFactory.Extensions().V1beta1().ReplicaSets(),

ctx.InformerFactory.Core().V1().Pods(),

ctx.ClientBuilder.ClientOrDie("replicaset-controller"),

replicaset.BurstReplicas,

).Run(int(ctx.Options.ConcurrentRSSyncs), ctx.Stop)

return true, nil

}

创建过程如下:

// NewReplicaSetController configures a replica set controller with the specified event recorder

func NewReplicaSetController(rsInformer extensionsinformers.ReplicaSetInformer, podInformer coreinformers.PodInformer, kubeClient clientset.Interface, burstReplicas int) *ReplicaSetController {

....

// 初始化controller

rsc := &ReplicaSetController{

kubeClient: kubeClient,

podControl: controller.RealPodControl{

KubeClient: kubeClient,

Recorder: eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "replicaset-controller"}),

},

burstReplicas: burstReplicas,

expectations: controller.NewUIDTrackingControllerExpectations(controller.NewControllerExpectations()),

queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "replicaset"),

}

// 在replica set informer上注册回调handler

rsInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{

AddFunc: rsc.enqueueReplicaSet,

UpdateFunc: rsc.updateRS,

// This will enter the sync loop and no-op, because the replica set has been deleted from the store.

// Note that deleting a replica set immediately after scaling it to 0 will not work. The recommended

// way of achieving this is by performing a `stop` operation on the replica set.

DeleteFunc: rsc.enqueueReplicaSet,

})

rsc.rsLister = rsInformer.Lister()

rsc.rsListerSynced = rsInformer.Informer().HasSynced

// 在pod informer上注册回调

podInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{

AddFunc: rsc.addPod,

// This invokes the ReplicaSet for every pod change, eg: host assignment. Though this might seem like

// overkill the most frequent pod update is status, and the associated ReplicaSet will only list from

// local storage, so it should be ok.

UpdateFunc: rsc.updatePod,

DeleteFunc: rsc.deletePod,

})

rsc.podLister = podInformer.Lister()

rsc.podListerSynced = podInformer.Informer().HasSynced

// syncReplicaSet整个controller实际业务逻辑的入口,会被回调触发

rsc.syncHandler = rsc.syncReplicaSet

return rsc

}

Replica Set资源变更回调

Informer监听到的变更最终会回调到syncReplicaSet方法上,但当中会穿越多个协程,逻辑比较复杂。用一个时序图近似表示如下:

1.Controller变更通知

这里的controller是Informer层的结构,对于资源变更会触发HandleDeltas()方法。HandleDeltas方法会调用sharedProcessor.distribute方法,将Delta传入到processListener的channel上,等待被处理。

2.processorListener.run

run方法会不断拉取listener自己本地channel中的变更,并根据ActionType分发到注册的handler上的不同方法里。

在上文介绍的NewReplicaSetController()函数里,可以看到AddFunc对应的回调函数是enqueueReplicaSet。最终会把delta放入ReplicaSetController自己的queue队列中,等待controller处理。

3.ReplicaSetController.processNextItem

processNextItem方法会处理RepliaSetController.queue当中的变更信息,最终调用syncReplicaSet方法来处理变更,确保Pods和配置一致。

每个Controller的处理逻辑都不相同,但与manager & informer的交互大体类似。

ReplicaSetController的分析中可以再次看出go实现中,调用顺序和传统面向对象语言有很大差异。

关于Controller实现ReplicaSetController的示例分析就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

0