mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 05:57:25 +00:00
Fix VolumeAttachment garbage collection for migrated PVs
This commit is contained in:
parent
ae1f28d7b0
commit
cd3709232f
@ -715,33 +715,45 @@ func (adc *attachDetachController) processVolumeAttachments() error {
|
|||||||
klog.Errorf("Unable to lookup pv object for: %q, err: %v", *pvName, err)
|
klog.Errorf("Unable to lookup pv object for: %q, err: %v", *pvName, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var plugin volume.AttachableVolumePlugin
|
||||||
volumeSpec := volume.NewSpecFromPersistentVolume(pv, false)
|
volumeSpec := volume.NewSpecFromPersistentVolume(pv, false)
|
||||||
plugin, err := adc.volumePluginMgr.FindAttachablePluginBySpec(volumeSpec)
|
|
||||||
if err != nil || plugin == nil {
|
// Consult csiMigratedPluginManager first before querying the plugins registered during runtime in volumePluginMgr.
|
||||||
// Currently VA objects are created for CSI volumes only. nil plugin is unexpected, generate a warning
|
// In-tree plugins that provisioned PVs will not be registered anymore after migration to CSI, once the respective
|
||||||
klog.Warningf(
|
// feature gate is enabled.
|
||||||
"Skipping processing the volume %q on nodeName: %q, no attacher interface found. err=%v",
|
if inTreePluginName, err := adc.csiMigratedPluginManager.GetInTreePluginNameFromSpec(pv, nil); err == nil {
|
||||||
*pvName,
|
if adc.csiMigratedPluginManager.IsMigrationEnabledForPlugin(inTreePluginName) {
|
||||||
nodeName,
|
// PV is migrated and should be handled by the CSI plugin instead of the in-tree one
|
||||||
err)
|
plugin, _ = adc.volumePluginMgr.FindAttachablePluginByName(csi.CSIPluginName)
|
||||||
continue
|
// podNamespace is not needed here for Azurefile as the volumeName generated will be the same with or without podNamespace
|
||||||
|
volumeSpec, err = csimigration.TranslateInTreeSpecToCSI(volumeSpec, "" /* podNamespace */, adc.intreeToCSITranslator)
|
||||||
|
if err != nil {
|
||||||
|
klog.Errorf(
|
||||||
|
"Failed to translate intree volumeSpec to CSI volumeSpec for volume:%q, va.Name:%q, nodeName:%q: %s. Error: %v",
|
||||||
|
*pvName,
|
||||||
|
va.Name,
|
||||||
|
nodeName,
|
||||||
|
inTreePluginName,
|
||||||
|
err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pluginName := plugin.GetPluginName()
|
|
||||||
if adc.csiMigratedPluginManager.IsMigrationEnabledForPlugin(pluginName) {
|
if plugin == nil {
|
||||||
plugin, _ = adc.volumePluginMgr.FindAttachablePluginByName(csi.CSIPluginName)
|
plugin, err = adc.volumePluginMgr.FindAttachablePluginBySpec(volumeSpec)
|
||||||
// podNamespace is not needed here for Azurefile as the volumeName generated will be the same with or without podNamespace
|
if err != nil || plugin == nil {
|
||||||
volumeSpec, err = csimigration.TranslateInTreeSpecToCSI(volumeSpec, "" /* podNamespace */, adc.intreeToCSITranslator)
|
// Currently VA objects are created for CSI volumes only. nil plugin is unexpected, generate a warning
|
||||||
if err != nil {
|
klog.Warningf(
|
||||||
klog.Errorf(
|
"Skipping processing the volume %q on nodeName: %q, no attacher interface found. err=%v",
|
||||||
"Failed to translate intree volumeSpec to CSI volumeSpec for volume:%q, va.Name:%q, nodeName:%q: %v",
|
|
||||||
*pvName,
|
*pvName,
|
||||||
va.Name,
|
|
||||||
nodeName,
|
nodeName,
|
||||||
pluginName,
|
|
||||||
err)
|
err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
volumeName, err := volumeutil.GetUniqueVolumeNameFromSpec(plugin, volumeSpec)
|
volumeName, err := volumeutil.GetUniqueVolumeNameFromSpec(plugin, volumeSpec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf(
|
klog.Errorf(
|
||||||
|
@ -36,7 +36,6 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/features"
|
"k8s.io/kubernetes/pkg/features"
|
||||||
"k8s.io/kubernetes/pkg/volume"
|
"k8s.io/kubernetes/pkg/volume"
|
||||||
"k8s.io/kubernetes/pkg/volume/csi"
|
"k8s.io/kubernetes/pkg/volume/csi"
|
||||||
"k8s.io/kubernetes/pkg/volume/gcepd"
|
|
||||||
"k8s.io/kubernetes/pkg/volume/util"
|
"k8s.io/kubernetes/pkg/volume/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -351,17 +350,18 @@ func attachDetachRecoveryTestCase(t *testing.T, extraPods1 []*v1.Pod, extraPods2
|
|||||||
}
|
}
|
||||||
|
|
||||||
type vaTest struct {
|
type vaTest struct {
|
||||||
testName string
|
testName string
|
||||||
volName string
|
volName string
|
||||||
podName string
|
podName string
|
||||||
podNodeName string
|
podNodeName string
|
||||||
pvName string
|
pvName string
|
||||||
vaName string
|
vaName string
|
||||||
vaNodeName string
|
vaNodeName string
|
||||||
vaAttachStatus bool
|
vaAttachStatus bool
|
||||||
csiMigration bool
|
csiMigration bool
|
||||||
expected_attaches map[string][]string
|
expected_attaches map[string][]string
|
||||||
expected_detaches map[string][]string
|
expected_detaches map[string][]string
|
||||||
|
expectedASWAttachState cache.AttachState
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_ADC_VolumeAttachmentRecovery(t *testing.T) {
|
func Test_ADC_VolumeAttachmentRecovery(t *testing.T) {
|
||||||
@ -398,15 +398,26 @@ func Test_ADC_VolumeAttachmentRecovery(t *testing.T) {
|
|||||||
expected_attaches: map[string][]string{},
|
expected_attaches: map[string][]string{},
|
||||||
expected_detaches: map[string][]string{"mynode-1": {"vol1"}},
|
expected_detaches: map[string][]string{"mynode-1": {"vol1"}},
|
||||||
},
|
},
|
||||||
{
|
{ // pod is scheduled, volume is migrated, attach status:false, verify volume is marked as attached
|
||||||
testName: "CSI Migration",
|
testName: "Scheduled Pod with migrated PV",
|
||||||
volName: "vol1",
|
volName: "vol1",
|
||||||
podNodeName: "mynode-1",
|
podNodeName: "mynode-1",
|
||||||
pvName: "pv1",
|
pvName: "pv1",
|
||||||
vaName: "va1",
|
vaName: "va1",
|
||||||
vaNodeName: "mynode-1",
|
vaNodeName: "mynode-1",
|
||||||
vaAttachStatus: false,
|
vaAttachStatus: false,
|
||||||
csiMigration: true,
|
csiMigration: true,
|
||||||
|
expectedASWAttachState: cache.AttachStateAttached,
|
||||||
|
},
|
||||||
|
{ // pod is deleted, volume is migrated, attach status:false, verify volume is marked as uncertain
|
||||||
|
testName: "Deleted Pod with migrated PV",
|
||||||
|
volName: "vol1",
|
||||||
|
pvName: "pv1",
|
||||||
|
vaName: "va1",
|
||||||
|
vaNodeName: "mynode-1",
|
||||||
|
vaAttachStatus: false,
|
||||||
|
csiMigration: true,
|
||||||
|
expectedASWAttachState: cache.AttachStateUncertain,
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(tc.testName, func(t *testing.T) {
|
t.Run(tc.testName, func(t *testing.T) {
|
||||||
@ -424,7 +435,7 @@ func volumeAttachmentRecoveryTestCase(t *testing.T, tc vaTest) {
|
|||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIMigrationGCE, tc.csiMigration)()
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIMigrationGCE, tc.csiMigration)()
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.InTreePluginGCEUnregister, tc.csiMigration)()
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.InTreePluginGCEUnregister, tc.csiMigration)()
|
||||||
|
|
||||||
plugins = gcepd.ProbeVolumePlugins()
|
// if InTreePluginGCEUnregister is enabled, only the CSI plugin is registered but not the in-tree one
|
||||||
plugins = append(plugins, csi.ProbeVolumePlugins()...)
|
plugins = append(plugins, csi.ProbeVolumePlugins()...)
|
||||||
} else {
|
} else {
|
||||||
plugins = controllervolumetesting.CreateTestPlugin()
|
plugins = controllervolumetesting.CreateTestPlugin()
|
||||||
@ -569,8 +580,8 @@ func verifyExpectedVolumeState(t *testing.T, adc *attachDetachController, tc vaT
|
|||||||
// Since csi migration is turned on, the attach state for the PV should be in CSI format.
|
// Since csi migration is turned on, the attach state for the PV should be in CSI format.
|
||||||
attachedState := adc.actualStateOfWorld.GetAttachState(
|
attachedState := adc.actualStateOfWorld.GetAttachState(
|
||||||
v1.UniqueVolumeName(csiPDUniqueNamePrefix+tc.volName), types.NodeName(tc.vaNodeName))
|
v1.UniqueVolumeName(csiPDUniqueNamePrefix+tc.volName), types.NodeName(tc.vaNodeName))
|
||||||
if attachedState != cache.AttachStateAttached {
|
if attachedState != tc.expectedASWAttachState {
|
||||||
t.Fatalf("Expected attachedState %v, but it is %v", cache.AttachStateAttached, attachedState)
|
t.Fatalf("Expected attachedState %v, but it is %v", tc.expectedASWAttachState, attachedState)
|
||||||
}
|
}
|
||||||
|
|
||||||
// kubernetes.io/gce-pd/<volName> should not be marked when CSI Migration is on
|
// kubernetes.io/gce-pd/<volName> should not be marked when CSI Migration is on
|
||||||
|
Loading…
Reference in New Issue
Block a user