kubelet: also provide filesystem stats for generic ephemeral volumes
When checking for a reference to a PVC, the code also needs to consider that a PVC might be referenced indirectly through an ephemeral volume source.
This commit is contained in:
		| @@ -26,6 +26,7 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/util/wait" | 	"k8s.io/apimachinery/pkg/util/wait" | ||||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" | 	utilfeature "k8s.io/apiserver/pkg/util/feature" | ||||||
| 	"k8s.io/client-go/tools/record" | 	"k8s.io/client-go/tools/record" | ||||||
|  | 	"k8s.io/component-helpers/storage/ephemeral" | ||||||
| 	"k8s.io/klog/v2" | 	"k8s.io/klog/v2" | ||||||
| 	stats "k8s.io/kubelet/pkg/apis/stats/v1alpha1" | 	stats "k8s.io/kubelet/pkg/apis/stats/v1alpha1" | ||||||
| 	"k8s.io/kubernetes/pkg/features" | 	"k8s.io/kubernetes/pkg/features" | ||||||
| @@ -149,6 +150,12 @@ func (s *volumeStatCalculator) calcAndStoreStats() { | |||||||
| 				Namespace: s.pod.GetNamespace(), | 				Namespace: s.pod.GetNamespace(), | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 		if volSpec.Ephemeral != nil && utilfeature.DefaultFeatureGate.Enabled(features.GenericEphemeralVolume) { | ||||||
|  | 			pvcRef = &stats.PVCReference{ | ||||||
|  | 				Name:      ephemeral.VolumeClaimName(s.pod, &volSpec), | ||||||
|  | 				Namespace: s.pod.GetNamespace(), | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 		volumeStats := s.parsePodVolumeStats(name, pvcRef, metric, volSpec) | 		volumeStats := s.parsePodVolumeStats(name, pvcRef, metric, volSpec) | ||||||
| 		if util.IsLocalEphemeralVolume(volSpec) { | 		if util.IsLocalEphemeralVolume(volSpec) { | ||||||
| 			ephemeralStats = append(ephemeralStats, volumeStats) | 			ephemeralStats = append(ephemeralStats, volumeStats) | ||||||
|   | |||||||
| @@ -49,6 +49,7 @@ const ( | |||||||
| 	vol0          = "vol0" | 	vol0          = "vol0" | ||||||
| 	vol1          = "vol1" | 	vol1          = "vol1" | ||||||
| 	vol2          = "vol2" | 	vol2          = "vol2" | ||||||
|  | 	vol3          = "vol3" | ||||||
| 	pvcClaimName0 = "pvc-fake0" | 	pvcClaimName0 = "pvc-fake0" | ||||||
| 	pvcClaimName1 = "pvc-fake1" | 	pvcClaimName1 = "pvc-fake1" | ||||||
| ) | ) | ||||||
| @@ -81,6 +82,12 @@ var ( | |||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
|  | 		{ | ||||||
|  | 			Name: vol3, | ||||||
|  | 			VolumeSource: k8sv1.VolumeSource{ | ||||||
|  | 				Ephemeral: &k8sv1.EphemeralVolumeSource{}, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	fakePod = &k8sv1.Pod{ | 	fakePod = &k8sv1.Pod{ | ||||||
| @@ -98,12 +105,13 @@ var ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| func TestPVCRef(t *testing.T) { | func TestPVCRef(t *testing.T) { | ||||||
|  | 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.GenericEphemeralVolume, true)() | ||||||
| 	mockCtrl := gomock.NewController(t) | 	mockCtrl := gomock.NewController(t) | ||||||
| 	defer mockCtrl.Finish() | 	defer mockCtrl.Finish() | ||||||
|  |  | ||||||
| 	// Setup mock stats provider | 	// Setup mock stats provider | ||||||
| 	mockStats := statstest.NewMockProvider(mockCtrl) | 	mockStats := statstest.NewMockProvider(mockCtrl) | ||||||
| 	volumes := map[string]volume.Volume{vol0: &fakeVolume{}, vol1: &fakeVolume{}} | 	volumes := map[string]volume.Volume{vol0: &fakeVolume{}, vol1: &fakeVolume{}, vol3: &fakeVolume{}} | ||||||
| 	mockStats.EXPECT().ListVolumesForPod(fakePod.UID).Return(volumes, true) | 	mockStats.EXPECT().ListVolumesForPod(fakePod.UID).Return(volumes, true) | ||||||
| 	blockVolumes := map[string]volume.BlockVolume{vol2: &fakeBlockVolume{}} | 	blockVolumes := map[string]volume.BlockVolume{vol2: &fakeBlockVolume{}} | ||||||
| 	mockStats.EXPECT().ListBlockVolumesForPod(fakePod.UID).Return(blockVolumes, true) | 	mockStats.EXPECT().ListBlockVolumesForPod(fakePod.UID).Return(blockVolumes, true) | ||||||
| @@ -118,7 +126,7 @@ func TestPVCRef(t *testing.T) { | |||||||
| 	statsCalculator.calcAndStoreStats() | 	statsCalculator.calcAndStoreStats() | ||||||
| 	vs, _ := statsCalculator.GetLatest() | 	vs, _ := statsCalculator.GetLatest() | ||||||
|  |  | ||||||
| 	assert.Len(t, append(vs.EphemeralVolumes, vs.PersistentVolumes...), 3) | 	assert.Len(t, append(vs.EphemeralVolumes, vs.PersistentVolumes...), 4) | ||||||
| 	// Verify 'vol0' doesn't have a PVC reference | 	// Verify 'vol0' doesn't have a PVC reference | ||||||
| 	assert.Contains(t, append(vs.EphemeralVolumes, vs.PersistentVolumes...), kubestats.VolumeStats{ | 	assert.Contains(t, append(vs.EphemeralVolumes, vs.PersistentVolumes...), kubestats.VolumeStats{ | ||||||
| 		Name:    vol0, | 		Name:    vol0, | ||||||
| @@ -142,6 +150,15 @@ func TestPVCRef(t *testing.T) { | |||||||
| 		}, | 		}, | ||||||
| 		FsStats: expectedBlockStats(), | 		FsStats: expectedBlockStats(), | ||||||
| 	}) | 	}) | ||||||
|  | 	// Verify 'vol3' has a PVC reference | ||||||
|  | 	assert.Contains(t, append(vs.EphemeralVolumes, vs.PersistentVolumes...), kubestats.VolumeStats{ | ||||||
|  | 		Name: vol3, | ||||||
|  | 		PVCRef: &kubestats.PVCReference{ | ||||||
|  | 			Name:      pName0 + "-" + vol3, | ||||||
|  | 			Namespace: namespace0, | ||||||
|  | 		}, | ||||||
|  | 		FsStats: expectedFSStats(), | ||||||
|  | 	}) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestNormalVolumeEvent(t *testing.T) { | func TestNormalVolumeEvent(t *testing.T) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Patrick Ohly
					Patrick Ohly