mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-13 11:25:19 +00:00
Promote block volume features to GA
This commit is contained in:
@@ -22,10 +22,7 @@ import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
storage "k8s.io/api/storage/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
pvutil "k8s.io/kubernetes/pkg/controller/volume/persistentvolume/util"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
// Test single call to syncClaim and syncVolume methods.
|
||||
@@ -611,68 +608,6 @@ func TestSync(t *testing.T) {
|
||||
}, []*v1.Pod{})
|
||||
}
|
||||
|
||||
func TestSyncBlockVolumeDisabled(t *testing.T) {
|
||||
modeBlock := v1.PersistentVolumeBlock
|
||||
modeFile := v1.PersistentVolumeFilesystem
|
||||
// All of these should bind as feature set is not enabled for BlockVolume
|
||||
// meaning volumeMode will be ignored and dropped
|
||||
tests := []controllerTest{
|
||||
{
|
||||
// syncVolume binds a requested block claim to a block volume
|
||||
"14-1 - binding to volumeMode block",
|
||||
withVolumeVolumeMode(&modeBlock, newVolumeArray("volume14-1", "10Gi", "", "", v1.VolumeAvailable, v1.PersistentVolumeReclaimRetain, classEmpty)),
|
||||
withVolumeVolumeMode(&modeBlock, newVolumeArray("volume14-1", "10Gi", "", "", v1.VolumeAvailable, v1.PersistentVolumeReclaimRetain, classEmpty)),
|
||||
withClaimVolumeMode(&modeBlock, newClaimArray("claim14-1", "uid14-1", "10Gi", "", v1.ClaimPending, nil)),
|
||||
withClaimVolumeMode(&modeBlock, newClaimArray("claim14-1", "uid14-1", "10Gi", "", v1.ClaimPending, nil)),
|
||||
noevents, noerrors, testSyncClaim,
|
||||
},
|
||||
{
|
||||
// syncVolume binds a requested filesystem claim to a filesystem volume
|
||||
"14-2 - binding to volumeMode filesystem",
|
||||
withVolumeVolumeMode(&modeFile, newVolumeArray("volume14-2", "10Gi", "", "", v1.VolumeAvailable, v1.PersistentVolumeReclaimRetain, classEmpty)),
|
||||
withVolumeVolumeMode(&modeFile, newVolumeArray("volume14-2", "10Gi", "uid14-2", "claim14-2", v1.VolumeBound, v1.PersistentVolumeReclaimRetain, classEmpty, pvutil.AnnBoundByController)),
|
||||
withClaimVolumeMode(&modeFile, newClaimArray("claim14-2", "uid14-2", "10Gi", "", v1.ClaimPending, nil)),
|
||||
withClaimVolumeMode(&modeFile, newClaimArray("claim14-2", "uid14-2", "10Gi", "volume14-2", v1.ClaimBound, nil, pvutil.AnnBoundByController, pvutil.AnnBindCompleted)),
|
||||
noevents, noerrors, testSyncClaim,
|
||||
},
|
||||
{
|
||||
// syncVolume binds an unspecified volumemode for claim to a specified filesystem volume
|
||||
"14-3 - binding to volumeMode filesystem using default for claim",
|
||||
withVolumeVolumeMode(&modeFile, newVolumeArray("volume14-3", "10Gi", "", "", v1.VolumeAvailable, v1.PersistentVolumeReclaimRetain, classEmpty)),
|
||||
withVolumeVolumeMode(&modeFile, newVolumeArray("volume14-3", "10Gi", "uid14-3", "claim14-3", v1.VolumeBound, v1.PersistentVolumeReclaimRetain, classEmpty, pvutil.AnnBoundByController)),
|
||||
withClaimVolumeMode(nil, newClaimArray("claim14-3", "uid14-3", "10Gi", "", v1.ClaimPending, nil)),
|
||||
withClaimVolumeMode(nil, newClaimArray("claim14-3", "uid14-3", "10Gi", "volume14-3", v1.ClaimBound, nil, pvutil.AnnBoundByController, pvutil.AnnBindCompleted)),
|
||||
noevents, noerrors, testSyncClaim,
|
||||
},
|
||||
{
|
||||
// syncVolume binds a requested filesystem claim to an unspecified volumeMode for volume
|
||||
"14-4 - binding to unspecified volumeMode using requested filesystem for claim",
|
||||
withVolumeVolumeMode(nil, newVolumeArray("volume14-4", "10Gi", "", "", v1.VolumeAvailable, v1.PersistentVolumeReclaimRetain, classEmpty)),
|
||||
withVolumeVolumeMode(nil, newVolumeArray("volume14-4", "10Gi", "uid14-4", "claim14-4", v1.VolumeBound, v1.PersistentVolumeReclaimRetain, classEmpty, pvutil.AnnBoundByController)),
|
||||
withClaimVolumeMode(&modeFile, newClaimArray("claim14-4", "uid14-4", "10Gi", "", v1.ClaimPending, nil)),
|
||||
withClaimVolumeMode(&modeFile, newClaimArray("claim14-4", "uid14-4", "10Gi", "volume14-4", v1.ClaimBound, nil, pvutil.AnnBoundByController, pvutil.AnnBindCompleted)),
|
||||
noevents, noerrors, testSyncClaim,
|
||||
},
|
||||
{
|
||||
// syncVolume binds a requested filesystem claim to an unspecified volumeMode for volume
|
||||
"14-5 - binding different volumeModes should be ignored",
|
||||
withVolumeVolumeMode(&modeBlock, newVolumeArray("volume14-5", "10Gi", "", "", v1.VolumeAvailable, v1.PersistentVolumeReclaimRetain, classEmpty)),
|
||||
withVolumeVolumeMode(&modeBlock, newVolumeArray("volume14-5", "10Gi", "", "", v1.VolumeAvailable, v1.PersistentVolumeReclaimRetain, classEmpty)),
|
||||
withClaimVolumeMode(&modeFile, newClaimArray("claim14-5", "uid14-5", "10Gi", "", v1.ClaimPending, nil)),
|
||||
withClaimVolumeMode(&modeFile, newClaimArray("claim14-5", "uid14-5", "10Gi", "", v1.ClaimPending, nil)),
|
||||
noevents, noerrors, testSyncClaim,
|
||||
},
|
||||
}
|
||||
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, false)()
|
||||
runSyncTests(t, tests, []*storage.StorageClass{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: classWait},
|
||||
VolumeBindingMode: &modeWait,
|
||||
},
|
||||
}, []*v1.Pod{})
|
||||
}
|
||||
|
||||
func TestSyncBlockVolume(t *testing.T) {
|
||||
modeBlock := v1.PersistentVolumeBlock
|
||||
modeFile := v1.PersistentVolumeFilesystem
|
||||
@@ -853,8 +788,6 @@ func TestSyncBlockVolume(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
|
||||
|
||||
runSyncTests(t, tests, []*storage.StorageClass{}, []*v1.Pod{})
|
||||
}
|
||||
|
||||
|
||||
@@ -1060,91 +1060,56 @@ func TestVolumeModeCheck(t *testing.T) {
|
||||
isExpectedMismatch bool
|
||||
vol *v1.PersistentVolume
|
||||
pvc *v1.PersistentVolumeClaim
|
||||
enableBlock bool
|
||||
}{
|
||||
"feature enabled - pvc block and pv filesystem": {
|
||||
"pvc block and pv filesystem": {
|
||||
isExpectedMismatch: true,
|
||||
vol: createVolumeModeFilesystemTestVolume(),
|
||||
pvc: makeVolumeModePVC("8G", &blockMode, nil),
|
||||
enableBlock: true,
|
||||
},
|
||||
"feature enabled - pvc filesystem and pv block": {
|
||||
"pvc filesystem and pv block": {
|
||||
isExpectedMismatch: true,
|
||||
vol: createVolumeModeBlockTestVolume(),
|
||||
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
|
||||
enableBlock: true,
|
||||
},
|
||||
"feature enabled - pvc block and pv block": {
|
||||
"pvc block and pv block": {
|
||||
isExpectedMismatch: false,
|
||||
vol: createVolumeModeBlockTestVolume(),
|
||||
pvc: makeVolumeModePVC("8G", &blockMode, nil),
|
||||
enableBlock: true,
|
||||
},
|
||||
"feature enabled - pvc filesystem and pv filesystem": {
|
||||
"pvc filesystem and pv filesystem": {
|
||||
isExpectedMismatch: false,
|
||||
vol: createVolumeModeFilesystemTestVolume(),
|
||||
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
|
||||
enableBlock: true,
|
||||
},
|
||||
"feature enabled - pvc filesystem and pv nil": {
|
||||
"pvc filesystem and pv nil": {
|
||||
isExpectedMismatch: false,
|
||||
vol: createVolumeModeNilTestVolume(),
|
||||
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
|
||||
enableBlock: true,
|
||||
},
|
||||
"feature enabled - pvc nil and pv filesystem": {
|
||||
"pvc nil and pv filesystem": {
|
||||
isExpectedMismatch: false,
|
||||
vol: createVolumeModeFilesystemTestVolume(),
|
||||
pvc: makeVolumeModePVC("8G", nil, nil),
|
||||
enableBlock: true,
|
||||
},
|
||||
"feature enabled - pvc nil and pv nil": {
|
||||
"pvc nil and pv nil": {
|
||||
isExpectedMismatch: false,
|
||||
vol: createVolumeModeNilTestVolume(),
|
||||
pvc: makeVolumeModePVC("8G", nil, nil),
|
||||
enableBlock: true,
|
||||
},
|
||||
"feature enabled - pvc nil and pv block": {
|
||||
"pvc nil and pv block": {
|
||||
isExpectedMismatch: true,
|
||||
vol: createVolumeModeBlockTestVolume(),
|
||||
pvc: makeVolumeModePVC("8G", nil, nil),
|
||||
enableBlock: true,
|
||||
},
|
||||
"feature enabled - pvc block and pv nil": {
|
||||
"pvc block and pv nil": {
|
||||
isExpectedMismatch: true,
|
||||
vol: createVolumeModeNilTestVolume(),
|
||||
pvc: makeVolumeModePVC("8G", &blockMode, nil),
|
||||
enableBlock: true,
|
||||
},
|
||||
"feature disabled - pvc block and pv filesystem": {
|
||||
isExpectedMismatch: true,
|
||||
vol: createVolumeModeFilesystemTestVolume(),
|
||||
pvc: makeVolumeModePVC("8G", &blockMode, nil),
|
||||
enableBlock: false,
|
||||
},
|
||||
"feature disabled - pvc filesystem and pv block": {
|
||||
isExpectedMismatch: true,
|
||||
vol: createVolumeModeBlockTestVolume(),
|
||||
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
|
||||
enableBlock: false,
|
||||
},
|
||||
"feature disabled - pvc block and pv block": {
|
||||
isExpectedMismatch: true,
|
||||
vol: createVolumeModeBlockTestVolume(),
|
||||
pvc: makeVolumeModePVC("8G", &blockMode, nil),
|
||||
enableBlock: false,
|
||||
},
|
||||
"feature disabled - pvc filesystem and pv filesystem": {
|
||||
isExpectedMismatch: false,
|
||||
vol: createVolumeModeFilesystemTestVolume(),
|
||||
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
|
||||
enableBlock: false,
|
||||
},
|
||||
}
|
||||
|
||||
for name, scenario := range scenarios {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, scenario.enableBlock)()
|
||||
expectedMismatch := pvutil.CheckVolumeModeMismatches(&scenario.pvc.Spec, &scenario.vol.Spec)
|
||||
// expected to match but either got an error or no returned pvmatch
|
||||
if expectedMismatch && !scenario.isExpectedMismatch {
|
||||
@@ -1167,73 +1132,46 @@ func TestFilteringVolumeModes(t *testing.T) {
|
||||
isExpectedMatch bool
|
||||
vol persistentVolumeOrderedIndex
|
||||
pvc *v1.PersistentVolumeClaim
|
||||
enableBlock bool
|
||||
}{
|
||||
"1-1 feature enabled - pvc block and pv filesystem": {
|
||||
"pvc block and pv filesystem": {
|
||||
isExpectedMatch: false,
|
||||
vol: createTestVolOrderedIndex(createVolumeModeFilesystemTestVolume()),
|
||||
pvc: makeVolumeModePVC("8G", &blockMode, nil),
|
||||
enableBlock: true,
|
||||
},
|
||||
"1-2 feature enabled - pvc filesystem and pv block": {
|
||||
"pvc filesystem and pv block": {
|
||||
isExpectedMatch: false,
|
||||
vol: createTestVolOrderedIndex(createVolumeModeBlockTestVolume()),
|
||||
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
|
||||
enableBlock: true,
|
||||
},
|
||||
"1-3 feature enabled - pvc block and pv no mode with default filesystem": {
|
||||
"pvc block and pv no mode with default filesystem": {
|
||||
isExpectedMatch: false,
|
||||
vol: createTestVolOrderedIndex(createVolumeModeFilesystemTestVolume()),
|
||||
pvc: makeVolumeModePVC("8G", &blockMode, nil),
|
||||
enableBlock: true,
|
||||
},
|
||||
"1-4 feature enabled - pvc no mode defaulted to filesystem and pv block": {
|
||||
"pvc no mode defaulted to filesystem and pv block": {
|
||||
isExpectedMatch: false,
|
||||
vol: createTestVolOrderedIndex(createVolumeModeBlockTestVolume()),
|
||||
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
|
||||
enableBlock: true,
|
||||
},
|
||||
"1-5 feature enabled - pvc block and pv block": {
|
||||
"pvc block and pv block": {
|
||||
isExpectedMatch: true,
|
||||
vol: createTestVolOrderedIndex(createVolumeModeBlockTestVolume()),
|
||||
pvc: makeVolumeModePVC("8G", &blockMode, nil),
|
||||
enableBlock: true,
|
||||
},
|
||||
"1-6 feature enabled - pvc filesystem and pv filesystem": {
|
||||
"pvc filesystem and pv filesystem": {
|
||||
isExpectedMatch: true,
|
||||
vol: createTestVolOrderedIndex(createVolumeModeFilesystemTestVolume()),
|
||||
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
|
||||
enableBlock: true,
|
||||
},
|
||||
"1-7 feature enabled - pvc mode is nil and defaulted and pv mode is nil and defaulted": {
|
||||
"pvc mode is nil and defaulted and pv mode is nil and defaulted": {
|
||||
isExpectedMatch: true,
|
||||
vol: createTestVolOrderedIndex(createVolumeModeFilesystemTestVolume()),
|
||||
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
|
||||
enableBlock: true,
|
||||
},
|
||||
"2-1 feature disabled - pvc mode is nil and pv mode is nil": {
|
||||
isExpectedMatch: true,
|
||||
vol: createTestVolOrderedIndex(testVolume("nomode-1", "8G")),
|
||||
pvc: makeVolumeModePVC("8G", nil, nil),
|
||||
enableBlock: false,
|
||||
},
|
||||
"2-2 feature disabled - pvc mode is block and pv mode is block - fields should be dropped by api and not analyzed with gate disabled": {
|
||||
isExpectedMatch: false,
|
||||
vol: createTestVolOrderedIndex(createVolumeModeBlockTestVolume()),
|
||||
pvc: makeVolumeModePVC("8G", &blockMode, nil),
|
||||
enableBlock: false,
|
||||
},
|
||||
"2-3 feature disabled - pvc mode is filesystem and pv mode is filesystem - fields should be dropped by api and not analyzed with gate disabled": {
|
||||
isExpectedMatch: true,
|
||||
vol: createTestVolOrderedIndex(createVolumeModeFilesystemTestVolume()),
|
||||
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
|
||||
enableBlock: false,
|
||||
},
|
||||
}
|
||||
|
||||
for name, scenario := range scenarios {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, scenario.enableBlock)()
|
||||
pvmatch, err := scenario.vol.findBestMatchForClaim(scenario.pvc, false)
|
||||
// expected to match but either got an error or no returned pvmatch
|
||||
if pvmatch == nil && scenario.isExpectedMatch {
|
||||
|
||||
@@ -30,11 +30,9 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
core "k8s.io/client-go/testing"
|
||||
"k8s.io/klog"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
// ErrVersionConflict is the error returned when resource version of requested
|
||||
@@ -114,7 +112,7 @@ func (r *VolumeReactor) React(action core.Action) (handled bool, ret runtime.Obj
|
||||
}
|
||||
|
||||
// mimic apiserver defaulting
|
||||
if volume.Spec.VolumeMode == nil && utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
|
||||
if volume.Spec.VolumeMode == nil {
|
||||
volume.Spec.VolumeMode = new(v1.PersistentVolumeMode)
|
||||
*volume.Spec.VolumeMode = v1.PersistentVolumeFilesystem
|
||||
}
|
||||
|
||||
@@ -307,23 +307,6 @@ func FindMatchingVolume(
|
||||
// CheckVolumeModeMismatches is a convenience method that checks volumeMode for PersistentVolume
|
||||
// and PersistentVolumeClaims
|
||||
func CheckVolumeModeMismatches(pvcSpec *v1.PersistentVolumeClaimSpec, pvSpec *v1.PersistentVolumeSpec) bool {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
|
||||
if pvcSpec.VolumeMode != nil && *pvcSpec.VolumeMode == v1.PersistentVolumeBlock {
|
||||
// Block PVC does not match anything when the feature is off. We explicitly want
|
||||
// to prevent binding block PVC to filesystem PV.
|
||||
// The PVC should be ignored by PV controller.
|
||||
return true
|
||||
}
|
||||
if pvSpec.VolumeMode != nil && *pvSpec.VolumeMode == v1.PersistentVolumeBlock {
|
||||
// Block PV does not match anything when the feature is off. We explicitly want
|
||||
// to prevent binding block PV to filesystem PVC.
|
||||
// The PV should be ignored by PV controller.
|
||||
return true
|
||||
}
|
||||
// Both PV + PVC are not block.
|
||||
return false
|
||||
}
|
||||
|
||||
// In HA upgrades, we cannot guarantee that the apiserver is on a version >= controller-manager.
|
||||
// So we default a nil volumeMode to filesystem
|
||||
requestedVolumeMode := v1.PersistentVolumeFilesystem
|
||||
|
||||
Reference in New Issue
Block a user