k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/pkg/kubelet/volume_host.go (about)

     1  /*
     2  Copyright 2016 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package kubelet
    18  
    19  import (
    20  	"fmt"
    21  	"net"
    22  	"runtime"
    23  
    24  	"k8s.io/klog/v2"
    25  	"k8s.io/mount-utils"
    26  	utilexec "k8s.io/utils/exec"
    27  
    28  	authenticationv1 "k8s.io/api/authentication/v1"
    29  	v1 "k8s.io/api/core/v1"
    30  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    31  	"k8s.io/apimachinery/pkg/types"
    32  	"k8s.io/apimachinery/pkg/util/wait"
    33  	"k8s.io/client-go/informers"
    34  	clientset "k8s.io/client-go/kubernetes"
    35  	storagelisters "k8s.io/client-go/listers/storage/v1"
    36  	"k8s.io/client-go/tools/cache"
    37  	"k8s.io/client-go/tools/record"
    38  	"k8s.io/kubernetes/pkg/kubelet/clustertrustbundle"
    39  	"k8s.io/kubernetes/pkg/kubelet/configmap"
    40  	"k8s.io/kubernetes/pkg/kubelet/secret"
    41  	"k8s.io/kubernetes/pkg/kubelet/token"
    42  	"k8s.io/kubernetes/pkg/volume"
    43  	"k8s.io/kubernetes/pkg/volume/util"
    44  	"k8s.io/kubernetes/pkg/volume/util/hostutil"
    45  	"k8s.io/kubernetes/pkg/volume/util/subpath"
    46  )
    47  
    48  // NewInitializedVolumePluginMgr returns a new instance of
    49  // volume.VolumePluginMgr initialized with kubelets implementation of the
    50  // volume.VolumeHost interface.
    51  //
    52  // kubelet - used by VolumeHost methods to expose kubelet specific parameters
    53  // plugins - used to initialize volumePluginMgr
    54  func NewInitializedVolumePluginMgr(
    55  	kubelet *Kubelet,
    56  	secretManager secret.Manager,
    57  	configMapManager configmap.Manager,
    58  	tokenManager *token.Manager,
    59  	clusterTrustBundleManager clustertrustbundle.Manager,
    60  	plugins []volume.VolumePlugin,
    61  	prober volume.DynamicPluginProber) (*volume.VolumePluginMgr, error) {
    62  
    63  	// Initialize csiDriverLister before calling InitPlugins
    64  	var informerFactory informers.SharedInformerFactory
    65  	var csiDriverLister storagelisters.CSIDriverLister
    66  	var csiDriversSynced cache.InformerSynced
    67  	const resyncPeriod = 0
    68  	// Don't initialize if kubeClient is nil
    69  	if kubelet.kubeClient != nil {
    70  		informerFactory = informers.NewSharedInformerFactory(kubelet.kubeClient, resyncPeriod)
    71  		csiDriverInformer := informerFactory.Storage().V1().CSIDrivers()
    72  		csiDriverLister = csiDriverInformer.Lister()
    73  		csiDriversSynced = csiDriverInformer.Informer().HasSynced
    74  
    75  	} else {
    76  		klog.InfoS("KubeClient is nil. Skip initialization of CSIDriverLister")
    77  	}
    78  
    79  	kvh := &kubeletVolumeHost{
    80  		kubelet:                   kubelet,
    81  		volumePluginMgr:           volume.VolumePluginMgr{},
    82  		secretManager:             secretManager,
    83  		configMapManager:          configMapManager,
    84  		tokenManager:              tokenManager,
    85  		clusterTrustBundleManager: clusterTrustBundleManager,
    86  		informerFactory:           informerFactory,
    87  		csiDriverLister:           csiDriverLister,
    88  		csiDriversSynced:          csiDriversSynced,
    89  		exec:                      utilexec.New(),
    90  	}
    91  
    92  	if err := kvh.volumePluginMgr.InitPlugins(plugins, prober, kvh); err != nil {
    93  		return nil, fmt.Errorf(
    94  			"could not initialize volume plugins for KubeletVolumePluginMgr: %v",
    95  			err)
    96  	}
    97  
    98  	return &kvh.volumePluginMgr, nil
    99  }
   100  
   101  // Compile-time check to ensure kubeletVolumeHost implements the VolumeHost interface
   102  var _ volume.VolumeHost = &kubeletVolumeHost{}
   103  var _ volume.KubeletVolumeHost = &kubeletVolumeHost{}
   104  
   105  func (kvh *kubeletVolumeHost) GetPluginDir(pluginName string) string {
   106  	return kvh.kubelet.getPluginDir(pluginName)
   107  }
   108  
   109  type kubeletVolumeHost struct {
   110  	kubelet                   *Kubelet
   111  	volumePluginMgr           volume.VolumePluginMgr
   112  	secretManager             secret.Manager
   113  	tokenManager              *token.Manager
   114  	configMapManager          configmap.Manager
   115  	clusterTrustBundleManager clustertrustbundle.Manager
   116  	informerFactory           informers.SharedInformerFactory
   117  	csiDriverLister           storagelisters.CSIDriverLister
   118  	csiDriversSynced          cache.InformerSynced
   119  	exec                      utilexec.Interface
   120  }
   121  
   122  func (kvh *kubeletVolumeHost) SetKubeletError(err error) {
   123  	kvh.kubelet.runtimeState.setStorageState(err)
   124  }
   125  
   126  func (kvh *kubeletVolumeHost) GetVolumeDevicePluginDir(pluginName string) string {
   127  	return kvh.kubelet.getVolumeDevicePluginDir(pluginName)
   128  }
   129  
   130  func (kvh *kubeletVolumeHost) GetPodsDir() string {
   131  	return kvh.kubelet.getPodsDir()
   132  }
   133  
   134  func (kvh *kubeletVolumeHost) GetPodVolumeDir(podUID types.UID, pluginName string, volumeName string) string {
   135  	dir := kvh.kubelet.getPodVolumeDir(podUID, pluginName, volumeName)
   136  	if runtime.GOOS == "windows" {
   137  		dir = util.GetWindowsPath(dir)
   138  	}
   139  	return dir
   140  }
   141  
   142  func (kvh *kubeletVolumeHost) GetPodVolumeDeviceDir(podUID types.UID, pluginName string) string {
   143  	return kvh.kubelet.getPodVolumeDeviceDir(podUID, pluginName)
   144  }
   145  
   146  func (kvh *kubeletVolumeHost) GetPodPluginDir(podUID types.UID, pluginName string) string {
   147  	return kvh.kubelet.getPodPluginDir(podUID, pluginName)
   148  }
   149  
   150  func (kvh *kubeletVolumeHost) GetKubeClient() clientset.Interface {
   151  	return kvh.kubelet.kubeClient
   152  }
   153  
   154  func (kvh *kubeletVolumeHost) GetSubpather() subpath.Interface {
   155  	return kvh.kubelet.subpather
   156  }
   157  
   158  func (kvh *kubeletVolumeHost) GetHostUtil() hostutil.HostUtils {
   159  	return kvh.kubelet.hostutil
   160  }
   161  
   162  func (kvh *kubeletVolumeHost) GetInformerFactory() informers.SharedInformerFactory {
   163  	return kvh.informerFactory
   164  }
   165  
   166  func (kvh *kubeletVolumeHost) CSIDriverLister() storagelisters.CSIDriverLister {
   167  	return kvh.csiDriverLister
   168  }
   169  
   170  func (kvh *kubeletVolumeHost) CSIDriversSynced() cache.InformerSynced {
   171  	return kvh.csiDriversSynced
   172  }
   173  
   174  // WaitForCacheSync is a helper function that waits for cache sync for CSIDriverLister
   175  func (kvh *kubeletVolumeHost) WaitForCacheSync() error {
   176  	if kvh.csiDriversSynced == nil {
   177  		klog.ErrorS(nil, "CsiDriversSynced not found on KubeletVolumeHost")
   178  		return fmt.Errorf("csiDriversSynced not found on KubeletVolumeHost")
   179  	}
   180  
   181  	synced := []cache.InformerSynced{kvh.csiDriversSynced}
   182  	if !cache.WaitForCacheSync(wait.NeverStop, synced...) {
   183  		klog.InfoS("Failed to wait for cache sync for CSIDriverLister")
   184  		return fmt.Errorf("failed to wait for cache sync for CSIDriverLister")
   185  	}
   186  
   187  	return nil
   188  }
   189  
   190  func (kvh *kubeletVolumeHost) NewWrapperMounter(
   191  	volName string,
   192  	spec volume.Spec,
   193  	pod *v1.Pod,
   194  	opts volume.VolumeOptions) (volume.Mounter, error) {
   195  	// The name of wrapper volume is set to "wrapped_{wrapped_volume_name}"
   196  	wrapperVolumeName := "wrapped_" + volName
   197  	if spec.Volume != nil {
   198  		spec.Volume.Name = wrapperVolumeName
   199  	}
   200  
   201  	return kvh.kubelet.newVolumeMounterFromPlugins(&spec, pod, opts)
   202  }
   203  
   204  func (kvh *kubeletVolumeHost) NewWrapperUnmounter(volName string, spec volume.Spec, podUID types.UID) (volume.Unmounter, error) {
   205  	// The name of wrapper volume is set to "wrapped_{wrapped_volume_name}"
   206  	wrapperVolumeName := "wrapped_" + volName
   207  	if spec.Volume != nil {
   208  		spec.Volume.Name = wrapperVolumeName
   209  	}
   210  
   211  	plugin, err := kvh.kubelet.volumePluginMgr.FindPluginBySpec(&spec)
   212  	if err != nil {
   213  		return nil, err
   214  	}
   215  
   216  	return plugin.NewUnmounter(spec.Name(), podUID)
   217  }
   218  
   219  func (kvh *kubeletVolumeHost) GetMounter(pluginName string) mount.Interface {
   220  	return kvh.kubelet.mounter
   221  }
   222  
   223  func (kvh *kubeletVolumeHost) GetHostName() string {
   224  	return kvh.kubelet.hostname
   225  }
   226  
   227  func (kvh *kubeletVolumeHost) GetHostIP() (net.IP, error) {
   228  	hostIPs, err := kvh.kubelet.GetHostIPs()
   229  	if err != nil {
   230  		return nil, err
   231  	}
   232  	return hostIPs[0], err
   233  }
   234  
   235  func (kvh *kubeletVolumeHost) GetNodeAllocatable() (v1.ResourceList, error) {
   236  	node, err := kvh.kubelet.getNodeAnyWay()
   237  	if err != nil {
   238  		return nil, fmt.Errorf("error retrieving node: %v", err)
   239  	}
   240  	return node.Status.Allocatable, nil
   241  }
   242  
   243  func (kvh *kubeletVolumeHost) GetSecretFunc() func(namespace, name string) (*v1.Secret, error) {
   244  	if kvh.secretManager != nil {
   245  		return kvh.secretManager.GetSecret
   246  	}
   247  	return func(namespace, name string) (*v1.Secret, error) {
   248  		return nil, fmt.Errorf("not supported due to running kubelet in standalone mode")
   249  	}
   250  }
   251  
   252  func (kvh *kubeletVolumeHost) GetConfigMapFunc() func(namespace, name string) (*v1.ConfigMap, error) {
   253  	if kvh.configMapManager != nil {
   254  		return kvh.configMapManager.GetConfigMap
   255  	}
   256  	return func(namespace, name string) (*v1.ConfigMap, error) {
   257  		return nil, fmt.Errorf("not supported due to running kubelet in standalone mode")
   258  	}
   259  }
   260  
   261  func (kvh *kubeletVolumeHost) GetServiceAccountTokenFunc() func(namespace, name string, tr *authenticationv1.TokenRequest) (*authenticationv1.TokenRequest, error) {
   262  	return kvh.tokenManager.GetServiceAccountToken
   263  }
   264  
   265  func (kvh *kubeletVolumeHost) DeleteServiceAccountTokenFunc() func(podUID types.UID) {
   266  	return kvh.tokenManager.DeleteServiceAccountToken
   267  }
   268  
   269  func (kvh *kubeletVolumeHost) GetTrustAnchorsByName(name string, allowMissing bool) ([]byte, error) {
   270  	return kvh.clusterTrustBundleManager.GetTrustAnchorsByName(name, allowMissing)
   271  }
   272  
   273  func (kvh *kubeletVolumeHost) GetTrustAnchorsBySigner(signerName string, labelSelector *metav1.LabelSelector, allowMissing bool) ([]byte, error) {
   274  	return kvh.clusterTrustBundleManager.GetTrustAnchorsBySigner(signerName, labelSelector, allowMissing)
   275  }
   276  
   277  func (kvh *kubeletVolumeHost) GetNodeLabels() (map[string]string, error) {
   278  	node, err := kvh.kubelet.GetNode()
   279  	if err != nil {
   280  		return nil, fmt.Errorf("error retrieving node: %v", err)
   281  	}
   282  	return node.Labels, nil
   283  }
   284  
   285  func (kvh *kubeletVolumeHost) GetAttachedVolumesFromNodeStatus() (map[v1.UniqueVolumeName]string, error) {
   286  	node, err := kvh.kubelet.GetNode()
   287  	if err != nil {
   288  		return nil, fmt.Errorf("error retrieving node: %v", err)
   289  	}
   290  	attachedVolumes := node.Status.VolumesAttached
   291  	result := map[v1.UniqueVolumeName]string{}
   292  	for i := range attachedVolumes {
   293  		attachedVolume := attachedVolumes[i]
   294  		result[attachedVolume.Name] = attachedVolume.DevicePath
   295  	}
   296  	return result, nil
   297  }
   298  
   299  func (kvh *kubeletVolumeHost) GetNodeName() types.NodeName {
   300  	return kvh.kubelet.nodeName
   301  }
   302  
   303  func (kvh *kubeletVolumeHost) GetEventRecorder() record.EventRecorder {
   304  	return kvh.kubelet.recorder
   305  }
   306  
   307  func (kvh *kubeletVolumeHost) GetExec(pluginName string) utilexec.Interface {
   308  	return kvh.exec
   309  }