Merge pull request #123157 from jsafrane/selinux-rwx
Add SELinuxMount feature gate
This commit is contained in:
		| @@ -907,6 +907,13 @@ const ( | |||||||
| 	// | 	// | ||||||
| 	// Allows namespace indexer for namespace scope resources in apiserver cache to accelerate list operations. | 	// Allows namespace indexer for namespace scope resources in apiserver cache to accelerate list operations. | ||||||
| 	StorageNamespaceIndex featuregate.Feature = "StorageNamespaceIndex" | 	StorageNamespaceIndex featuregate.Feature = "StorageNamespaceIndex" | ||||||
|  |  | ||||||
|  | 	// owner: @jsafrane | ||||||
|  | 	// kep: https://kep.k8s.io/1710 | ||||||
|  | 	// alpha: v1.30 | ||||||
|  | 	// Speed up container startup by mounting volumes with the correct SELinux label | ||||||
|  | 	// instead of changing each file on the volumes recursively. | ||||||
|  | 	SELinuxMount featuregate.Feature = "SELinuxMount" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func init() { | func init() { | ||||||
| @@ -1159,6 +1166,8 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS | |||||||
|  |  | ||||||
| 	UserNamespacesPodSecurityStandards: {Default: false, PreRelease: featuregate.Alpha}, | 	UserNamespacesPodSecurityStandards: {Default: false, PreRelease: featuregate.Alpha}, | ||||||
|  |  | ||||||
|  | 	SELinuxMount: {Default: false, PreRelease: featuregate.Alpha}, | ||||||
|  |  | ||||||
| 	// inherited features from generic apiserver, relisted here to get a conflict if it is changed | 	// inherited features from generic apiserver, relisted here to get a conflict if it is changed | ||||||
| 	// unintentionally on either side: | 	// unintentionally on either side: | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1140,6 +1140,7 @@ func TestCheckVolumeSELinux(t *testing.T) { | |||||||
| 		accessModes                  []v1.PersistentVolumeAccessMode | 		accessModes                  []v1.PersistentVolumeAccessMode | ||||||
| 		existingContainerSELinuxOpts *v1.SELinuxOptions | 		existingContainerSELinuxOpts *v1.SELinuxOptions | ||||||
| 		newContainerSELinuxOpts      *v1.SELinuxOptions | 		newContainerSELinuxOpts      *v1.SELinuxOptions | ||||||
|  | 		seLinuxMountFeatureEnabled   bool | ||||||
| 		pluginSupportsSELinux        bool | 		pluginSupportsSELinux        bool | ||||||
| 		expectError                  bool | 		expectError                  bool | ||||||
| 		expectedContext              string | 		expectedContext              string | ||||||
| @@ -1159,14 +1160,22 @@ func TestCheckVolumeSELinux(t *testing.T) { | |||||||
| 			expectedContext:         "system_u:object_r:container_file_t:s0:c3,c4", | 			expectedContext:         "system_u:object_r:container_file_t:s0:c3,c4", | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			name:                    "RWX with plugin with SELinux with fill context in pod", | 			name:                    "RWX with plugin with SELinux with full context in pod and SELinuxMount feature disabled", | ||||||
| 			accessModes:             []v1.PersistentVolumeAccessMode{v1.ReadWriteMany}, | 			accessModes:             []v1.PersistentVolumeAccessMode{v1.ReadWriteMany}, | ||||||
| 			newContainerSELinuxOpts: fullOpts, | 			newContainerSELinuxOpts: fullOpts, | ||||||
| 			pluginSupportsSELinux:   true, | 			pluginSupportsSELinux:   true, | ||||||
| 			expectedContext:         "", // RWX volumes don't support SELinux | 			expectedContext:         "", // RWX volumes don't support SELinux | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			name:                    "RWOP with plugin with no SELinux with fill context in pod", | 			name:                       "RWX with plugin with SELinux with full context in pod and SELinuxMount feature enabled", | ||||||
|  | 			accessModes:                []v1.PersistentVolumeAccessMode{v1.ReadWriteMany}, | ||||||
|  | 			newContainerSELinuxOpts:    fullOpts, | ||||||
|  | 			pluginSupportsSELinux:      true, | ||||||
|  | 			seLinuxMountFeatureEnabled: true, | ||||||
|  | 			expectedContext:            "system_u:object_r:container_file_t:s0:c1,c2", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:                    "RWOP with plugin with no SELinux with full context in pod", | ||||||
| 			accessModes:             []v1.PersistentVolumeAccessMode{v1.ReadWriteOncePod}, | 			accessModes:             []v1.PersistentVolumeAccessMode{v1.ReadWriteOncePod}, | ||||||
| 			newContainerSELinuxOpts: fullOpts, | 			newContainerSELinuxOpts: fullOpts, | ||||||
| 			pluginSupportsSELinux:   false, | 			pluginSupportsSELinux:   false, | ||||||
| @@ -1195,6 +1204,25 @@ func TestCheckVolumeSELinux(t *testing.T) { | |||||||
| 			pluginSupportsSELinux:        true, | 			pluginSupportsSELinux:        true, | ||||||
| 			expectedContext:              "", | 			expectedContext:              "", | ||||||
| 		}, | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:                         "mismatched SELinux with RWX and SELinuxMount feature disabled", | ||||||
|  | 			accessModes:                  []v1.PersistentVolumeAccessMode{v1.ReadWriteMany}, | ||||||
|  | 			existingContainerSELinuxOpts: fullOpts, | ||||||
|  | 			newContainerSELinuxOpts:      differentFullOpts, | ||||||
|  | 			pluginSupportsSELinux:        true, | ||||||
|  | 			expectedContext:              "", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:                         "mismatched SELinux with RWX and SELinuxMount feature enabled", | ||||||
|  | 			accessModes:                  []v1.PersistentVolumeAccessMode{v1.ReadWriteMany}, | ||||||
|  | 			existingContainerSELinuxOpts: fullOpts, | ||||||
|  | 			newContainerSELinuxOpts:      differentFullOpts, | ||||||
|  | 			pluginSupportsSELinux:        true, | ||||||
|  | 			seLinuxMountFeatureEnabled:   true, | ||||||
|  | 			expectError:                  true, | ||||||
|  | 			// The original seLinuxOpts are kept in DSW | ||||||
|  | 			expectedContext: "system_u:object_r:container_file_t:s0:c1,c2", | ||||||
|  | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			name:                         "mismatched SELinux with RWOP - failure", | 			name:                         "mismatched SELinux with RWOP - failure", | ||||||
| 			accessModes:                  []v1.PersistentVolumeAccessMode{v1.ReadWriteOncePod}, | 			accessModes:                  []v1.PersistentVolumeAccessMode{v1.ReadWriteOncePod}, | ||||||
| @@ -1247,6 +1275,7 @@ func TestCheckVolumeSELinux(t *testing.T) { | |||||||
| 					}, | 					}, | ||||||
| 				}, | 				}, | ||||||
| 			} | 			} | ||||||
|  | 			defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMount, tc.seLinuxMountFeatureEnabled)() | ||||||
|  |  | ||||||
| 			fakeVolumePluginMgr, plugin := volumetesting.GetTestKubeletVolumePluginMgr(t) | 			fakeVolumePluginMgr, plugin := volumetesting.GetTestKubeletVolumePluginMgr(t) | ||||||
| 			plugin.SupportsSELinux = tc.pluginSupportsSELinux | 			plugin.SupportsSELinux = tc.pluginSupportsSELinux | ||||||
|   | |||||||
| @@ -449,6 +449,9 @@ type VolumeToMount struct { | |||||||
| 	DesiredPersistentVolumeSize resource.Quantity | 	DesiredPersistentVolumeSize resource.Quantity | ||||||
|  |  | ||||||
| 	// SELinux label that should be used to mount. | 	// SELinux label that should be used to mount. | ||||||
|  | 	// The label is set when: | ||||||
|  | 	// * SELinuxMountReadWriteOncePod feature gate is enabled and the volume is RWOP and kubelet knows the SELinux label. | ||||||
|  | 	// * Or, SELinuxMount feature gate is enabled and kubelet knows the SELinux label. | ||||||
| 	SELinuxLabel string | 	SELinuxLabel string | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -177,6 +177,10 @@ func VolumeSupportsSELinuxMount(volumeSpec *volume.Spec) bool { | |||||||
| 	if len(volumeSpec.PersistentVolume.Spec.AccessModes) != 1 { | 	if len(volumeSpec.PersistentVolume.Spec.AccessModes) != 1 { | ||||||
| 		return false | 		return false | ||||||
| 	} | 	} | ||||||
|  | 	if utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMount) { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 	// Only SELinuxMountReadWriteOncePod feature enabled | ||||||
| 	if !v1helper.ContainsAccessMode(volumeSpec.PersistentVolume.Spec.AccessModes, v1.ReadWriteOncePod) { | 	if !v1helper.ContainsAccessMode(volumeSpec.PersistentVolume.Spec.AccessModes, v1.ReadWriteOncePod) { | ||||||
| 		return false | 		return false | ||||||
| 	} | 	} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Kubernetes Prow Robot
					Kubernetes Prow Robot