diff --git a/docs/pod-metrics.md b/docs/pod-metrics.md index f728a594bd..3037372efd 100644 --- a/docs/pod-metrics.md +++ b/docs/pod-metrics.md @@ -52,6 +52,7 @@ | 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 | - | | kube_pod_tolerations | Gauge | Information about the pod tolerations | | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid>
`key`=<toleration-key>
`operator`=<toleration-operator>
`value`=<toleration-value>
`effect`=<toleration-effect> `toleration_seconds`=<toleration-seconds> | EXPERIMENTAL | - | +| kube_pod_service_account | Gauge | The service account for a pod | | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid>
`service_account`=<service_account> | EXPERIMENTAL | - | ## Useful metrics queries diff --git a/internal/store/pod.go b/internal/store/pod.go index 59143a81b8..233fb2718b 100644 --- a/internal/store/pod.go +++ b/internal/store/pod.go @@ -92,6 +92,7 @@ func podMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat createPodStatusUnschedulableFamilyGenerator(), createPodTolerationsFamilyGenerator(), createPodNodeSelectorsFamilyGenerator(), + createPodServiceAccountFamilyGenerator(), } } @@ -1652,6 +1653,27 @@ func createPodNodeSelectorsFamilyGenerator() generator.FamilyGenerator { ) } +func createPodServiceAccountFamilyGenerator() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_pod_service_account", + "The service account for a pod.", + metric.Gauge, + basemetrics.ALPHA, + "", + wrapPodFunc(func(p *v1.Pod) *metric.Family { + m := metric.Metric{ + LabelKeys: []string{"service_account"}, + LabelValues: []string{p.Spec.ServiceAccountName}, + Value: 1, + } + + return &metric.Family{ + Metrics: []*metric.Metric{&m}, + } + }), + ) +} + func wrapPodFunc(f func(*v1.Pod) *metric.Family) func(interface{}) *metric.Family { return func(obj interface{}) *metric.Family { pod := obj.(*v1.Pod) diff --git a/internal/store/pod_test.go b/internal/store/pod_test.go index c66467d937..e1ae2d00bd 100644 --- a/internal/store/pod_test.go +++ b/internal/store/pod_test.go @@ -2066,6 +2066,26 @@ func TestPodStore(t *testing.T) { "kube_pod_tolerations", }, }, + { + Obj: &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + Namespace: "ns1", + UID: "uid1", + }, + Spec: v1.PodSpec{ + ServiceAccountName: "service-account-name", + }, + }, + Want: ` + # HELP kube_pod_service_account The service account for a pod. + # TYPE kube_pod_service_account gauge + kube_pod_service_account{namespace="ns1",pod="pod1",service_account="service-account-name",uid="uid1"} 1 + `, + MetricNames: []string{ + "kube_pod_service_account", + }, + }, } for i, c := range cases { @@ -2161,7 +2181,7 @@ func BenchmarkPodStore(b *testing.B) { }, } - expectedFamilies := 50 + expectedFamilies := 51 for n := 0; n < b.N; n++ { families := f(pod) if len(families) != expectedFamilies { diff --git a/pkg/app/server_test.go b/pkg/app/server_test.go index 3611b925ed..0d49ccd133 100644 --- a/pkg/app/server_test.go +++ b/pkg/app/server_test.go @@ -235,6 +235,7 @@ func TestFullScrapeCycle(t *testing.T) { # HELP kube_pod_overhead_cpu_cores The pod overhead in regards to cpu cores associated with running a pod. # HELP kube_pod_overhead_memory_bytes The pod overhead in regards to memory associated with running a pod. # HELP kube_pod_runtimeclass_name_info The runtimeclass associated with the pod. +# 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. @@ -284,6 +285,7 @@ func TestFullScrapeCycle(t *testing.T) { # TYPE kube_pod_overhead_cpu_cores gauge # TYPE kube_pod_overhead_memory_bytes gauge # TYPE kube_pod_runtimeclass_name_info gauge +# TYPE kube_pod_service_account gauge # TYPE kube_pod_owner gauge # TYPE kube_pod_restart_policy gauge # TYPE kube_pod_spec_volumes_persistentvolumeclaims_info gauge @@ -334,6 +336,7 @@ kube_pod_info{namespace="default",pod="pod0",uid="abc-0",host_ip="1.1.1.1",pod_i kube_pod_labels{namespace="default",pod="pod0",uid="abc-0"} 1 kube_pod_owner{namespace="default",pod="pod0",uid="abc-0",owner_kind="",owner_name="",owner_is_controller=""} 1 kube_pod_restart_policy{namespace="default",pod="pod0",uid="abc-0",type="Always"} 1 +kube_pod_service_account{namespace="default",pod="pod0",uid="abc-0",service_account=""} 1 kube_pod_status_phase{namespace="default",pod="pod0",uid="abc-0",phase="Failed"} 0 kube_pod_status_phase{namespace="default",pod="pod0",uid="abc-0",phase="Pending"} 0 kube_pod_status_phase{namespace="default",pod="pod0",uid="abc-0",phase="Running"} 1