Self-hosted service
kubernetes/kube-state-metrics avatar
kubernetes/kube-state-metrics

kube-state-metrics: cluster state as raw Prometheus metrics

Add-on agent to generate and expose cluster-level metrics.

6,211 stars2,193 forksGoApache-2.0

At a glance

What is it?
kube-state-metrics watches the Kubernetes API and republishes object state on /metrics without modification. This review covers what it exposes, how to deploy it, where it breaks down, and how it differs from metrics-server.
Who is it for?
Adopt kube-state-metrics if you need object-level state in Prometheus: replica counts, conditions, label-derived series, and the raw values kubectl rewrites. Do not adopt it as a replacement for metrics-server or cAdvisor; it does not measure CPU or memory consumption, and it does not retain history when an object is deleted.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 6 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What kube-state-metrics solves, and for whom

Prometheus scrapes endpoints. Kubernetes objects do not have endpoints. A Deployment has a desired replica count, a status condition, and a generation number, but none of that appears on a scrape target unless something translates it. kube-state-metrics is that translator. The README describes it as "a simple service that listens to the Kubernetes API server and generates metrics about the state of the objects," and it is explicit that the scope is object health rather than component health: deployments, nodes and pods, not the control plane processes themselves.

The audience is anyone running Prometheus against Kubernetes and needing to alert or graph on state. A replica count below the desired count, a node that has been NotReady, a PersistentVolumeClaim stuck in Pending: these are API object fields, and kube-state-metrics turns them into Prometheus series. If your only requirement is CPU and memory per pod, this project is the wrong layer, and the README says so directly in its comparison with metrics-server.

The design decision that matters most is stated plainly: metrics are generated "from Kubernetes API objects without modification." That has a visible consequence. The README warns that values may not match kubectl, because kubectl applies heuristics to produce readable output. kube-state-metrics publishes the raw field and leaves interpretation to the query layer. For alerting this is usually what you want, since you control the threshold. For a human reading a dashboard, it can be surprising.

How the agent turns API objects into /metrics output

The process is a client of the API server. The README points to client-go as the mechanism, and go.mod pins k8s.io/client-go v0.36.4 for the current tree. The agent watches resources, keeps an in-memory view of object state, and renders that view as Prometheus text on the HTTP endpoint /metrics, listening on port 8080 by default. The Dockerfile passes --port=8080 and --telemetry-port=8081 as entrypoint arguments and exposes both. The README notes the metrics are served as plaintext and can be opened in a browser.

Two consequences follow from the in-memory model. First, the endpoint reflects current state only. The README states this explicitly: when Kubernetes objects are deleted, they are no longer visible on /metrics. Prometheus handles the historical part, because a series that disappears from a scrape is marked stale. Second, the resource group version matters. Resources evolve from alpha to beta to GA, and the README says the project uses the oldest API available in the latest release. That is a stability choice, and it also means a very new Kubernetes version may need an unreleased kube-state-metrics build to cover the full range of supported resources.

Custom resource metrics exist but are on a path out. The README marks custom-resource-state as feature-frozen in favor of resource-state-metrics, and says it will be deprecated once that project is stable. If your plan depends on generating metrics from your own CRDs through kube-state-metrics, factor in that migration now rather than later.

Installing kube-state-metrics and reading the endpoint

The README points to a Helm chart and to Kubernetes deployment manifests, and the repository ships examples/standard/ alongside examples for sharding variants. The published container image is the shortest path if you already have a deployment workflow. The README lists the current image as registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.20.0, built for amd64, arm, arm64, ppc64le and s390x.

The entrypoint of that image is already defined in the Dockerfile, which is the only place the project documents the default flags:

dockerfile
ENTRYPOINT ["/kube-state-metrics", "--port=8080", "--telemetry-port=8081"]

EXPOSE 8080 8081

Against a real cluster the container needs credentials and API access; the repository's examples/standard/ directory holds the manifests the project maintains for that case, and the README also names a Helm chart as the supported install route. Once it is running, the first thing to check is that the endpoint answers. The README states that the metrics are exported on /metrics and that you can open it in a browser to see the raw output.

To confirm which build you are running, the CHANGELOG.md and the release tags are the reference points. The README does not document a version flag on the binary, so verify the image tag you deployed rather than querying the process.

Where kube-state-metrics stops being the right tool

The most common misreading is to treat it as a resource-usage exporter. It is not. CPU and memory consumption come from the kubelet and cAdvisor, surfaced through metrics-server for the resource-metrics API. kube-state-metrics reports that a Deployment wants five replicas and has three; it does not report how much CPU those three are burning. The README devotes a section to this distinction precisely because it is the first question new users ask.

The second limitation is cardinality. Every pod, every container, every label on every object becomes a series. The README's scaling section acknowledges this with resource recommendations, a latency discussion, and a note on costing, plus horizontal sharding, deployment sharding, daemonset sharding for pod metrics, and resource filtering as mitigations. If you run a cluster with a large number of short-lived pods, the pod metrics are where cost accumulates, and the daemonset sharding pattern exists for that case. The existence of five separate scaling strategies is itself the signal: this project does not scale by default, it scales by configuration.

