mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-30 06:54:01 +00:00
add volumeHealth label to metrics
This commit is contained in:
parent
bab1755274
commit
ed7fd0ced5
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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{
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
@ -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{}
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user