Skip to content

Commit 636d302

Browse files
committed
feat(pvc): support kube_persistentvolumeclaim_deletion_timestamp
Signed-off-by: Maxime Leroy <[email protected]>
1 parent 42e7742 commit 636d302

File tree

3 files changed

+85
-1
lines changed

3 files changed

+85
-1
lines changed

docs/persistentvolumeclaim-metrics.md

+29-1
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,36 @@
99
| kube_persistentvolumeclaim_resource_requests_storage_bytes | Gauge | | | `namespace`=&lt;persistentvolumeclaim-namespace&gt; <br> `persistentvolumeclaim`=&lt;persistentvolumeclaim-name&gt; | STABLE |
1010
| kube_persistentvolumeclaim_status_condition | Gauge | | | `namespace` =&lt;persistentvolumeclaim-namespace&gt; <br> `persistentvolumeclaim`=&lt;persistentvolumeclaim-name&gt; <br> `type`=&lt;persistentvolumeclaim-condition-type&gt; <br> `status`=&lt;true\false\unknown&gt; | EXPERIMENTAL |
1111
| kube_persistentvolumeclaim_status_phase | Gauge | | | `namespace`=&lt;persistentvolumeclaim-namespace&gt; <br> `persistentvolumeclaim`=&lt;persistentvolumeclaim-name&gt; <br> `phase`=&lt;Pending\Bound\Lost&gt; | STABLE |
12-
| kube_persistentvolumeclaim_created | Gauge | Unix Creation Timestamp | seconds | `namespace`=&lt;persistentvolumeclaim-namespace&gt; <br> `persistentvolumeclaim`=&lt;persistentvolumeclaim-name&gt; | EXPERIMENTAL |
12+
| kube_persistentvolumeclaim_created | Gauge | Unix creation timestamp | seconds | `namespace`=&lt;persistentvolumeclaim-namespace&gt; <br> `persistentvolumeclaim`=&lt;persistentvolumeclaim-name&gt; | EXPERIMENTAL |
13+
| kube_persistentvolumeclaim_deletion_timestamp | Gauge | Unix deletion timestamp | seconds | `namespace`=&lt;persistentvolumeclaim-namespace&gt; <br> `persistentvolumeclaim`=&lt;persistentvolumeclaim-name&gt; | EXPERIMENTAL |
1314

1415
Note:
1516

1617
- An empty string will be used if PVC has no storage class.
18+
19+
## Useful metrics queries
20+
21+
### How to retrieve non-standard PVC state
22+
23+
It is not straightforward to get the PVC states for certain cases like "Terminating" since it is not stored behind a field in the `PersistentVolumeClaim.Status`.
24+
25+
So to mimic the [logic](https://github.com/kubernetes/kubernetes/blob/v1.17.3/pkg/printers/internalversion/printers.go#L1402) used by the `kubectl` command line, you will need to compose multiple metrics.
26+
27+
For example:
28+
29+
* For PVCs in `Terminating` state: `count(kube_persistentvolumeclaim_deletion_timestamp) by (namespace, persistentvolumeclaim) * count(kube_persistentvolumeclaim_status_phase{phase="Bound"} == 1) by (namespace, persistentvolumeclaim)`
30+
31+
Here is an example of a Prometheus rule that can be used to alert on a PVC that has been in the `Terminating` state for more than `5m`.
32+
33+
```yaml
34+
groups:
35+
- name: PVC state
36+
rules:
37+
- alert: PVCBlockedInTerminatingState
38+
expr: count(kube_persistentvolumeclaim_deletion_timestamp) by (namespace, persistentvolumeclaim) * count(kube_persistentvolumeclaim_status_phase{phase="Bound"} == 1) by (namespace, persistentvolumeclaim) > 0
39+
for: 5m
40+
labels:
41+
severity: page
42+
annotations:
43+
summary: PVC {{$labels.namespace}}/{{$labels.persistentvolumeclaim}} blocked in Terminating state.
44+
```

internal/store/persistentvolumeclaim.go

+22
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,28 @@ func persistentVolumeClaimMetricFamilies(allowAnnotationsList, allowLabelsList [
226226
})
227227
}
228228