Third, the unmodified-data promise cuts both ways. The README notes that conflict resolution applies in the *_labels family, where Kubernetes labels are exposed as Prometheus labels and name collisions have to be resolved somehow. If you rely on label-derived series for routing or alert grouping, read that section before you build on top of it. And alpha API resources are excluded from any stability guarantee, so a metric name sourced from an alpha API can change in any release.

kube-state-metrics vs metrics-server: different data, different pipeline

metrics-server implements the Kubernetes resource metrics API. It aggregates CPU and memory readings from kubelets and serves them through the API so that kubectl top and the Horizontal Pod Autoscaler can consume them. Its output is a small, current snapshot of consumption. It has no long-term storage, and Prometheus is not its consumer in the normal case.

kube-state-metrics is a Prometheus exporter. It has no API surface of its own beyond /metrics, it does not feed the HPA, and it does not measure consumption. What it does have is breadth: object state across the resource types the project supports, plus the self-metrics it publishes about its own operation. The two run side by side in a typical cluster, and the README's comparison section frames the split that way.

If you are choosing between them, the question is what you intend to query. "Is this Deployment short of replicas" is kube-state-metrics. "Is this pod near its memory limit" is metrics-server or a cAdvisor-based scrape. Choosing kube-state-metrics to answer the second question leads to a dashboard full of replica counts and no utilization data.

Maintenance, version compatibility and licence

The repository is not archived, and the last push was on 2026-09-17. Releases are frequent: v2.20.0 on 2026-08-18, v2.19.1 on 2026-06-12, v2.19.0 on 2026-05-21. The compatibility matrix pairs each kube-state-metrics release with a client-go version, from v2.16.0 with client-go v1.32 through v2.20.0 and main with v1.36. The upgrade cost is therefore not just the image tag. Moving kube-state-metrics forward can move the client-go version with it, and the README states that maintainers support only the latest release, with older versions left to interested community users. Plan upgrades against that matrix rather than against your cluster version alone.

The build chain is visible in the repository. The Dockerfile uses a multi-stage build from golang:1.26 with a distroless runtime, and runs as USER nobody. The Makefile pins supporting tool versions, including PROMETHEUS_VERSION = 3.9.1 and a .go-version file for the Go toolchain. None of that affects a Helm install, but it matters if you build the image yourself, since the build pulls the full source tree into the builder stage.

The licence is Apache-2.0, which is permissive and includes an explicit patent grant. That is a statement about the licence text, not legal advice; if you redistribute a modified build, read the NOTICE and attribution expectations in the repository rather than assuming the permissive grant covers every obligation.

Editorial conclusion

Adopt kube-state-metrics if you need object-level state in Prometheus: replica counts, conditions, label-derived series, and the raw values kubectl rewrites. Do not adopt it as a replacement for metrics-server or cAdvisor; it does not measure CPU or memory consumption, and it does not retain history when an object is deleted. Before rollout, check the compatibility matrix row for your Kubernetes version, confirm the image tag you pulled from registry.k8s.io, and open /metrics once to see how many series your cluster actually produces.

Frequently asked questions

What is the difference between kube-state-metrics and metrics-server in Kubernetes?

kube-state-metrics generates metrics about the state of Kubernetes API objects, such as deployments, nodes and pods, and serves them on /metrics for Prometheus. metrics-server serves the resource metrics API for CPU and memory consumption, which is what kubectl top and the Horizontal Pod Autoscaler consume. The README treats them as separate concerns and the two normally run side by side.

What is kube-state-metrics used for?

It listens to the Kubernetes API server and generates metrics about the state of objects inside the cluster, rather than the health of Kubernetes components themselves. The metrics are served as plaintext on /metrics on port 8080 and are designed for Prometheus or a compatible scraper.

How do I install kube-state-metrics on Kubernetes?

The README points to a Helm chart and to Kubernetes deployment manifests, and the repository ships an examples/standard/ directory. The published image is registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.20.0, built for amd64, arm, arm64, ppc64le and s390x. The README does not give a single install command beyond those routes.

How do I check the kube-state-metrics version?

The README does not document a version flag on the binary, so the check is against what you deployed: the image tag, the release tags, and CHANGELOG.md. The compatibility matrix in the README pairs each release with the client-go version it uses, from v2.16.0 with client-go v1.32 through v2.20.0 with v1.36.

What is kube-state-metrics in Prometheus?

It is a Prometheus exporter. The metrics are exported on the HTTP endpoint /metrics on the listening port, which defaults to 8080, and are served as plaintext for Prometheus itself or a scraper compatible with a Prometheus client endpoint. The project also publishes self-metrics about its own operation.

How do I deploy kube-state-metrics?

The README lists a Helm chart and Kubernetes deployment manifests as the supported routes, and the repository contains examples/standard/ plus examples for the sharding variants under examples/autosharding/, examples/daemonsetsharding/ and examples/deploymentsharding/. The Dockerfile shows the container entrypoint starts the binary with --port=8080 and --telemetry-port=8081.

Official sources

  1. kubernetes/kube-state-metrics on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/kubernetes-kube-state-metrics.svg)](https://hysenlabs.com/projects/kubernetes-kube-state-metrics)