kube-controller分析(五)-QuotaController-v1.5.2
本次分析将介绍ResourceQuotaController。之前我们已经介绍过Kubernetes如何管理配额,但当发生删除操作时,无需经过比较配额,直接删除即可,或者,系统配额与实际情况不一致的情况,这些,都需要一种机制来矫,而这个机制就是ResourceQuotaController。
ResourceQuotaController
ResourceQuotaController定义在/pkg/controller/resourcequota/resource_quota_controller.go中:
|
|
具体字段含义如下:
- kubeClient: kubernetes的client;
- rqIndexer:存储resource quota用;
- rqController: resource quota的controller;
- queue: 缓存待处理的quota的key;
- missingUsageQueue: 缓存Used字段未初始化的quota;
- syncHandler:处理key所对应的quota的方法;
- registry: quota的registry,可以使用registry.Evaluators()来获取所有的evaluator;
- replenishmentControllers: 处理删除,更新后需要进行quota更新的操作。
可以通过NewResourceQuotaController()生成ResourceQuotaController():
|
|
NewResourceQuotaController()流程如下:
- 生成ResourceQuotaController;
- 填充ResourceQuotaController的syncHandler为rq.syncResourceQuotaFromKey;
- 生成quota的NewIndexerInformer,并把indexer和controller赋值给rq.rqIndexer, rq.rqController;
3.1 AddFunc为rq.addQuota()
3.2 UpdateFunc为rq.addQuota()
3.3 DeleteFunc为rq.enqueueResourceQuota() - 生成replenishmentControllers(依据传入的资源列表生成多个replenishmentController)。
ResourceQuotaController::Run()
每个controller必须定义Run()方法,ResourceQuotaController也不例外:
|
|
Run()的流程如下:
- 启动rqController,这些关于quota的变化都会同步到rqIndexer中;
- 启动rq.replenishmentControllers中的replenishmentController;
- 启动workers个worker消费queue中的内容;
- 启动workers个worker消费missingUsageQueue中的内容;
- 启动定时检查所有quota的流程;
- 监听stopCh。
所以,只有给stopCh信号,Run()才会退出。
ResourceQuotaController::worker()
再来看下worker:
|
|
worker的流程就是从queue中获取key,然后调用syncHandler()处理该key,syncHandler()就是rq.syncResourceQuotaFromKey()。
ResourceQuotaController::syncResourceQuotaFromKey()
syncResourceQuotaFromKey()从rqIndexer中通过key获取quota,然后调用syncResourceQuota()处理quota。
|
|
ResourceQuotaController::syncResourceQuota()
|
|
syncResourceQuota()会计算quota对应namespace下资源的使用情况,如果需要更新,则更新quota。
所以,经过syncResourceQuota()处理过的quota就和实际情况保持一致了。
ResourceQuotaController::addQuota()
接着来看IndexerInformer中使用到的addQuota():
|
|
addQuota()会依据情况把quota的key加入到missingUsageQueue或queue中。只要该quota发生了变动,那对该quota进行处理。
ResourceQuotaController::enqueueResourceQuota()
enqueueResourceQuota()只把quota的key加入到queue中。因为不是首次quota处理已经由addQuota()完成,即到enqueueResourceQuota()处理时Used初始化已经完成。
|
|
ResourceQuotaController::enqueueAll()
关于ResourceQuotaController,最后来看下定时处理全部quota的方法enqueueAll():
|
|
enqueueAll()会把rqIndexer中所有的key取出,放到queue中处理。
replenishmentControllerFactory
replenishmentControllerFactory定义在/pkg/controller/resourcequota/replenishment_controller.go中,负责某些资源的Delete或Update检查,进而触发更新quota的操作。ResourceQuotaController是通过调用NewController()来生成replenishmentController的。
replenishmentControllerFactory::NewController()
NewController()会根据不同的资源生成不同的controller。
|
|
这些controller的关键是UpdateFunc,DeleteFunc的设置。以”pod”为例:
|
|
PodReplenishmentUpdateFunc()为UpdateFunc,PodReplenishmentUpdateFunc()会检查oldPod和newPod的,如果oldPod需要纳入计算,但newPod不需要纳入计算了,则触发ReplenishmentFunc()。
|
|
ObjectReplenishmentDeleteFunc()为DeleteFunc,ObjectReplenishmentDeleteFunc()也针对触发ReplenishmentFunc()。
ReplenishmentFunc()
ReplenishmentFunc()其实就是rq.replenishQuota(),从下面代码(定义在resource_quota_controller.go的NewResourceQuotaController()中)可以看出:
|
|
ResourceQuotaController::replenishQuota()
replenishQuota()会依据资源找出需要更新的quota,并调用enqueueResourceQuota()触发处理动作。
|
|
controllermanager
最后来看下controllermanager中对于ResourceQuotaController的调用,代码在/cmd/kube-controller-manager/app/controllermanager.go中:
|
|
所以,可以看出kube-controller监控了”Pod”, “Service”, “ReplicationController”, “PersistentVolumeClaim”, “Secret”, “ConfigMap”这些资源的Update和Delete操作,因为这些资源都和quota相关。