add volumeHealth label to metrics

This commit is contained in:
fengzixu 2021-11-26 10:50:24 +09:00
parent bab1755274
commit ed7fd0ced5
6 changed files with 41 additions and 24 deletions

View File

@ -65,7 +65,7 @@ var (
volumeStatsHealthAbnormalDesc = metrics.NewDesc( volumeStatsHealthAbnormalDesc = metrics.NewDesc(
metrics.BuildFQName("", kubeletmetrics.KubeletSubsystem, kubeletmetrics.VolumeStatsHealthStatusKey), metrics.BuildFQName("", kubeletmetrics.KubeletSubsystem, kubeletmetrics.VolumeStatsHealthStatusKey),
"Volume health status. The count is either 1 or 0", "Volume health status. The count is either 1 or 0",
[]string{"namespace", "persistentvolumeclaim"}, nil, []string{"namespace", "persistentvolumeclaim", "volume_health_status"}, nil,
metrics.ALPHA, "") metrics.ALPHA, "")
) )
@ -102,7 +102,6 @@ func (collector *volumeStatsCollector) CollectWithStability(ch chan<- metrics.Me
} }
addGauge := func(desc *metrics.Desc, pvcRef *stats.PVCReference, v float64, lv ...string) { addGauge := func(desc *metrics.Desc, pvcRef *stats.PVCReference, v float64, lv ...string) {
lv = append([]string{pvcRef.Namespace, pvcRef.Name}, lv...) lv = append([]string{pvcRef.Namespace, pvcRef.Name}, lv...)
ch <- metrics.NewLazyConstMetric(desc, metrics.GaugeValue, v, lv...) ch <- metrics.NewLazyConstMetric(desc, metrics.GaugeValue, v, lv...)
} }
allPVCs := sets.String{} allPVCs := sets.String{}
@ -127,7 +126,7 @@ func (collector *volumeStatsCollector) CollectWithStability(ch chan<- metrics.Me
addGauge(volumeStatsInodesDesc, pvcRef, float64(*volumeStat.Inodes)) addGauge(volumeStatsInodesDesc, pvcRef, float64(*volumeStat.Inodes))
addGauge(volumeStatsInodesFreeDesc, pvcRef, float64(*volumeStat.InodesFree)) addGauge(volumeStatsInodesFreeDesc, pvcRef, float64(*volumeStat.InodesFree))
addGauge(volumeStatsInodesUsedDesc, pvcRef, float64(*volumeStat.InodesUsed)) addGauge(volumeStatsInodesUsedDesc, pvcRef, float64(*volumeStat.InodesUsed))
addGauge(volumeStatsHealthAbnormalDesc, pvcRef, convertBoolToFloat64(volumeStat.Abnormal)) addGauge(volumeStatsHealthAbnormalDesc, pvcRef, convertBoolToFloat64(volumeStat.VolumeHealthStats.Abnormal), "abnormal")
allPVCs.Insert(pvcUniqStr) allPVCs.Insert(pvcUniqStr)
} }
} }

View File

