Skip to content

Commit

Permalink
Merge pull request kubernetes#108692 from jsafrane/selinux
Browse files Browse the repository at this point in the history
Speed up SELinux volume relabeling using mounts MVP
  • Loading branch information
k8s-ci-robot committed Aug 4, 2022
2 parents c8edeab + f9c7ce5 commit b6d0f6a
Show file tree
Hide file tree
Showing 83 changed files with 2,444 additions and 460 deletions.
4 changes: 4 additions & 0 deletions api/openapi-spec/swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions api/openapi-spec/v3/apis__storage.k8s.io__v1_openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1280,6 +1280,10 @@
"description": "RequiresRepublish indicates the CSI driver wants `NodePublishVolume` being periodically called to reflect any possible change in the mounted volume. This field defaults to false.\n\nNote: After a successful initial NodePublishVolume call, subsequent calls to NodePublishVolume should only update the contents of the volume. New mount points will not be seen by a running container.",
"type": "boolean"
},
"seLinuxMount": {
"description": "SELinuxMount specifies if the CSI driver supports \"-o context\" mount option.\n\nWhen \"true\", the CSI driver must ensure that all volumes provided by this CSI driver can be mounted separately with different `-o context` options. This is typical for storage backends that provide volumes as filesystems on block devices or as independent shared volumes. Kubernetes will call NodeStage / NodePublish with \"-o context=xyz\" mount option when mounting a ReadWriteOncePod volume used in Pod that has explicitly set SELinux context. In the future, it may be expanded to other volume AccessModes. In any case, Kubernetes will ensure that the volume is mounted only with a single SELinux context.\n\nWhen \"false\", Kubernetes won't pass any special SELinux mount options to the driver. This is typical for volumes that represent subdirectories of a bigger shared filesystem.\n\nDefault is \"false\".",
"type": "boolean"
},
"storageCapacity": {
"description": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.",
"type": "boolean"
Expand Down
21 changes: 21 additions & 0 deletions pkg/apis/storage/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,27 @@ type CSIDriverSpec struct {
//
// +optional
RequiresRepublish *bool

// SELinuxMount specifies if the CSI driver supports "-o context"
// mount option.
//
// When "true", the CSI driver must ensure that all volumes provided by this CSI
// driver can be mounted separately with different `-o context` options. This is
// typical for storage backends that provide volumes as filesystems on block
// devices or as independent shared volumes.
// Kubernetes will call NodeStage / NodePublish with "-o context=xyz" mount
// option when mounting a ReadWriteOncePod volume used in Pod that has
// explicitly set SELinux context. In the future, it may be expanded to other
// volume AccessModes. In any case, Kubernetes will ensure that the volume is
// mounted only with a single SELinux context.
//
// When "false", Kubernetes won't pass any special SELinux mount options to the driver.
// This is typical for volumes that represent subdirectories of a bigger shared filesystem.
//
// Default is "false".
//
// +optional
SELinuxMount *bool
}

// FSGroupPolicy specifies if a CSI Driver supports modifying
Expand Down
4 changes: 4 additions & 0 deletions pkg/apis/storage/v1/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,8 @@ func SetDefaults_CSIDriver(obj *storagev1.CSIDriver) {
obj.Spec.RequiresRepublish = new(bool)
*(obj.Spec.RequiresRepublish) = false
}
if obj.Spec.SELinuxMount == nil && utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
obj.Spec.SELinuxMount = new(bool)
*(obj.Spec.SELinuxMount) = false
}
}
27 changes: 27 additions & 0 deletions pkg/apis/storage/v1/defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,30 @@ func TestSetDefaultCSIDriver(t *testing.T) {
})
}
}

func TestSetDefaultSELinuxMountReadWriteOncePodEnabled(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true)()
driver := &storagev1.CSIDriver{}

// field should be defaulted
defaultSELinuxMount := false
output := roundTrip(t, runtime.Object(driver)).(*storagev1.CSIDriver)
outSELinuxMount := output.Spec.SELinuxMount
if outSELinuxMount == nil {
t.Errorf("Expected SELinuxMount to be defaulted to: %+v, got: nil", defaultSELinuxMount)
} else if *outSELinuxMount != defaultSELinuxMount {
t.Errorf("Expected SELinuxMount to be defaulted to: %+v, got: %+v", defaultSELinuxMount, outSELinuxMount)
}
}

func TestSetDefaultSELinuxMountReadWriteOncePodDisabled(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, false)()
driver := &storagev1.CSIDriver{}

