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 }