@ -85,7 +85,7 @@ func TestVolumeStatsCollector(t *testing.T) {
Name: "testpvc", Name: "testpvc",
Namespace: "testns", Namespace: "testns",
}, },
VolumeHealthStats: statsapi.VolumeHealthStats{ VolumeHealthStats: &statsapi.VolumeHealthStats{
Abnormal: true, Abnormal: true,
}, },
}, },
@ -111,7 +111,7 @@ func TestVolumeStatsCollector(t *testing.T) {
Name: "testpvc", Name: "testpvc",
Namespace: "testns", Namespace: "testns",
}, },
VolumeHealthStats: statsapi.VolumeHealthStats{ VolumeHealthStats: &statsapi.VolumeHealthStats{
Abnormal: true, Abnormal: true,
}, },
}, },
@ -126,7 +126,7 @@ func TestVolumeStatsCollector(t *testing.T) {
kubelet_volume_stats_inodes_free{namespace="testns",persistentvolumeclaim="testpvc"} 655344 kubelet_volume_stats_inodes_free{namespace="testns",persistentvolumeclaim="testpvc"} 655344
kubelet_volume_stats_inodes_used{namespace="testns",persistentvolumeclaim="testpvc"} 16 kubelet_volume_stats_inodes_used{namespace="testns",persistentvolumeclaim="testpvc"} 16
kubelet_volume_stats_used_bytes{namespace="testns",persistentvolumeclaim="testpvc"} 4.21789696e+09 kubelet_volume_stats_used_bytes{namespace="testns",persistentvolumeclaim="testpvc"} 4.21789696e+09
kubelet_volume_stats_health_status{namespace="testns",persistentvolumeclaim="testpvc"} 1 kubelet_volume_stats_health_status{namespace="testns",persistentvolumeclaim="testpvc",volume_health_status="abnormal"} 1
` `
metrics = []string{ metrics = []string{

View File

@ -177,7 +177,11 @@ func (s *volumeStatCalculator) calcAndStoreStats() {
// parsePodVolumeStats converts (internal) volume.Metrics to (external) stats.VolumeStats structures // parsePodVolumeStats converts (internal) volume.Metrics to (external) stats.VolumeStats structures
func (s *volumeStatCalculator) parsePodVolumeStats(podName string, pvcRef *stats.PVCReference, metric *volume.Metrics, volSpec v1.Volume) stats.VolumeStats { func (s *volumeStatCalculator) parsePodVolumeStats(podName string, pvcRef *stats.PVCReference, metric *volume.Metrics, volSpec v1.Volume) stats.VolumeStats {
var available, capacity, used, inodes, inodesFree, inodesUsed uint64 var (
available, capacity, used, inodes, inodesFree, inodesUsed uint64
volumeStats stats.VolumeStats
)
if metric.Available != nil { if metric.Available != nil {
available = uint64(metric.Available.Value()) available = uint64(metric.Available.Value())
} }
@ -197,13 +201,15 @@ func (s *volumeStatCalculator) parsePodVolumeStats(podName string, pvcRef *stats
inodesUsed = uint64(metric.InodesUsed.Value()) inodesUsed = uint64(metric.InodesUsed.Value())
} }
return stats.VolumeStats{ volumeStats.FsStats = stats.FsStats{Time: metric.Time, AvailableBytes: &available, CapacityBytes: &capacity,
Name: podName, UsedBytes: &used, Inodes: &inodes, InodesFree: &inodesFree, InodesUsed: &inodesUsed}
PVCRef: pvcRef, volumeStats.Name = podName
VolumeHealthStats: stats.VolumeHealthStats{ volumeStats.PVCRef = pvcRef
if metric.Abnormal != nil {
volumeStats.VolumeHealthStats = &stats.VolumeHealthStats{
Abnormal: *metric.Abnormal, Abnormal: *metric.Abnormal,
},
FsStats: stats.FsStats{Time: metric.Time, AvailableBytes: &available, CapacityBytes: &capacity,
UsedBytes: &used, Inodes: &inodes, InodesFree: &inodesFree, InodesUsed: &inodesUsed},
} }
} }
return volumeStats
}

View File

@ -130,6 +130,7 @@ func TestPVCRef(t *testing.T) {
assert.Contains(t, append(vs.EphemeralVolumes, vs.PersistentVolumes...), kubestats.VolumeStats{ assert.Contains(t, append(vs.EphemeralVolumes, vs.PersistentVolumes...), kubestats.VolumeStats{
Name: vol0, Name: vol0,
FsStats: expectedFSStats(), FsStats: expectedFSStats(),
VolumeHealthStats: expectedVolumeHealthStats(),
}) })
// Verify 'vol1' has a PVC reference // Verify 'vol1' has a PVC reference
assert.Contains(t, append(vs.EphemeralVolumes, vs.PersistentVolumes...), kubestats.VolumeStats{ assert.Contains(t, append(vs.EphemeralVolumes, vs.PersistentVolumes...), kubestats.VolumeStats{
@ -139,8 +140,9 @@ func TestPVCRef(t *testing.T) {
Namespace: namespace0, Namespace: namespace0,
}, },
FsStats: expectedFSStats(), FsStats: expectedFSStats(),
VolumeHealthStats: expectedVolumeHealthStats(),
}) })
// Verify 'vol2' has a PVC reference // // Verify 'vol2' has a PVC reference
assert.Contains(t, append(vs.EphemeralVolumes, vs.PersistentVolumes...), kubestats.VolumeStats{ assert.Contains(t, append(vs.EphemeralVolumes, vs.PersistentVolumes...), kubestats.VolumeStats{
Name: vol2, Name: vol2,
PVCRef: &kubestats.PVCReference{ PVCRef: &kubestats.PVCReference{
@ -148,6 +150,7 @@ func TestPVCRef(t *testing.T) {
Namespace: namespace0, Namespace: namespace0,
}, },
FsStats: expectedBlockStats(), FsStats: expectedBlockStats(),
VolumeHealthStats: expectedVolumeHealthStats(),
}) })
// Verify 'vol3' has a PVC reference // Verify 'vol3' has a PVC reference
assert.Contains(t, append(vs.EphemeralVolumes, vs.PersistentVolumes...), kubestats.VolumeStats{ assert.Contains(t, append(vs.EphemeralVolumes, vs.PersistentVolumes...), kubestats.VolumeStats{
@ -263,6 +266,13 @@ func expectedFSStats() kubestats.FsStats {
} }
} }
func expectedVolumeHealthStats() *kubestats.VolumeHealthStats {
metric := expectedMetrics()
return &kubestats.VolumeHealthStats{
Abnormal: *metric.Abnormal,
}
}
// Fake block-volume/metrics provider, block-devices have no inodes // Fake block-volume/metrics provider, block-devices have no inodes
var _ volume.BlockVolume = &fakeBlockVolume{} var _ volume.BlockVolume = &fakeBlockVolume{}

View File

@ -272,14 +272,14 @@ type VolumeStats struct {
// VolumeHealthStats contains data about volume health // VolumeHealthStats contains data about volume health
// +optional // +optional
VolumeHealthStats `json:"volumeHealthStats,omitempty"` VolumeHealthStats *VolumeHealthStats `json:"volumeHealthStats,omitempty"`
} }
// VolumeHealthStats contains data about volume health. // VolumeHealthStats contains data about volume health.
type VolumeHealthStats struct { type VolumeHealthStats struct {
// Normal volumes are available for use and operating optimally. // Normal volumes are available for use and operating optimally.
// An abnormal volume does not meet these criteria. // An abnormal volume does not meet these criteria.
Abnormal bool `json:"abnormal,omitempty"` Abnormal bool `json:"abnormal"`
} }
// PVCReference contains enough information to describe the referenced PVC. // PVCReference contains enough information to describe the referenced PVC.

View File

@ -230,9 +230,11 @@ var _ = SIGDescribe("Summary API [NodeConformance]", func() {
"test-empty-dir": gstruct.MatchAllFields(gstruct.Fields{ "test-empty-dir": gstruct.MatchAllFields(gstruct.Fields{
"Name": gomega.Equal("test-empty-dir"), "Name": gomega.Equal("test-empty-dir"),
"PVCRef": gomega.BeNil(), "PVCRef": gomega.BeNil(),
"VolumeHealthStats": gstruct.MatchAllFields(gstruct.Fields{ "VolumeHealthStats": gstruct.MatchAllFields(
"Abnormal": gomega.BeTrue(), gstruct.Fields{
}), "Abnormal": gomega.BeFalse(),
},
),
"FsStats": gstruct.MatchAllFields(gstruct.Fields{ "FsStats": gstruct.MatchAllFields(gstruct.Fields{
"Time": recent(maxStatsAge), "Time": recent(maxStatsAge),
"AvailableBytes": fsCapacityBounds, "AvailableBytes": fsCapacityBounds,