mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Merge pull request #105885 from gnufied/move-configurable-fsgroup-ga
Move configurable fsgroup to GA
This commit is contained in:
commit
dcf0a031e9
@ -571,8 +571,6 @@ func dropDisabledFields(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
dropDisabledFSGroupFields(podSpec, oldPodSpec)
|
|
||||||
|
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(features.PodOverhead) && !overheadInUse(oldPodSpec) {
|
if !utilfeature.DefaultFeatureGate.Enabled(features.PodOverhead) && !overheadInUse(oldPodSpec) {
|
||||||
// Set Overhead to nil only if the feature is disabled and it is not used
|
// Set Overhead to nil only if the feature is disabled and it is not used
|
||||||
podSpec.Overhead = nil
|
podSpec.Overhead = nil
|
||||||
@ -623,16 +621,6 @@ func dropDisabledProcMountField(podSpec, oldPodSpec *api.PodSpec) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func dropDisabledFSGroupFields(podSpec, oldPodSpec *api.PodSpec) {
|
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(features.ConfigurableFSGroupPolicy) && !fsGroupPolicyInUse(oldPodSpec) {
|
|
||||||
// if oldPodSpec had no FSGroupChangePolicy set then we should prevent new pod from having this field
|
|
||||||
// if ConfigurableFSGroupPolicy feature is disabled
|
|
||||||
if podSpec.SecurityContext != nil {
|
|
||||||
podSpec.SecurityContext.FSGroupChangePolicy = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// dropDisabledCSIVolumeSourceAlphaFields removes disabled alpha fields from []CSIVolumeSource.
|
// dropDisabledCSIVolumeSourceAlphaFields removes disabled alpha fields from []CSIVolumeSource.
|
||||||
// This should be called from PrepareForCreate/PrepareForUpdate for all pod specs resources containing a CSIVolumeSource
|
// This should be called from PrepareForCreate/PrepareForUpdate for all pod specs resources containing a CSIVolumeSource
|
||||||
func dropDisabledCSIVolumeSourceAlphaFields(podSpec, oldPodSpec *api.PodSpec) {
|
func dropDisabledCSIVolumeSourceAlphaFields(podSpec, oldPodSpec *api.PodSpec) {
|
||||||
@ -710,17 +698,6 @@ func ephemeralContainersInUse(podSpec *api.PodSpec) bool {
|
|||||||
return len(podSpec.EphemeralContainers) > 0
|
return len(podSpec.EphemeralContainers) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func fsGroupPolicyInUse(podSpec *api.PodSpec) bool {
|
|
||||||
if podSpec == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
securityContext := podSpec.SecurityContext
|
|
||||||
if securityContext != nil && securityContext.FSGroupChangePolicy != nil {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// overheadInUse returns true if the pod spec is non-nil and has Overhead set
|
// overheadInUse returns true if the pod spec is non-nil and has Overhead set
|
||||||
func overheadInUse(podSpec *api.PodSpec) bool {
|
func overheadInUse(podSpec *api.PodSpec) bool {
|
||||||
if podSpec == nil {
|
if podSpec == nil {
|
||||||
|
@ -562,56 +562,24 @@ func TestDropFSGroupFields(t *testing.T) {
|
|||||||
}
|
}
|
||||||
podInfos := []struct {
|
podInfos := []struct {
|
||||||
description string
|
description string
|
||||||
featureEnabled bool
|
|
||||||
newPodHasFSGroupChangePolicy bool
|
newPodHasFSGroupChangePolicy bool
|
||||||
pod func() *api.Pod
|
pod func() *api.Pod
|
||||||
expectPolicyInPod bool
|
expectPolicyInPod bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
description: "oldPod.FSGroupChangePolicy=nil, feature=true, newPod.FSGroupChangePolicy=true",
|
description: "oldPod.FSGroupChangePolicy=nil, feature=true, newPod.FSGroupChangePolicy=true",
|
||||||
featureEnabled: true,
|
|
||||||
pod: nofsGroupPod,
|
pod: nofsGroupPod,
|
||||||
newPodHasFSGroupChangePolicy: true,
|
newPodHasFSGroupChangePolicy: true,
|
||||||
expectPolicyInPod: true,
|
expectPolicyInPod: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
description: "oldPod=nil, feature=false, newPod.FSGroupChangePolicy=true",
|
|
||||||
featureEnabled: false,
|
|
||||||
pod: func() *api.Pod { return nil },
|
|
||||||
newPodHasFSGroupChangePolicy: true,
|
|
||||||
expectPolicyInPod: false,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
description: "oldPod=nil, feature=true, newPod.FSGroupChangePolicy=true",
|
description: "oldPod=nil, feature=true, newPod.FSGroupChangePolicy=true",
|
||||||
featureEnabled: true,
|
|
||||||
pod: func() *api.Pod { return nil },
|
pod: func() *api.Pod { return nil },
|
||||||
newPodHasFSGroupChangePolicy: true,
|
newPodHasFSGroupChangePolicy: true,
|
||||||
expectPolicyInPod: true,
|
expectPolicyInPod: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
description: "oldPod.FSGroupChangePolicy=nil, feature=false, newPod.FSGroupChangePolicy=true",
|
|
||||||
featureEnabled: false,
|
|
||||||
pod: nofsGroupPod,
|
|
||||||
newPodHasFSGroupChangePolicy: true,
|
|
||||||
expectPolicyInPod: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "oldPod.FSGroupChangePolicy=true, feature=false, newPod.FSGroupChangePolicy=true",
|
|
||||||
featureEnabled: false,
|
|
||||||
pod: fsGroupPod,
|
|
||||||
newPodHasFSGroupChangePolicy: true,
|
|
||||||
expectPolicyInPod: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "oldPod.FSGroupChangePolicy=true, feature=false, newPod.FSGroupChangePolicy=false",
|
|
||||||
featureEnabled: false,
|
|
||||||
pod: fsGroupPod,
|
|
||||||
newPodHasFSGroupChangePolicy: false,
|
|
||||||
expectPolicyInPod: false,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
description: "oldPod.FSGroupChangePolicy=true, feature=true, newPod.FSGroupChangePolicy=false",
|
description: "oldPod.FSGroupChangePolicy=true, feature=true, newPod.FSGroupChangePolicy=false",
|
||||||
featureEnabled: true,
|
|
||||||
pod: fsGroupPod,
|
pod: fsGroupPod,
|
||||||
newPodHasFSGroupChangePolicy: false,
|
newPodHasFSGroupChangePolicy: false,
|
||||||
expectPolicyInPod: false,
|
expectPolicyInPod: false,
|
||||||
@ -619,7 +587,6 @@ func TestDropFSGroupFields(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, podInfo := range podInfos {
|
for _, podInfo := range podInfos {
|
||||||
t.Run(podInfo.description, func(t *testing.T) {
|
t.Run(podInfo.description, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ConfigurableFSGroupPolicy, podInfo.featureEnabled)()
|
|
||||||
oldPod := podInfo.pod()
|
oldPod := podInfo.pod()
|
||||||
newPod := oldPod.DeepCopy()
|
newPod := oldPod.DeepCopy()
|
||||||
if oldPod == nil && podInfo.newPodHasFSGroupChangePolicy {
|
if oldPod == nil && podInfo.newPodHasFSGroupChangePolicy {
|
||||||
|
@ -341,6 +341,7 @@ const (
|
|||||||
// owner: @gnufied
|
// owner: @gnufied
|
||||||
// alpha: v1.18
|
// alpha: v1.18
|
||||||
// beta: v1.20
|
// beta: v1.20
|
||||||
|
// GA: v1.23
|
||||||
// Allows user to configure volume permission change policy for fsGroups when mounting
|
// Allows user to configure volume permission change policy for fsGroups when mounting
|
||||||
// a volume in a Pod.
|
// a volume in a Pod.
|
||||||
ConfigurableFSGroupPolicy featuregate.Feature = "ConfigurableFSGroupPolicy"
|
ConfigurableFSGroupPolicy featuregate.Feature = "ConfigurableFSGroupPolicy"
|
||||||
@ -841,7 +842,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
|||||||
InTreePluginvSphereUnregister: {Default: false, PreRelease: featuregate.Alpha},
|
InTreePluginvSphereUnregister: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
CSIMigrationOpenStack: {Default: true, PreRelease: featuregate.Beta},
|
CSIMigrationOpenStack: {Default: true, PreRelease: featuregate.Beta},
|
||||||
InTreePluginOpenStackUnregister: {Default: false, PreRelease: featuregate.Alpha},
|
InTreePluginOpenStackUnregister: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
ConfigurableFSGroupPolicy: {Default: true, PreRelease: featuregate.Beta},
|
ConfigurableFSGroupPolicy: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
|
||||||
CSIInlineVolume: {Default: true, PreRelease: featuregate.Beta},
|
CSIInlineVolume: {Default: true, PreRelease: featuregate.Beta},
|
||||||
CSIStorageCapacity: {Default: true, PreRelease: featuregate.Beta},
|
CSIStorageCapacity: {Default: true, PreRelease: featuregate.Beta},
|
||||||
CSIServiceAccountToken: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23
|
CSIServiceAccountToken: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23
|
||||||
|
@ -110,7 +110,7 @@ func OperationCompleteHook(plugin, operationName string) func(types.CompleteFunc
|
|||||||
|
|
||||||
// FSGroupCompleteHook returns a hook to call when volume recursive permission is changed
|
// FSGroupCompleteHook returns a hook to call when volume recursive permission is changed
|
||||||
func FSGroupCompleteHook(plugin volume.VolumePlugin, spec *volume.Spec) func(types.CompleteFuncParam) {
|
func FSGroupCompleteHook(plugin volume.VolumePlugin, spec *volume.Spec) func(types.CompleteFuncParam) {
|
||||||
return OperationCompleteHook(GetFullQualifiedPluginNameForVolume(plugin.GetPluginName(), spec), "volume_fsgroup_recursive_apply")
|
return OperationCompleteHook(GetFullQualifiedPluginNameForVolume(plugin.GetPluginName(), spec), "volume_apply_access_control")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFullQualifiedPluginNameForVolume returns full qualified plugin name for
|
// GetFullQualifiedPluginNameForVolume returns full qualified plugin name for
|
||||||
|
@ -27,9 +27,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
"k8s.io/kubernetes/pkg/volume/util/types"
|
"k8s.io/kubernetes/pkg/volume/util/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -47,25 +45,11 @@ func SetVolumeOwnership(mounter Mounter, fsGroup *int64, fsGroupChangePolicy *v1
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
fsGroupPolicyEnabled := utilfeature.DefaultFeatureGate.Enabled(features.ConfigurableFSGroupPolicy)
|
|
||||||
|
|
||||||
timer := time.AfterFunc(30*time.Second, func() {
|
timer := time.AfterFunc(30*time.Second, func() {
|
||||||
klog.Warningf("Setting volume ownership for %s and fsGroup set. If the volume has a lot of files then setting volume ownership could be slow, see https://github.com/kubernetes/kubernetes/issues/69699", mounter.GetPath())
|
klog.Warningf("Setting volume ownership for %s and fsGroup set. If the volume has a lot of files then setting volume ownership could be slow, see https://github.com/kubernetes/kubernetes/issues/69699", mounter.GetPath())
|
||||||
})
|
})
|
||||||
defer timer.Stop()
|
defer timer.Stop()
|
||||||
|
|
||||||
// This code exists for legacy purposes, so as old behaviour is entirely preserved when feature gate is disabled
|
|
||||||
// TODO: remove this when ConfigurableFSGroupPolicy turns GA.
|
|
||||||
if !fsGroupPolicyEnabled {
|
|
||||||
err := legacyOwnershipChange(mounter, fsGroup)
|
|
||||||
if completeFunc != nil {
|
|
||||||
completeFunc(types.CompleteFuncParam{
|
|
||||||
Err: &err,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if skipPermissionChange(mounter, fsGroup, fsGroupChangePolicy) {
|
if skipPermissionChange(mounter, fsGroup, fsGroupChangePolicy) {
|
||||||
klog.V(3).InfoS("Skipping permission and ownership change for volume", "path", mounter.GetPath())
|
klog.V(3).InfoS("Skipping permission and ownership change for volume", "path", mounter.GetPath())
|
||||||
return nil
|
return nil
|
||||||
@ -85,15 +69,6 @@ func SetVolumeOwnership(mounter Mounter, fsGroup *int64, fsGroupChangePolicy *v1
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func legacyOwnershipChange(mounter Mounter, fsGroup *int64) error {
|
|
||||||
return filepath.Walk(mounter.GetPath(), func(path string, info os.FileInfo, err error) error {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return changeFilePermission(path, fsGroup, mounter.GetAttributes().ReadOnly, info)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func changeFilePermission(filename string, fsGroup *int64, readonly bool, info os.FileInfo) error {
|
func changeFilePermission(filename string, fsGroup *int64, readonly bool, info os.FileInfo) error {
|
||||||
err := os.Lchown(filename, -1, int(*fsGroup))
|
err := os.Lchown(filename, -1, int(*fsGroup))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -27,10 +27,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
utiltesting "k8s.io/client-go/util/testing"
|
utiltesting "k8s.io/client-go/util/testing"
|
||||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type localFakeMounter struct {
|
type localFakeMounter struct {
|
||||||
@ -192,12 +189,10 @@ func TestSetVolumeOwnershipMode(t *testing.T) {
|
|||||||
fsGroupChangePolicy *v1.PodFSGroupChangePolicy
|
fsGroupChangePolicy *v1.PodFSGroupChangePolicy
|
||||||
setupFunc func(path string) error
|
setupFunc func(path string) error
|
||||||
assertFunc func(path string) error
|
assertFunc func(path string) error
|
||||||
featureGate bool
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
description: "featuregate=on, fsgroupchangepolicy=always",
|
description: "featuregate=on, fsgroupchangepolicy=always",
|
||||||
fsGroupChangePolicy: &always,
|
fsGroupChangePolicy: &always,
|
||||||
featureGate: true,
|
|
||||||
setupFunc: func(path string) error {
|
setupFunc: func(path string) error {
|
||||||
info, err := os.Lstat(path)
|
info, err := os.Lstat(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -230,7 +225,6 @@ func TestSetVolumeOwnershipMode(t *testing.T) {
|
|||||||
{
|
{
|
||||||
description: "featuregate=on, fsgroupchangepolicy=onrootmismatch,rootdir=validperm",
|
description: "featuregate=on, fsgroupchangepolicy=onrootmismatch,rootdir=validperm",
|
||||||
fsGroupChangePolicy: &onrootMismatch,
|
fsGroupChangePolicy: &onrootMismatch,
|
||||||
featureGate: true,
|
|
||||||
setupFunc: func(path string) error {
|
setupFunc: func(path string) error {
|
||||||
info, err := os.Lstat(path)
|
info, err := os.Lstat(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -262,7 +256,6 @@ func TestSetVolumeOwnershipMode(t *testing.T) {
|
|||||||
{
|
{
|
||||||
description: "featuregate=on, fsgroupchangepolicy=onrootmismatch,rootdir=invalidperm",
|
description: "featuregate=on, fsgroupchangepolicy=onrootmismatch,rootdir=invalidperm",
|
||||||
fsGroupChangePolicy: &onrootMismatch,
|
fsGroupChangePolicy: &onrootMismatch,
|
||||||
featureGate: true,
|
|
||||||
setupFunc: func(path string) error {
|
setupFunc: func(path string) error {
|
||||||
// change mode of root folder to be right
|
// change mode of root folder to be right
|
||||||
err := os.Chmod(path, 0770)
|
err := os.Chmod(path, 0770)
|
||||||
@ -291,7 +284,6 @@ func TestSetVolumeOwnershipMode(t *testing.T) {
|
|||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.description, func(t *testing.T) {
|
t.Run(test.description, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ConfigurableFSGroupPolicy, test.featureGate)()
|
|
||||||
tmpDir, err := utiltesting.MkTmpdir("volume_linux_ownership")
|
tmpDir, err := utiltesting.MkTmpdir("volume_linux_ownership")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error creating temp dir: %v", err)
|
t.Fatalf("error creating temp dir: %v", err)
|
||||||
|
Loading…
Reference in New Issue
Block a user