diff --git a/docs/metrics/workload/pod-metrics.md b/docs/metrics/workload/pod-metrics.md
index 88c68eca2d..f2cb08ffb5 100644
--- a/docs/metrics/workload/pod-metrics.md
+++ b/docs/metrics/workload/pod-metrics.md
@@ -48,8 +48,8 @@
| kube_pod_init_container_status_restarts_total | Counter | The number of restarts for the init container | integer | `container`=<container-name>
`namespace`=<pod-namespace>
`pod`=<pod-name>
`uid`=<pod-uid> | STABLE | - |
| kube_pod_init_container_resource_limits | Gauge | The number of CPU cores requested limit by an init container | `cpu`=<core>
`memory`=<bytes> | `resource`=<resource-name>
`unit`=<resource-unit>
`container`=<container-name>
`pod`=<pod-name>
`namespace`=<pod-namespace>
`node`=< node-name>
`uid`=<pod-uid> | EXPERIMENTAL | - |
| kube_pod_init_container_resource_requests | Gauge | The number of CPU cores requested by an init container | `cpu`=<core>
`memory`=<bytes> | `resource`=<resource-name>
`unit`=<resource-unit>
`container`=<container-name>
`pod`=<pod-name>
`namespace`=<pod-namespace>
`node`=< node-name>
`uid`=<pod-uid> | EXPERIMENTAL | - |
-| kube_pod_spec_volumes_persistentvolumeclaims_info | Gauge | Information about persistentvolumeclaim volumes in a pod | | `pod`=<pod-name>
`namespace`=<pod-namespace>
`volume`=<volume-name>
`persistentvolumeclaim`=<persistentvolumeclaim-claimname>
`uid`=<pod-uid> | STABLE | - |
-| kube_pod_spec_volumes_persistentvolumeclaims_readonly | Gauge | Describes whether a persistentvolumeclaim is mounted read only | bool | `pod`=<pod-name>
`namespace`=<pod-namespace>
`volume`=<volume-name>
`persistentvolumeclaim`=<persistentvolumeclaim-claimname>
`uid`=<pod-uid> | STABLE | - |
+| kube_pod_spec_volumes_persistentvolumeclaims_info | Gauge | Information about persistentvolumeclaim and ephemeral volumes in a pod | | `pod`=<pod-name>
`namespace`=<pod-namespace>
`volume`=<volume-name>
`persistentvolumeclaim`=<persistentvolumeclaim-claimname>
`uid`=<pod-uid> | STABLE | - |
+| kube_pod_spec_volumes_persistentvolumeclaims_readonly | Gauge | Describes whether a persistentvolumeclaim is mounted read only. Ephemeral volumes always report 0 since the ephemeral volume source does not support a read-only flag | bool | `pod`=<pod-name>
`namespace`=<pod-namespace>
`volume`=<volume-name>
`persistentvolumeclaim`=<persistentvolumeclaim-claimname>
`uid`=<pod-uid> | STABLE | - |
| kube_pod_status_reason | Gauge | The pod status reasons | | `pod`=<pod-name>
`namespace`=<pod-namespace>
`reason`=<Evicted\|NodeAffinity\|NodeLost\|PreemptionByScheduler\|SchedulingGated\|Shutdown\|TerminationByKubelet\|UnexpectedAdmissionError>
`uid`=<pod-uid> | EXPERIMENTAL | - |
| kube_pod_status_scheduled_time | Gauge | Unix timestamp when pod moved into scheduled status | seconds | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | STABLE | - |
| kube_pod_status_unschedulable | Gauge | Describes the unschedulable status for the pod | | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | STABLE | - |
diff --git a/go.mod b/go.mod
index 519c32c005..bf822d19d7 100644
--- a/go.mod
+++ b/go.mod
@@ -23,6 +23,7 @@ require (
k8s.io/apimachinery v0.35.4
k8s.io/client-go v0.35.4
k8s.io/component-base v0.35.4
+ k8s.io/component-helpers v0.35.4
k8s.io/klog/v2 v2.140.0
k8s.io/sample-controller v0.35.4
k8s.io/utils v0.0.0-20260108192941-914a6e750570
diff --git a/go.sum b/go.sum
index f48a777447..618153b956 100644
--- a/go.sum
+++ b/go.sum
@@ -908,6 +908,8 @@ k8s.io/client-go v0.35.4 h1:DN6fyaGuzK64UvnKO5fOA6ymSjvfGAnCAHAR0C66kD8=
k8s.io/client-go v0.35.4/go.mod h1:2Pg9WpsS4NeOpoYTfHHfMxBG8zFMSAUi4O/qoiJC3nY=
k8s.io/component-base v0.35.4 h1:6n1tNJ87johN0Hif0Fs8K2GMthsaUwMqCebUDLYyv7U=
k8s.io/component-base v0.35.4/go.mod h1:qaDJgz5c1KYKla9occFmlJEfPpkuA55s90G509R+PeY=
+k8s.io/component-helpers v0.35.4 h1:WJM/+fAeeJTAqxPDxgH0aB0q7t8DP+AbV5WkRkOoxYA=
+k8s.io/component-helpers v0.35.4/go.mod h1:mE7X9mnMQEX6IbZejdMlWvCx3EPVt1/9PhH/FW0XHDI=
k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc=
k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0=
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE=
diff --git a/internal/store/pod.go b/internal/store/pod.go
index 952147c706..c603d652ec 100644
--- a/internal/store/pod.go
+++ b/internal/store/pod.go
@@ -21,6 +21,7 @@ import (
"strconv"
basemetrics "k8s.io/component-base/metrics"
+ "k8s.io/component-helpers/storage/ephemeral"
"k8s.io/utils/net"
"k8s.io/kube-state-metrics/v2/pkg/constant"
@@ -1259,7 +1260,7 @@ func createPodRuntimeClassNameInfoFamilyGenerator() generator.FamilyGenerator {
func createPodSpecVolumesPersistentVolumeClaimsInfoFamilyGenerator() generator.FamilyGenerator {
return *generator.NewFamilyGeneratorWithStability(
"kube_pod_spec_volumes_persistentvolumeclaims_info",
- "Information about persistentvolumeclaim volumes in a pod.",
+ "Information about persistentvolumeclaim and ephemeral volumes in a pod.",
metric.Gauge,
basemetrics.STABLE,
"",
@@ -1273,6 +1274,12 @@ func createPodSpecVolumesPersistentVolumeClaimsInfoFamilyGenerator() generator.F
LabelValues: []string{v.Name, v.PersistentVolumeClaim.ClaimName},
Value: 1,
})
+ } else if v.Ephemeral != nil {
+ ms = append(ms, &metric.Metric{
+ LabelKeys: []string{"volume", "persistentvolumeclaim"},
+ LabelValues: []string{v.Name, ephemeral.VolumeClaimName(p, &v)},
+ Value: 1,
+ })
}
}
@@ -1286,7 +1293,7 @@ func createPodSpecVolumesPersistentVolumeClaimsInfoFamilyGenerator() generator.F
func createPodSpecVolumesPersistentVolumeClaimsReadonlyFamilyGenerator() generator.FamilyGenerator {
return *generator.NewFamilyGeneratorWithStability(
"kube_pod_spec_volumes_persistentvolumeclaims_readonly",
- "Describes whether a persistentvolumeclaim is mounted read only.",
+ "Describes whether a persistentvolumeclaim is mounted read only. Ephemeral volumes always report 0 since the ephemeral volume source does not support a read-only flag.",
metric.Gauge,
basemetrics.STABLE,
"",
@@ -1300,6 +1307,12 @@ func createPodSpecVolumesPersistentVolumeClaimsReadonlyFamilyGenerator() generat
LabelValues: []string{v.Name, v.PersistentVolumeClaim.ClaimName},
Value: boolFloat64(v.PersistentVolumeClaim.ReadOnly),
})
+ } else if v.Ephemeral != nil {
+ ms = append(ms, &metric.Metric{
+ LabelKeys: []string{"volume", "persistentvolumeclaim"},
+ LabelValues: []string{v.Name, ephemeral.VolumeClaimName(p, &v)},
+ Value: 0,
+ })
}
}
diff --git a/internal/store/pod_test.go b/internal/store/pod_test.go
index 6c390fdb35..0d8d29fc4e 100644
--- a/internal/store/pod_test.go
+++ b/internal/store/pod_test.go
@@ -2031,6 +2031,10 @@ func TestPodStore(t *testing.T) {
},
},
},
+ {
+ Name: "my-ephemeral-vol",
+ VolumeSource: v1.VolumeSource{Ephemeral: &v1.EphemeralVolumeSource{}},
+ },
{
Name: "not-pvc-vol",
VolumeSource: v1.VolumeSource{
@@ -2043,14 +2047,16 @@ func TestPodStore(t *testing.T) {
},
},
Want: `
- # HELP kube_pod_spec_volumes_persistentvolumeclaims_info [STABLE] Information about persistentvolumeclaim volumes in a pod.
- # HELP kube_pod_spec_volumes_persistentvolumeclaims_readonly [STABLE] Describes whether a persistentvolumeclaim is mounted read only.
+ # HELP kube_pod_spec_volumes_persistentvolumeclaims_info [STABLE] Information about persistentvolumeclaim and ephemeral volumes in a pod.
+ # HELP kube_pod_spec_volumes_persistentvolumeclaims_readonly [STABLE] Describes whether a persistentvolumeclaim is mounted read only. Ephemeral volumes always report 0 since the ephemeral volume source does not support a read-only flag.
# TYPE kube_pod_spec_volumes_persistentvolumeclaims_info gauge
# TYPE kube_pod_spec_volumes_persistentvolumeclaims_readonly gauge
kube_pod_spec_volumes_persistentvolumeclaims_info{namespace="ns1",persistentvolumeclaim="claim1",pod="pod1",volume="myvol",uid="uid1"} 1
kube_pod_spec_volumes_persistentvolumeclaims_info{namespace="ns1",persistentvolumeclaim="claim2",pod="pod1",volume="my-readonly-vol",uid="uid1"} 1
+ kube_pod_spec_volumes_persistentvolumeclaims_info{namespace="ns1",persistentvolumeclaim="pod1-my-ephemeral-vol",pod="pod1",volume="my-ephemeral-vol",uid="uid1"} 1
kube_pod_spec_volumes_persistentvolumeclaims_readonly{namespace="ns1",persistentvolumeclaim="claim1",pod="pod1",volume="myvol",uid="uid1"} 0
kube_pod_spec_volumes_persistentvolumeclaims_readonly{namespace="ns1",persistentvolumeclaim="claim2",pod="pod1",volume="my-readonly-vol",uid="uid1"} 1
+ kube_pod_spec_volumes_persistentvolumeclaims_readonly{namespace="ns1",persistentvolumeclaim="pod1-my-ephemeral-vol",pod="pod1",volume="my-ephemeral-vol",uid="uid1"} 0
`,
MetricNames: []string{
diff --git a/pkg/app/server_test.go b/pkg/app/server_test.go
index 29becc5066..806f0e989c 100644
--- a/pkg/app/server_test.go
+++ b/pkg/app/server_test.go
@@ -249,8 +249,8 @@ func TestFullScrapeCycle(t *testing.T) {
# HELP kube_pod_service_account The service account for a pod.
# HELP kube_pod_owner [STABLE] Information about the Pod's owner.
# HELP kube_pod_restart_policy [STABLE] Describes the restart policy in use by this pod.
-# HELP kube_pod_spec_volumes_persistentvolumeclaims_info [STABLE] Information about persistentvolumeclaim volumes in a pod.
-# HELP kube_pod_spec_volumes_persistentvolumeclaims_readonly [STABLE] Describes whether a persistentvolumeclaim is mounted read only.
+# HELP kube_pod_spec_volumes_persistentvolumeclaims_info [STABLE] Information about persistentvolumeclaim and ephemeral volumes in a pod.
+# HELP kube_pod_spec_volumes_persistentvolumeclaims_readonly [STABLE] Describes whether a persistentvolumeclaim is mounted read only. Ephemeral volumes always report 0 since the ephemeral volume source does not support a read-only flag.
# HELP kube_pod_start_time [STABLE] Start time in unix timestamp for a pod.
# HELP kube_pod_status_container_ready_time Readiness achieved time in unix timestamp for a pod containers.
# HELP kube_pod_status_initialized_time Initialized time in unix timestamp for a pod.