// field should not be defaulted
output := roundTrip(t, runtime.Object(driver)).(*storagev1.CSIDriver)
outSELinuxMount := output.Spec.SELinuxMount
if outSELinuxMount != nil {
t.Errorf("Expected SELinuxMount to remain nil, got: %+v", outSELinuxMount)
}
}
2 changes: 2 additions & 0 deletions pkg/apis/storage/v1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions pkg/apis/storage/v1beta1/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,8 @@ func SetDefaults_CSIDriver(obj *storagev1beta1.CSIDriver) {
obj.Spec.RequiresRepublish = new(bool)
*(obj.Spec.RequiresRepublish) = false
}
if obj.Spec.SELinuxMount == nil && utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
obj.Spec.SELinuxMount = new(bool)
*(obj.Spec.SELinuxMount) = false
}
}
27 changes: 27 additions & 0 deletions pkg/apis/storage/v1beta1/defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,30 @@ func TestSetDefaultCSIDriver(t *testing.T) {
})
}
}

func TestSetDefaultSELinuxMountReadWriteOncePodEnabled(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true)()
driver := &storagev1beta1.CSIDriver{}

// field should be defaulted
defaultSELinuxMount := false
output := roundTrip(t, runtime.Object(driver)).(*storagev1beta1.CSIDriver)
outSELinuxMount := output.Spec.SELinuxMount
if outSELinuxMount == nil {
t.Errorf("Expected SELinuxMount to be defaulted to: %+v, got: nil", defaultSELinuxMount)
} else if *outSELinuxMount != defaultSELinuxMount {
t.Errorf("Expected SELinuxMount to be defaulted to: %+v, got: %+v", defaultSELinuxMount, outSELinuxMount)
}
}

func TestSetDefaultSELinuxMountReadWriteOncePodDisabled(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, false)()
driver := &storagev1beta1.CSIDriver{}

// field should not be defaulted
output := roundTrip(t, runtime.Object(driver)).(*storagev1beta1.CSIDriver)
outSELinuxMount := output.Spec.SELinuxMount
if outSELinuxMount != nil {
t.Errorf("Expected SELinuxMount remain nil, got: %+v", outSELinuxMount)
}
}
2 changes: 2 additions & 0 deletions pkg/apis/storage/v1beta1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions pkg/apis/storage/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions pkg/controller/volume/attachdetach/testing/testvolumespec.go
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,10 @@ func (plugin *TestPlugin) SupportsBulkVolumeVerification() bool {
return false
}

func (plugin *TestPlugin) SupportsSELinuxContextMount(spec *volume.Spec) (bool, error) {
return false, nil
}

func (plugin *TestPlugin) GetErrorEncountered() bool {
plugin.pluginLock.RLock()
defer plugin.pluginLock.RUnlock()
Expand Down
4 changes: 4 additions & 0 deletions pkg/controller/volume/persistentvolume/framework_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -970,6 +970,10 @@ func (plugin *mockVolumePlugin) ConstructVolumeSpec(volumeName, mountPath string
return nil, nil
}

func (plugin *mockVolumePlugin) SupportsSELinuxContextMount(spec *volume.Spec) (bool, error) {
return false, nil
}

func (plugin *mockVolumePlugin) NewMounter(spec *volume.Spec, podRef *v1.Pod, opts volume.VolumeOptions) (volume.Mounter, error) {
return nil, fmt.Errorf("Mounter is not supported by this plugin")
}
Expand Down
10 changes: 10 additions & 0 deletions pkg/features/kube_features.go
Original file line number Diff line number Diff line change
Expand Up @@ -860,6 +860,14 @@ const (
// Allow users to specify whether to take nodeAffinity/nodeTaint into consideration when
// calculating pod topology spread skew.
NodeInclusionPolicyInPodTopologySpread featuregate.Feature = "NodeInclusionPolicyInPodTopologySpread"

// owner: @jsafrane
// kep: http://kep.k8s.io/1710
// alpha: v1.25
// Speed up container startup by mounting volumes with the correct SELinux label
// instead of changing each file on the volumes recursively.
// Initial implementation focused on ReadWriteOncePod volumes.
SELinuxMountReadWriteOncePod featuregate.Feature = "SELinuxMountReadWriteOncePod"
)

func init() {
Expand Down Expand Up @@ -1099,6 +1107,8 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS

NodeInclusionPolicyInPodTopologySpread: {Default: false, PreRelease: featuregate.Alpha},

SELinuxMountReadWriteOncePod: {Default: false, PreRelease: featuregate.Alpha},

// inherited features from generic apiserver, relisted here to get a conflict if it is changed
// unintentionally on either side:

Expand Down
14 changes: 14 additions & 0 deletions pkg/generated/openapi/zz_generated.openapi.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit b6d0f6a

Please sign in to comment.