Skip to content

Latest commit

 

History

History
104 lines (85 loc) · 3.75 KB

File metadata and controls

104 lines (85 loc) · 3.75 KB

PersistentVolumeController

在 Kube Controller Manager 中有一个名为 PersistentVolumeController 的 Controller 用于维护 PV 和 PVC 的状态。代码位于 pkg/controller/volume/persistentvolume。它会对 PV 和 PVC 对象分别进行处理以达到用户的最终期望状态。

下面先来看它的内部结构:

type PersistentVolumeController struct {
    ...
	volumeQueue *workqueue.Type
	claimQueue  *workqueue.Type
    ...
}

在 PersistentVolumeController 中有两个队列分别用来存储需要处理的 PV 和 PVC 对象。

在创建 PersistentVolumeController 的时候需要传入一个 ControllerParameters 对象作为参数。

type ControllerParameters struct {
    ...
	VolumeInformer            coreinformers.PersistentVolumeInformer
	ClaimInformer             coreinformers.PersistentVolumeClaimInformer
    ...
}

其中有一个 PersistentVolumeInformer 和一个 PersistentVolumeClaimInformer,分别用于 watch PV 和 PVC 对象的改动。

下面是创建 PersistentVolumeController 对象的函数:

func NewController(p ControllerParameters) (*PersistentVolumeController, error) {
    ...
	controller := &PersistentVolumeController{
        ...
	}

    ...
	p.VolumeInformer.Informer().AddEventHandler(
		cache.ResourceEventHandlerFuncs{
			AddFunc:    func(obj interface{}) { controller.enqueueWork(controller.volumeQueue, obj) },
			UpdateFunc: func(oldObj, newObj interface{}) { controller.enqueueWork(controller.volumeQueue, newObj) },
			DeleteFunc: func(obj interface{}) { controller.enqueueWork(controller.volumeQueue, obj) },
		},
	)
    ...
	p.ClaimInformer.Informer().AddEventHandler(
		cache.ResourceEventHandlerFuncs{
			AddFunc:    func(obj interface{}) { controller.enqueueWork(controller.claimQueue, obj) },
			UpdateFunc: func(oldObj, newObj interface{}) { controller.enqueueWork(controller.claimQueue, newObj) },
			DeleteFunc: func(obj interface{}) { controller.enqueueWork(controller.claimQueue, obj) },
		},
	)
    ...
	return controller, nil
}

可以看出它启动后,会对 PV 和 PVC 对象进行 watch,发现 PV 和 PVC 对象有改动时,分别将其加入上文提到的 PersistentVolumeController 对象的 PV 和 PVC 队列中。

func (ctrl *PersistentVolumeController) Run(stopCh <-chan struct{}) {
    ...
	go wait.Until(ctrl.resync, ctrl.resyncPeriod, stopCh)
	go wait.Until(ctrl.volumeWorker, time.Second, stopCh)
	go wait.Until(ctrl.claimWorker, time.Second, stopCh)
    ...
	<-stopCh
}

在随后执行 PersistentVolumeController.Run() 时,会分别启动两个 goroutine,volumeWorkerclaimWorker 从 PV 和 PVC 队列中取出数据进行处理。

和这两个同时启动的还有另外一个 goroutine resync,它会周期性地进行执行,这个执行周期由 Kube Controller Manager 的 --pvclaimbinder-sync-period 参数指定,默认为15秒。它的内容如下:

func (ctrl *PersistentVolumeController) resync() {
	klog.V(4).Infof("resyncing PV controller")

	pvcs, err := ctrl.claimLister.List(labels.NewSelector())
	if err != nil {
		klog.Warningf("cannot list claims: %s", err)
		return
	}
	for _, pvc := range pvcs {
		ctrl.enqueueWork(ctrl.claimQueue, pvc)
	}

	pvs, err := ctrl.volumeLister.List(labels.NewSelector())
	if err != nil {
		klog.Warningf("cannot list persistent volumes: %s", err)
		return
	}
	for _, pv := range pvs {
		ctrl.enqueueWork(ctrl.volumeQueue, pv)
	}
}

这个函数的逻辑也非常简单,就是将所有的 PV 和 PVC 对象分别加入到各自的队列中进行处理。因此它的作用就是周期性地同步所有的 PV 和 PVC 对象。

下一节我们针对 volumeWorker 和 `claimWorker 这两个 goroutine 分别进行分析,看 PersistentVolumeController 是如何处理 PV 和 PVC 对象的。