diff --git a/pkg/volume/csi/csi_attacher.go b/pkg/volume/csi/csi_attacher.go index 11de3c558bc..57fbcb7e9c5 100644 --- a/pkg/volume/csi/csi_attacher.go +++ b/pkg/volume/csi/csi_attacher.go @@ -26,9 +26,6 @@ import ( "strings" "time" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/klog/v2" - v1 "k8s.io/api/core/v1" storage "k8s.io/api/storage/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -36,9 +33,12 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/watch" + utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/kubernetes" + "k8s.io/klog/v2" "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/volume" + "k8s.io/kubernetes/pkg/volume/util" volumetypes "k8s.io/kubernetes/pkg/volume/util/types" "k8s.io/utils/clock" ) @@ -331,8 +331,9 @@ func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMo klog.V(4).Info(log("created target path successfully [%s]", deviceMountPath)) dataDir := filepath.Dir(deviceMountPath) data := map[string]string{ - volDataKey.volHandle: csiSource.VolumeHandle, - volDataKey.driverName: csiSource.Driver, + volDataKey.volHandle: csiSource.VolumeHandle, + volDataKey.driverName: csiSource.Driver, + volDataKey.seLinuxMountContext: deviceMounterArgs.SELinuxLabel, } err = saveVolumeData(dataDir, volDataFileName, data) @@ -371,6 +372,16 @@ func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMo mountOptions = spec.PersistentVolume.Spec.MountOptions } + if utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) { + support, err := c.plugin.SupportsSELinuxContextMount(spec) + if err != nil { + return errors.New(log("failed to query for SELinuxMount support: %s", err)) + } + if support { + mountOptions = util.AddSELinuxMountOption(mountOptions, deviceMounterArgs.SELinuxLabel) + } + } + var nodeStageFSGroupArg *int64 if utilfeature.DefaultFeatureGate.Enabled(features.DelegateFSGroupToCSIDriver) { driverSupportsCSIVolumeMountGroup, err := csi.NodeSupportsVolumeMountGroup(ctx) diff --git a/pkg/volume/csi/csi_mounter.go b/pkg/volume/csi/csi_mounter.go index 1e85796a216..42175153c11 100644 --- a/pkg/volume/csi/csi_mounter.go +++ b/pkg/volume/csi/csi_mounter.go @@ -24,8 +24,6 @@ import ( "os" "path/filepath" - "k8s.io/klog/v2" - authenticationv1 "k8s.io/api/authentication/v1" api "k8s.io/api/core/v1" storage "k8s.io/api/storage/v1" @@ -33,6 +31,7 @@ import ( "k8s.io/apimachinery/pkg/types" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/kubernetes" + "k8s.io/klog/v2" "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/util" @@ -49,7 +48,8 @@ var ( driverName, nodeName, attachmentID, - volumeLifecycleMode string + volumeLifecycleMode, + seLinuxMountContext string }{ "specVolID", "volumeHandle", @@ -57,6 +57,7 @@ var ( "nodeName", "attachmentID", "volumeLifecycleMode", + "seLinuxMountContext", } ) @@ -70,7 +71,7 @@ type csiMountMgr struct { volumeID string specVolumeID string readOnly bool - supportsSELinux bool + needSELinuxRelabel bool spec *volume.Spec pod *api.Pod podUID types.UID @@ -245,6 +246,18 @@ func (c *csiMountMgr) SetUpAt(dir string, mounterArgs volume.MounterArgs) error } } + var selinuxLabelMount bool + if utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) { + support, err := c.plugin.SupportsSELinuxContextMount(c.spec) + if err != nil { + return errors.New(log("failed to query for SELinuxMount support: %s", err)) + } + if support { + mountOptions = util.AddSELinuxMountOption(mountOptions, mounterArgs.SELinuxLabel) + selinuxLabelMount = true + } + } + err = csi.NodePublishVolume( ctx, volumeHandle, @@ -270,10 +283,12 @@ func (c *csiMountMgr) SetUpAt(dir string, mounterArgs volume.MounterArgs) error return err } - c.supportsSELinux, err = c.kubeVolHost.GetHostUtil().GetSELinuxSupport(dir) - if err != nil { - // The volume is mounted. Return UncertainProgressError, so kubelet will unmount it when user deletes the pod. - return volumetypes.NewUncertainProgressError(fmt.Sprintf("error checking for SELinux support: %s", err)) + if !selinuxLabelMount { + c.needSELinuxRelabel, err = c.kubeVolHost.GetHostUtil().GetSELinuxSupport(dir) + if err != nil { + // The volume is mounted. Return UncertainProgressError, so kubelet will unmount it when user deletes the pod. + return volumetypes.NewUncertainProgressError(fmt.Sprintf("error checking for SELinux support: %s", err)) + } } if !driverSupportsCSIVolumeMountGroup && c.supportsFSGroup(fsType, mounterArgs.FsGroup, c.fsGroupPolicy) { @@ -350,7 +365,7 @@ func (c *csiMountMgr) GetAttributes() volume.Attributes { return volume.Attributes{ ReadOnly: c.readOnly, Managed: !c.readOnly, - SELinuxRelabel: c.supportsSELinux, + SELinuxRelabel: c.needSELinuxRelabel, } } diff --git a/pkg/volume/csi/csi_mounter_test.go b/pkg/volume/csi/csi_mounter_test.go index e8f5c5fea38..458643aff05 100644 --- a/pkg/volume/csi/csi_mounter_test.go +++ b/pkg/volume/csi/csi_mounter_test.go @@ -1235,7 +1235,7 @@ func Test_csiMountMgr_supportsFSGroup(t *testing.T) { volumeID: tt.fields.volumeID, specVolumeID: tt.fields.specVolumeID, readOnly: tt.fields.readOnly, - supportsSELinux: tt.fields.supportsSELinux, + needSELinuxRelabel: tt.fields.supportsSELinux, spec: tt.fields.spec, pod: tt.fields.pod, podUID: tt.fields.podUID, diff --git a/pkg/volume/csi/csi_plugin.go b/pkg/volume/csi/csi_plugin.go index 25358644e85..d739be18ee1 100644 --- a/pkg/volume/csi/csi_plugin.go +++ b/pkg/volume/csi/csi_plugin.go @@ -351,7 +351,7 @@ func (p *csiPlugin) RequiresRemount(spec *volume.Spec) bool { klog.V(5).Info(log("Failed to mark %q as republish required, err: %v", spec.Name(), err)) return false } - csiDriver, err := p.csiDriverLister.Get(driverName) + csiDriver, err := p.getCSIDriver(driverName) if err != nil { klog.V(5).Info(log("Failed to mark %q as republish required, err: %v", spec.Name(), err)) return false @@ -582,6 +582,20 @@ func (p *csiPlugin) SupportsBulkVolumeVerification() bool { } func (p *csiPlugin) SupportsSELinuxContextMount(spec *volume.Spec) (bool, error) { + if utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) { + driver, err := GetCSIDriverName(spec) + if err != nil { + return false, err + } + csiDriver, err := p.getCSIDriver(driver) + if err != nil { + return false, err + } + if csiDriver.Spec.SELinuxMount != nil { + return *csiDriver.Spec.SELinuxMount, nil + } + return false, nil + } return false, nil } @@ -795,17 +809,7 @@ func (p *csiPlugin) ConstructBlockVolumeSpec(podUID types.UID, specVolName, mapP // skipAttach looks up CSIDriver object associated with driver name // to determine if driver requires attachment volume operation func (p *csiPlugin) skipAttach(driver string) (bool, error) { - kletHost, ok := p.host.(volume.KubeletVolumeHost) - if ok { - if err := kletHost.WaitForCacheSync(); err != nil { - return false, err - } - } - - if p.csiDriverLister == nil { - return false, errors.New("CSIDriver lister does not exist") - } - csiDriver, err := p.csiDriverLister.Get(driver) + csiDriver, err := p.getCSIDriver(driver) if err != nil { if apierrors.IsNotFound(err) { // Don't skip attach if CSIDriver does not exist @@ -819,6 +823,21 @@ func (p *csiPlugin) skipAttach(driver string) (bool, error) { return false, nil } +func (p *csiPlugin) getCSIDriver(driver string) (*storage.CSIDriver, error) { + kletHost, ok := p.host.(volume.KubeletVolumeHost) + if ok { + if err := kletHost.WaitForCacheSync(); err != nil { + return nil, err + } + } + + if p.csiDriverLister == nil { + return nil, errors.New("CSIDriver lister does not exist") + } + csiDriver, err := p.csiDriverLister.Get(driver) + return csiDriver, err +} + // supportsVolumeMode checks whether the CSI driver supports a volume in the given mode. // An error indicates that it isn't supported and explains why. func (p *csiPlugin) supportsVolumeLifecycleMode(driver string, volumeMode storage.VolumeLifecycleMode) error { @@ -836,14 +855,7 @@ func (p *csiPlugin) supportsVolumeLifecycleMode(driver string, volumeMode storag // optional), but then only persistent volumes are supported. var csiDriver *storage.CSIDriver if p.csiDriverLister != nil { - kletHost, ok := p.host.(volume.KubeletVolumeHost) - if ok { - if err := kletHost.WaitForCacheSync(); err != nil { - return err - } - } - - c, err := p.csiDriverLister.Get(driver) + c, err := p.getCSIDriver(driver) if err != nil && !apierrors.IsNotFound(err) { // Some internal error. return err @@ -904,14 +916,7 @@ func (p *csiPlugin) getFSGroupPolicy(driver string) (storage.FSGroupPolicy, erro // optional) var csiDriver *storage.CSIDriver if p.csiDriverLister != nil { - kletHost, ok := p.host.(volume.KubeletVolumeHost) - if ok { - if err := kletHost.WaitForCacheSync(); err != nil { - return storage.ReadWriteOnceWithFSTypeFSGroupPolicy, err - } - } - - c, err := p.csiDriverLister.Get(driver) + c, err := p.getCSIDriver(driver) if err != nil && !apierrors.IsNotFound(err) { // Some internal error. return storage.ReadWriteOnceWithFSTypeFSGroupPolicy, err @@ -969,16 +974,7 @@ func (p *csiPlugin) newAttacherDetacher() (*csiAttacher, error) { // podInfoEnabled check CSIDriver enabled pod info flag func (p *csiPlugin) podInfoEnabled(driverName string) (bool, error) { - kletHost, ok := p.host.(volume.KubeletVolumeHost) - if ok { - kletHost.WaitForCacheSync() - } - - if p.csiDriverLister == nil { - return false, fmt.Errorf("CSIDriverLister not found") - } - - csiDriver, err := p.csiDriverLister.Get(driverName) + csiDriver, err := p.getCSIDriver(driverName) if err != nil { if apierrors.IsNotFound(err) { klog.V(4).Infof(log("CSIDriver %q not found, not adding pod information", driverName))