mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-10-31 05:40:42 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			125 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			125 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| /*
 | |
| Copyright 2019 The Kubernetes Authors.
 | |
| 
 | |
| Licensed under the Apache License, Version 2.0 (the "License");
 | |
| you may not use this file except in compliance with the License.
 | |
| You may obtain a copy of the License at
 | |
| 
 | |
|     http://www.apache.org/licenses/LICENSE-2.0
 | |
| 
 | |
| Unless required by applicable law or agreed to in writing, software
 | |
| distributed under the License is distributed on an "AS IS" BASIS,
 | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| See the License for the specific language governing permissions and
 | |
| limitations under the License.
 | |
| */
 | |
| 
 | |
| package pluginmanager
 | |
| 
 | |
| import (
 | |
| 	"time"
 | |
| 
 | |
| 	"k8s.io/apimachinery/pkg/util/runtime"
 | |
| 	"k8s.io/client-go/tools/record"
 | |
| 	"k8s.io/klog/v2"
 | |
| 	"k8s.io/kubernetes/pkg/kubelet/config"
 | |
| 	"k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache"
 | |
| 	"k8s.io/kubernetes/pkg/kubelet/pluginmanager/metrics"
 | |
| 	"k8s.io/kubernetes/pkg/kubelet/pluginmanager/operationexecutor"
 | |
| 	"k8s.io/kubernetes/pkg/kubelet/pluginmanager/pluginwatcher"
 | |
| 	"k8s.io/kubernetes/pkg/kubelet/pluginmanager/reconciler"
 | |
| )
 | |
| 
 | |
| // PluginManager runs a set of asynchronous loops that figure out which plugins
 | |
| // need to be registered/deregistered and makes it so.
 | |
| type PluginManager interface {
 | |
| 	// Starts the plugin manager and all the asynchronous loops that it controls
 | |
| 	Run(sourcesReady config.SourcesReady, stopCh <-chan struct{})
 | |
| 
 | |
| 	// AddHandler adds the given plugin handler for a specific plugin type, which
 | |
| 	// will be added to the actual state of world cache so that it can be passed to
 | |
| 	// the desired state of world cache in order to be used during plugin
 | |
| 	// registration/deregistration
 | |
| 	AddHandler(pluginType string, pluginHandler cache.PluginHandler)
 | |
| }
 | |
| 
 | |
| const (
 | |
| 	// loopSleepDuration is the amount of time the reconciler loop waits
 | |
| 	// between successive executions
 | |
| 	loopSleepDuration = 1 * time.Second
 | |
| )
 | |
| 
 | |
| // NewPluginManager returns a new concrete instance implementing the
 | |
| // PluginManager interface.
 | |
| func NewPluginManager(
 | |
| 	sockDir string,
 | |
| 	recorder record.EventRecorder) PluginManager {
 | |
| 	asw := cache.NewActualStateOfWorld()
 | |
| 	dsw := cache.NewDesiredStateOfWorld()
 | |
| 	reconciler := reconciler.NewReconciler(
 | |
| 		operationexecutor.NewOperationExecutor(
 | |
| 			operationexecutor.NewOperationGenerator(
 | |
| 				recorder,
 | |
| 			),
 | |
| 		),
 | |
| 		loopSleepDuration,
 | |
| 		dsw,
 | |
| 		asw,
 | |
| 	)
 | |
| 
 | |
| 	pm := &pluginManager{
 | |
| 		desiredStateOfWorldPopulator: pluginwatcher.NewWatcher(
 | |
| 			sockDir,
 | |
| 			dsw,
 | |
| 		),
 | |
| 		reconciler:          reconciler,
 | |
| 		desiredStateOfWorld: dsw,
 | |
| 		actualStateOfWorld:  asw,
 | |
| 	}
 | |
| 	return pm
 | |
| }
 | |
| 
 | |
| // pluginManager implements the PluginManager interface
 | |
| type pluginManager struct {
 | |
| 	// desiredStateOfWorldPopulator (the plugin watcher) runs an asynchronous
 | |
| 	// periodic loop to populate the desiredStateOfWorld.
 | |
| 	desiredStateOfWorldPopulator *pluginwatcher.Watcher
 | |
| 
 | |
| 	// reconciler runs an asynchronous periodic loop to reconcile the
 | |
| 	// desiredStateOfWorld with the actualStateOfWorld by triggering register
 | |
| 	// and unregister operations using the operationExecutor.
 | |
| 	reconciler reconciler.Reconciler
 | |
| 
 | |
| 	// actualStateOfWorld is a data structure containing the actual state of
 | |
| 	// the world according to the manager: i.e. which plugins are registered.
 | |
| 	// The data structure is populated upon successful completion of register
 | |
| 	// and unregister actions triggered by the reconciler.
 | |
| 	actualStateOfWorld cache.ActualStateOfWorld
 | |
| 
 | |
| 	// desiredStateOfWorld is a data structure containing the desired state of
 | |
| 	// the world according to the plugin manager: i.e. what plugins are registered.
 | |
| 	// The data structure is populated by the desired state of the world
 | |
| 	// populator (plugin watcher).
 | |
| 	desiredStateOfWorld cache.DesiredStateOfWorld
 | |
| }
 | |
| 
 | |
| var _ PluginManager = &pluginManager{}
 | |
| 
 | |
| func (pm *pluginManager) Run(sourcesReady config.SourcesReady, stopCh <-chan struct{}) {
 | |
| 	defer runtime.HandleCrash()
 | |
| 
 | |
| 	pm.desiredStateOfWorldPopulator.Start(stopCh)
 | |
| 	klog.V(2).InfoS("The desired_state_of_world populator (plugin watcher) starts")
 | |
| 
 | |
| 	klog.InfoS("Starting Kubelet Plugin Manager")
 | |
| 	go pm.reconciler.Run(stopCh)
 | |
| 
 | |
| 	metrics.Register(pm.actualStateOfWorld, pm.desiredStateOfWorld)
 | |
| 	<-stopCh
 | |
| 	klog.InfoS("Shutting down Kubelet Plugin Manager")
 | |
| }
 | |
| 
 | |
| func (pm *pluginManager) AddHandler(pluginType string, handler cache.PluginHandler) {
 | |
| 	pm.reconciler.AddHandler(pluginType, handler)
 | |
| }
 |