mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-26 21:17:23 +00:00
Add GetPossiblyMountedVolumesForPod to let kubelet know all volumes were unmounted
podVolumesExist() should consider also uncertain volumes (where kubelet does not know if a volume was fully unmounted) when checking for pod's volumes. Added GetPossiblyMountedVolumesForPod for that. Adding uncertain mounts to GetMountedVolumesForPod would potentially break other callers (e.g. `verifyVolumesMountedFunc`).
This commit is contained in:
parent
f4b41c0a17
commit
ca934b8f5c
@ -74,7 +74,7 @@ func (kl *Kubelet) ListBlockVolumesForPod(podUID types.UID) (map[string]volume.B
|
|||||||
// pods for the specified volume are mounted.
|
// pods for the specified volume are mounted.
|
||||||
func (kl *Kubelet) podVolumesExist(podUID types.UID) bool {
|
func (kl *Kubelet) podVolumesExist(podUID types.UID) bool {
|
||||||
if mountedVolumes :=
|
if mountedVolumes :=
|
||||||
kl.volumeManager.GetMountedVolumesForPod(
|
kl.volumeManager.GetPossiblyMountedVolumesForPod(
|
||||||
volumetypes.UniquePodName(podUID)); len(mountedVolumes) > 0 {
|
volumetypes.UniquePodName(podUID)); len(mountedVolumes) > 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -397,6 +397,9 @@ func TestVolumeAttachAndMountControllerEnabled(t *testing.T) {
|
|||||||
|
|
||||||
podVolumes := kubelet.volumeManager.GetMountedVolumesForPod(
|
podVolumes := kubelet.volumeManager.GetMountedVolumesForPod(
|
||||||
util.GetUniquePodName(pod))
|
util.GetUniquePodName(pod))
|
||||||
|
allPodVolumes := kubelet.volumeManager.GetPossiblyMountedVolumesForPod(
|
||||||
|
util.GetUniquePodName(pod))
|
||||||
|
assert.Equal(t, podVolumes, allPodVolumes, "GetMountedVolumesForPod and GetPossiblyMountedVolumesForPod should return the same volumes")
|
||||||
|
|
||||||
expectedPodVolumes := []string{"vol1"}
|
expectedPodVolumes := []string{"vol1"}
|
||||||
assert.Len(t, podVolumes, len(expectedPodVolumes), "Volumes for pod %+v", pod)
|
assert.Len(t, podVolumes, len(expectedPodVolumes), "Volumes for pod %+v", pod)
|
||||||
@ -476,6 +479,9 @@ func TestVolumeUnmountAndDetachControllerEnabled(t *testing.T) {
|
|||||||
|
|
||||||
podVolumes := kubelet.volumeManager.GetMountedVolumesForPod(
|
podVolumes := kubelet.volumeManager.GetMountedVolumesForPod(
|
||||||
util.GetUniquePodName(pod))
|
util.GetUniquePodName(pod))
|
||||||
|
allPodVolumes := kubelet.volumeManager.GetPossiblyMountedVolumesForPod(
|
||||||
|
util.GetUniquePodName(pod))
|
||||||
|
assert.Equal(t, podVolumes, allPodVolumes, "GetMountedVolumesForPod and GetPossiblyMountedVolumesForPod should return the same volumes")
|
||||||
|
|
||||||
expectedPodVolumes := []string{"vol1"}
|
expectedPodVolumes := []string{"vol1"}
|
||||||
assert.Len(t, podVolumes, len(expectedPodVolumes), "Volumes for pod %+v", pod)
|
assert.Len(t, podVolumes, len(expectedPodVolumes), "Volumes for pod %+v", pod)
|
||||||
@ -500,6 +506,9 @@ func TestVolumeUnmountAndDetachControllerEnabled(t *testing.T) {
|
|||||||
// Verify volumes unmounted
|
// Verify volumes unmounted
|
||||||
podVolumes = kubelet.volumeManager.GetMountedVolumesForPod(
|
podVolumes = kubelet.volumeManager.GetMountedVolumesForPod(
|
||||||
util.GetUniquePodName(pod))
|
util.GetUniquePodName(pod))
|
||||||
|
allPodVolumes = kubelet.volumeManager.GetPossiblyMountedVolumesForPod(
|
||||||
|
util.GetUniquePodName(pod))
|
||||||
|
assert.Equal(t, podVolumes, allPodVolumes, "GetMountedVolumesForPod and GetPossiblyMountedVolumesForPod should return the same volumes")
|
||||||
|
|
||||||
assert.Len(t, podVolumes, 0,
|
assert.Len(t, podVolumes, 0,
|
||||||
"Expected volumes to be unmounted and detached. But some volumes are still mounted: %#v", podVolumes)
|
"Expected volumes to be unmounted and detached. But some volumes are still mounted: %#v", podVolumes)
|
||||||
|
@ -136,6 +136,11 @@ type ActualStateOfWorld interface {
|
|||||||
// current actual state of the world.
|
// current actual state of the world.
|
||||||
GetMountedVolumesForPod(podName volumetypes.UniquePodName) []MountedVolume
|
GetMountedVolumesForPod(podName volumetypes.UniquePodName) []MountedVolume
|
||||||
|
|
||||||
|
// GetPossiblyMountedVolumesForPod generates and returns a list of volumes for
|
||||||
|
// the specified pod that either are attached and mounted or are "uncertain",
|
||||||
|
// i.e. a volume plugin may be mounting the volume right now.
|
||||||
|
GetPossiblyMountedVolumesForPod(podName volumetypes.UniquePodName) []MountedVolume
|
||||||
|
|
||||||
// GetGloballyMountedVolumes generates and returns a list of all attached
|
// GetGloballyMountedVolumes generates and returns a list of all attached
|
||||||
// volumes that are globally mounted. This list can be used to determine
|
// volumes that are globally mounted. This list can be used to determine
|
||||||
// which volumes should be reported as "in use" in the node's VolumesInUse
|
// which volumes should be reported as "in use" in the node's VolumesInUse
|
||||||
@ -757,6 +762,26 @@ func (asw *actualStateOfWorld) GetMountedVolumesForPod(
|
|||||||
return mountedVolume
|
return mountedVolume
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (asw *actualStateOfWorld) GetPossiblyMountedVolumesForPod(
|
||||||
|
podName volumetypes.UniquePodName) []MountedVolume {
|
||||||
|
asw.RLock()
|
||||||
|
defer asw.RUnlock()
|
||||||
|
mountedVolume := make([]MountedVolume, 0 /* len */, len(asw.attachedVolumes) /* cap */)
|
||||||
|
for _, volumeObj := range asw.attachedVolumes {
|
||||||
|
for mountedPodName, podObj := range volumeObj.mountedPods {
|
||||||
|
if mountedPodName == podName &&
|
||||||
|
(podObj.volumeMountStateForPod == operationexecutor.VolumeMounted ||
|
||||||
|
podObj.volumeMountStateForPod == operationexecutor.VolumeMountUncertain) {
|
||||||
|
mountedVolume = append(
|
||||||
|
mountedVolume,
|
||||||
|
getMountedVolume(&podObj, &volumeObj))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mountedVolume
|
||||||
|
}
|
||||||
|
|
||||||
func (asw *actualStateOfWorld) GetGloballyMountedVolumes() []AttachedVolume {
|
func (asw *actualStateOfWorld) GetGloballyMountedVolumes() []AttachedVolume {
|
||||||
asw.RLock()
|
asw.RLock()
|
||||||
defer asw.RUnlock()
|
defer asw.RUnlock()
|
||||||
|
@ -20,7 +20,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/kubernetes/pkg/volume"
|
"k8s.io/kubernetes/pkg/volume"
|
||||||
volumetesting "k8s.io/kubernetes/pkg/volume/testing"
|
volumetesting "k8s.io/kubernetes/pkg/volume/testing"
|
||||||
@ -653,7 +653,18 @@ func TestUncertainVolumeMounts(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if volumeFound {
|
if volumeFound {
|
||||||
t.Fatalf("expected volume %s to be not found in asw", volumeSpec1.Name())
|
t.Fatalf("expected volume %s to be not found in asw.GetMountedVolumesForPod", volumeSpec1.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
possiblyMountedVolumes := asw.GetPossiblyMountedVolumesForPod(podName1)
|
||||||
|
volumeFound = false
|
||||||
|
for _, volume := range possiblyMountedVolumes {
|
||||||
|
if volume.InnerVolumeSpecName == volumeSpec1.Name() {
|
||||||
|
volumeFound = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !volumeFound {
|
||||||
|
t.Fatalf("expected volume %s to be found in aws.GetPossiblyMountedVolumesForPod", volumeSpec1.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
volExists, _, _ := asw.PodExistsInVolume(podName1, generatedVolumeName1)
|
volExists, _, _ := asw.PodExistsInVolume(podName1, generatedVolumeName1)
|
||||||
|
@ -113,6 +113,14 @@ type VolumeManager interface {
|
|||||||
// volumes.
|
// volumes.
|
||||||
GetMountedVolumesForPod(podName types.UniquePodName) container.VolumeMap
|
GetMountedVolumesForPod(podName types.UniquePodName) container.VolumeMap
|
||||||
|
|
||||||
|
// GetPossiblyMountedVolumesForPod returns a VolumeMap containing the volumes
|
||||||
|
// referenced by the specified pod that are either successfully attached
|
||||||
|
// and mounted or are "uncertain", i.e. a volume plugin may be mounting
|
||||||
|
// them right now. The key in the map is the OuterVolumeSpecName (i.e.
|
||||||
|
// pod.Spec.Volumes[x].Name). It returns an empty VolumeMap if pod has no
|
||||||
|
// volumes.
|
||||||
|
GetPossiblyMountedVolumesForPod(podName types.UniquePodName) container.VolumeMap
|
||||||
|
|
||||||
// GetExtraSupplementalGroupsForPod returns a list of the extra
|
// GetExtraSupplementalGroupsForPod returns a list of the extra
|
||||||
// supplemental groups for the Pod. These extra supplemental groups come
|
// supplemental groups for the Pod. These extra supplemental groups come
|
||||||
// from annotations on persistent volumes that the pod depends on.
|
// from annotations on persistent volumes that the pod depends on.
|
||||||
@ -290,6 +298,19 @@ func (vm *volumeManager) GetMountedVolumesForPod(podName types.UniquePodName) co
|
|||||||
return podVolumes
|
return podVolumes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (vm *volumeManager) GetPossiblyMountedVolumesForPod(podName types.UniquePodName) container.VolumeMap {
|
||||||
|
podVolumes := make(container.VolumeMap)
|
||||||
|
for _, mountedVolume := range vm.actualStateOfWorld.GetPossiblyMountedVolumesForPod(podName) {
|
||||||
|
podVolumes[mountedVolume.OuterVolumeSpecName] = container.VolumeInfo{
|
||||||
|
Mounter: mountedVolume.Mounter,
|
||||||
|
BlockVolumeMapper: mountedVolume.BlockVolumeMapper,
|
||||||
|
ReadOnly: mountedVolume.VolumeSpec.ReadOnly,
|
||||||
|
InnerVolumeSpecName: mountedVolume.InnerVolumeSpecName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return podVolumes
|
||||||
|
}
|
||||||
|
|
||||||
func (vm *volumeManager) GetExtraSupplementalGroupsForPod(pod *v1.Pod) []int64 {
|
func (vm *volumeManager) GetExtraSupplementalGroupsForPod(pod *v1.Pod) []int64 {
|
||||||
podName := util.GetUniquePodName(pod)
|
podName := util.GetUniquePodName(pod)
|
||||||
supplementalGroups := sets.NewString()
|
supplementalGroups := sets.NewString()
|
||||||
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||||||
package volumemanager
|
package volumemanager
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/config"
|
"k8s.io/kubernetes/pkg/kubelet/config"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/container"
|
"k8s.io/kubernetes/pkg/kubelet/container"
|
||||||
"k8s.io/kubernetes/pkg/volume/util/types"
|
"k8s.io/kubernetes/pkg/volume/util/types"
|
||||||
@ -55,6 +55,11 @@ func (f *FakeVolumeManager) GetMountedVolumesForPod(podName types.UniquePodName)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetPossiblyMountedVolumesForPod is not implemented
|
||||||
|
func (f *FakeVolumeManager) GetPossiblyMountedVolumesForPod(podName types.UniquePodName) container.VolumeMap {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetExtraSupplementalGroupsForPod is not implemented
|
// GetExtraSupplementalGroupsForPod is not implemented
|
||||||
func (f *FakeVolumeManager) GetExtraSupplementalGroupsForPod(pod *v1.Pod) []int64 {
|
func (f *FakeVolumeManager) GetExtraSupplementalGroupsForPod(pod *v1.Pod) []int64 {
|
||||||
return nil
|
return nil
|
||||||
|
Loading…
Reference in New Issue
Block a user