229+
return &metric.Family{
230+
Metrics: ms,
231+
}
232+
}),
233+
),
234+
*generator.NewFamilyGeneratorWithStability(
235+
"kube_persistentvolumeclaim_deletion_timestamp",
236+
"Unix deletion timestamp",
237+
metric.Gauge,
238+
basemetrics.ALPHA,
239+
"",
240+
wrapPersistentVolumeClaimFunc(func(p *v1.PersistentVolumeClaim) *metric.Family {
241+
ms := []*metric.Metric{}
242+
243+
if p.DeletionTimestamp != nil && !p.DeletionTimestamp.IsZero() {
244+
ms = append(ms, &metric.Metric{
245+
LabelKeys: []string{},
246+
LabelValues: []string{},
247+
Value: float64(p.DeletionTimestamp.Unix()),
248+
})
249+
}
250+
229251
return &metric.Family{
230252
Metrics: ms,
231253
}

internal/store/persistentvolumeclaim_test.go

+34
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,40 @@ func TestPersistentVolumeClaimStore(t *testing.T) {
276276
`,
277277
MetricNames: []string{"kube_persistentvolumeclaim_created", "kube_persistentvolumeclaim_info", "kube_persistentvolumeclaim_status_phase", "kube_persistentvolumeclaim_resource_requests_storage_bytes", "kube_persistentvolumeclaim_annotations", "kube_persistentvolumeclaim_labels", "kube_persistentvolumeclaim_access_mode", "kube_persistentvolumeclaim_status_condition"},
278278
},
279+
{
280+
Obj: &v1.PersistentVolumeClaim{
281+
ObjectMeta: metav1.ObjectMeta{
282+
Name: "terminating-data",
283+
CreationTimestamp: metav1.Time{Time: time.Unix(1500000000, 0)},
284+
DeletionTimestamp: &metav1.Time{Time: time.Unix(1800000000, 0)},
285+
},
286+
Spec: v1.PersistentVolumeClaimSpec{
287+
AccessModes: []v1.PersistentVolumeAccessMode{
288+
v1.ReadWriteOnce,
289+
},
290+
Resources: v1.ResourceRequirements{
291+
Requests: v1.ResourceList{
292+
v1.ResourceStorage: resource.MustParse("1Gi"),
293+
},
294+
},
295+
VolumeName: "pvc-postgresql-data",
296+
},
297+
Status: v1.PersistentVolumeClaimStatus{
298+
Phase: v1.ClaimBound,
299+
},
300+
},
301+
Want: `
302+
# HELP kube_persistentvolumeclaim_deletion_timestamp Unix deletion timestamp
303+
# HELP kube_persistentvolumeclaim_status_phase [STABLE] The phase the persistent volume claim is currently in.
304+
# TYPE kube_persistentvolumeclaim_deletion_timestamp gauge
305+
# TYPE kube_persistentvolumeclaim_status_phase gauge
306+
kube_persistentvolumeclaim_deletion_timestamp{namespace="",persistentvolumeclaim="terminating-data"} 1.8e+09
307+
kube_persistentvolumeclaim_status_phase{namespace="",persistentvolumeclaim="terminating-data",phase="Bound"} 1
308+
kube_persistentvolumeclaim_status_phase{namespace="",persistentvolumeclaim="terminating-data",phase="Lost"} 0
309+
kube_persistentvolumeclaim_status_phase{namespace="",persistentvolumeclaim="terminating-data",phase="Pending"} 0
310+
`,
311+
MetricNames: []string{"kube_persistentvolumeclaim_deletion_timestamp", "kube_persistentvolumeclaim_status_phase"},
312+
},
279313
}
280314
for i, c := range cases {
281315
c.Func = generator.ComposeMetricGenFuncs(persistentVolumeClaimMetricFamilies(c.AllowAnnotationsList, c.AllowLabelsList))

0 commit comments

Comments
 (0)