The changes introduce a new metric generator `kube_pod_status_unscheduled_time` to record the Unix timestamp when pods transition to unscheduled status. This enhances monitoring capabilities for scheduling issues by capturing exact transition times during `PodScheduled` condition changes.
This adds an Authentication/Authorization filter through Kubernetes'
TokenReview / SubjectAccessReview resources.
The client config for kube-state-metrics needs a clusterrole for
* apiGroups: authentication.k8s.io, resources: tokenreviews, verbs: create
* apiGroups: authorization.k8s.io, resources: subjectaccessreviews, verbs: create
The Prometheus client needs a clusterrole for
* nonResourceURLs: "/metrics", verbs: get
This change allows user-controlled limits on how many objects KSM will
list from the API. This is helpful to prevent resource exhaustion on
KSM, in case the API creates too many resources.
The object limit it set globally and applied per resource watched.
In order to monitor for PVs with different reclaim policies add a
`reclaim_policy` label to the `kube_persistentvolume_info` metric.
Signed-off-by: SuperQ <superq@gmail.com>
by addressing the warning below.
```
make container
...
2 warnings found (use --debug to expand):
- FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 3)
```
3rd-party dependencies cannot be installed pre-build since Makefile
variables are initialized earlier than that.
Signed-off-by: Pranshu Srivastava <rexagod@gmail.com>
Without this change Info logs appear in the benchmark
ok k8s.io/kube-state-metrics/v2/pkg/allowdenylist 0.005s
I1106 08:50:22.006480 144965 builder.go:280] "Active resources" activeStoreNames="certificatesigningrequests,configmaps,cronjobs,daemonsets,deployments,endpoints,horizontalpodautoscalers,ingresses,jobs,leases,limitranges,mutatingwebhookconfigurations,namespaces,networkpolicies,nodes,persistentvolumeclaims,persistentvolumes,poddisruptionbudgets,pods,replicasets,replicationcontrollers,resourcequotas,secrets,services,statefulsets,storageclasses,validatingwebhookconfigurations,volumeattachments"
goos: linux
goarch: amd64
pkg: k8s.io/kube-state-metrics/v2/pkg/app
cpu: Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz
BenchmarkKubeStateMetrics/GenerateMetrics-8 1 1001291639 ns/op 67578008 B/op 582810 allocs/op
In busy/large clusters, will prevent timeouts from long living
locks/concurrency issues, as the writing to the map takes overly long,
blocking the metrics-reading thread and as the lock doesn't get released
in a timely manner, timing out the request.
Inpired by previous PR at https://github.com/kubernetes/kube-state-metrics/pull/1028
pkg/metric_generator/generator.go:32:22: 16 bytes saved: struct with 96 pointer bytes could be 80
pkg/metrics_store/metrics_store.go:31:19: 40 bytes saved: struct with 64 pointer bytes could be 24
pkg/options/options.go:42:14: 24 bytes saved: struct of size 384 could be 360
internal/store/builder.go:67:14: 8 bytes saved: struct of size 200 could be 192
internal/store/pod.go:1351:16: 8 bytes saved: struct with 16 pointer bytes could be 8
internal/store/pod.go:1477:20: 8 bytes saved: struct with 16 pointer bytes could be 8
internal/store/testutils.go:32:30: 16 bytes saved: struct with 136 pointer bytes could be 120
pkg/metricshandler/metrics_handler.go:46:21: 8 bytes saved: struct of size 104 could be 96
internal/discovery/types.go:39:19: 32 bytes saved: struct with 88 pointer bytes could be 56
pkg/customresourcestate/config.go:51:15: 16 bytes saved: struct with 112 pointer bytes could be 96
pkg/customresourcestate/config.go:134:16: 8 bytes saved: struct with 88 pointer bytes could be 80
pkg/customresourcestate/config.go:150:13: 8 bytes saved: struct with 40 pointer bytes could be 32
pkg/customresourcestate/config_metrics_types.go:29:18: 8 bytes saved: struct with 64 pointer bytes could be 56
pkg/customresourcestate/config_metrics_types.go:42:17: 8 bytes saved: struct with 40 pointer bytes could be 32
pkg/customresourcestate/registry_factory.go:125:21: 8 bytes saved: struct with 40 pointer bytes could be 32
pkg/customresourcestate/registry_factory.go:212:20: 16 bytes saved: struct with 88 pointer bytes could be 72
pkg/customresourcestate/registry_factory.go:377:23: 8 bytes saved: struct with 104 pointer bytes could be 96
pkg/customresourcestate/registry_factory.go:497:21: 8 bytes saved: struct with 64 pointer bytes could be 56
pkg/customresourcestate/registry_factory.go:549:13: 8 bytes saved: struct with 24 pointer bytes could be 16
Add automatic detection of container and system memory limits to control
the Go `GOMEMLIMIT` garbage collector feature. This helps reduced OOMs
by triggering GC when the process approaches system limits.
Signed-off-by: SuperQ <superq@gmail.com>
Discourage the usage of `/metrics` for any probe, and use `/readyz` in
place of the earlier telemetry metrics endpoint to secure the exposition
data.
Signed-off-by: Pranshu Srivastava <rexagod@gmail.com>
Add a `livez` endpoint to identify network outages. This helps in
restarting the binary if such as case is observed.
Signed-off-by: Pranshu Srivastava <rexagod@gmail.com>
Signed-off-by: Pranshu Srivastava <rexagod@gmail.com>
There are a few documented scenarios where `kube-state-metrics` will
lock up(#995, #1028). I believe a much simpler solution to ensure
`kube-state-metrics` doesn't lock up and require a restart to server
`/metrics` requests is to add default read and write timeouts and to
allow them to be configurable. At Grafana, we've experienced a few
scenarios where `kube-state-metrics` running in larger clusters falls
behind and starts getting scraped multiple times. When this occurs,
`kube-state-metrics` becomes completely unresponsive and requires a
reboot. This is somewhat easily reproduceable(I'll provide a script in
an issue) and causes other critical workloads(KEDA, VPA) to fail in
weird ways.
Adds two flags:
- `server-read-timeout`
- `server-write-timeout`
Updates the metrics http server to set the `ReadTimeout` and
`WriteTimeout` to the configured values.
Add the kube_secret_owner metric for Secrets.
This metric already exists for several other Kubernetes primitives (Jobs, Pods, etc).
Cluster operators will often use external secret stores with a controller
to reconcile those secrets into Kubernetes Secrets.
Cluster operators may wish to discourage manually managed secrets.
Having the secret owner data in kube-state-metrics allows graphing and alerting on unmanaged secrets.
Fallback to `gauge` metric type when the negotiated content-type is
`protofmt`-based, since Prometheus' protobuf machinery does not
recognize all OpenMetrics types (`info` and `statesets` in this
context).
Signed-off-by: Pranshu Srivastava <rexagod@gmail.com>
Allow prefixing * paths, for instance, foo_*: [foo, bar, baz], will
result in foo_baz being the key for all object resolutions under baz.
Signed-off-by: Pranshu Srivastava <rexagod@gmail.com>
Currently all matching support is limited to map-list representations;
this adds support for a more general "key:value" based matching
expression for any `interface{}` field (non-map-list-like).
In order to better identify, prioritize, and debug webhook latency
issues it is important to have a metric that would point to the resource
it is responsible for. However, it is not possible to have that
dimension in the metrics exposed by Kubernetes because of the unbound
cardinality that such a label would have.
The name of the webhook could be an alternative since it usually
contains some information about the resource that the webhook targets,
however this is not very practical to use in multi-tenants
environments.
A solution for these kind of platform is to tie a specific webhook to a
namespace in order to be able to know which tenant manages it and take
actions depending on that. This is achieveable by leveraging the client
config information of webhooks configured via WebhookConfiguration
resources since Services are namespaced objects.
With these new metrics, users will be able to split the alerting
severity of webhook latency / rejection rate per namespace on top of
being able to do it based on the webhook name. This is key in
environment where administrators don't have control over the webhooks
installed by the various tenants.
Signed-off-by: Damien Grisonnet <dgrisonn@redhat.com>
Adds a paragraph on RBAC and removes the outdated information on setting
the customresource in the --resources flag.
Signed-off-by: Manuel Rüger <manuel@rueg.eu>
This patch adds the namespace label to the `kube_lease_renew_time` and
updates unit tests to validate the changes.
Fixes github.com/kubernetes/kube-state-metrics
Add support for variable VKs in CRS config, while maintaining a cache
of discovered GVKs in the cluster, and updating it every 30s.
Signed-off-by: Pranshu Srivastava <rexagod@gmail.com>
The `map[string]interface{}` resolution searched for values within various nested fields, but not the relative path itself.
Ref.: ca1da6b22e/pkg/customresourcestate/registry_factory.go (L603)
Signed-off-by: Pranshu Srivastava <rexagod@gmail.com>
Handle unit length `valueFrom` values and skip strings where we expect
them to be type-cast-able to `float64`, instead of erroring, since that
is the expected behavior, and what's being done for other types.
This change adds hot reloading support for the customresourcestate
config file.
It also resolves a bug in which the customresourcestate config file was
included in the ksm config file, in which it did not get detected.
It also resolves a bug in which customresourcestatemetrics were not
added when set resources were non-default resources.
Fixes: https://github.com/kubernetes/kube-state-metrics/issues/1892
This will prefix the auto-generated GVK labels for CustomResources with
customresource_ to make it a bit more clear that these labels got generated.
Signed-off-by: Mario Constanti <mario@constanti.de>
Simplify the implementation of the MetricsWriter to avoid code
duplication between single and multi stores scenarios.
Signed-off-by: Damien Grisonnet <dgrisonn@redhat.com>
Returning empty string instead of "<none>" value for "owner_kind", "owner_name" and "owner_is_controller" dimensions when no metadata.ownerReferences exists in Kubernetes resoures.
This uses code pieces from prometheus/alertmanager in https://github.com/prometheus/alertmanager/blob/main/config/coordinator.go#LL56C26-L56C26
licensed under Apache-2.0.
kube_state_metrics_config_hash{type="config", filename="config.yml"} 4.0061079457904e+13
kube_state_metrics_config_last_reload_success_timestamp_seconds{type="config", filename="config.yml"} 1.6697483049487052e+09
kube_state_metrics_config_last_reload_successful{type="config",
filename="config.yml"} 1
Signed-off-by: Manuel Rüger <manuel@rueg.eu>
Implements https://pkg.go.dev/k8s.io/api/discovery/v1#EndpointSlice
This resourcetype is disabled by default as they are very verbose and
have a high cardinality.
Metrics from endpointslices can be used to identify if specific pods are
part of an endpoint and thus discoverable through a service.
Signed-off-by: Manuel Rüger <manuel@rueg.eu>
Issue: https://github.com/kubernetes/kube-state-metrics/issues/1711
Problem: kube-state-metrics supports up to (latest k8s release - 3) k8s
version. Since v1.25 has been release we can update it to start using
autoscaler/v2.
Solution: update packages to start using autoscaler/v2
Signed-off-by: JoaoBraveCoding <jmarcal@redhat.com>
s/pflags/cobra/g:
* Use spf13/cobra to handle all flags and sub-commands.
* Remove all spf13/pflag usage, and fallback to the in-build flag
package if, and when needed.
* Add completion support.
Signed-off-by: Pranshu Srivastava <rexagod@gmail.com>
Support filtering label allowlist by "*", which will expand to the
enabled resources, while infering their values based on its value(s).
Signed-off-by: Pranshu Srivastava <rexagod@gmail.com>
... to only monitor all known custom-resource configurations instead of
listing each of them explicitly
Signed-off-by: Mario Constanti <mario@constanti.de>
As of this moment, there are 2 vulns in the codebase.
* GO-2022-1095: os/exec@go1.19.2
* GO-2022-1095: syscall@go1.19.2
This commit aims to fix that.
Signed-off-by: Pranshu Srivastava <rexagod@gmail.com>
Allow `labelFromKey` field for the following types:
* Gauge: Done.
* Info: Done.
* StateSet: N/A (redundant use case, see doc changes for more info).
Signed-off-by: Pranshu Srivastava <rexagod@gmail.com>
Recommend metrics exposed by the kube-scheduler, in case of the ones below:
* `kube_pod_container_resource_limits`
* `kube_pod_container_resource_requests`
Signed-off-by: Pranshu Srivastava <rexagod@gmail.com>
Remediate:
G104: Errors unhandled.
G109: Potential Integer overflow made by strconv.Atoi result conversion to int16/32
G112: Potential Slowloris Attack because ReadHeaderTimeout is not configured in the http.Server
G304: Potential file inclusion via variable
G601: Implicit memory aliasing in for loop.
Signed-off-by: Manuel Rüger <manuel@rueg.eu>
Represent GVK information as labels in the metrics, instead of appending
them to the metric name itself. This would allow users to aggregate
varying GVKs of a CR under the same metric, making operations much more
easier.
Handle singular labels in allowlist failing when such a label is
supplied, in order to keep the behaviour in sync with --resources.
Signed-off-by: Pranshu Srivastava <rexagod@gmail.com>
* graduate kube_endpoint_ports and kube_endpoint_address to STABLE
* graduate kube_endpoint_address_not_ready and
kube_endpoint_address_available to DEPRECATED as the information is
precomputed during metrics-scraping
Signed-off-by: Mario Constanti <mario@constanti.de>
* Adds detection of booleans in string format to getNum.
* Refactors configuration file to allow definition of different metric types
having different configuration variables.
* Refactor order of types and funcs in pkg/customersourcestate.
* Allows info and stateSet metrics to iterate over arrays.
* Adds `nilIsZero` config variable to gauge to indicate non-existing values to tread as 0 value instead of returning an error.
* Skip adding a label instead of setting value to `<nil>`.
* Replace namespace and subsystem by metricsNamePrefix
* Adjust docs for customresourcestate metrics to align with new configuration file
As KSM shouldn't be responsible for computation of metrics, a new metric
is needed to expose available and unavailable addresses of an endpoint.
This new metric is generated as a future replacement for
kube_endpoint_address_available and kube_endpoint_address_not_ready.
Signed-off-by: Mario Constanti <mario@constanti.de>
This is more flexible than the env variable, as a configuration can still set an env variable and use substitution in the args. e.g.,
```yaml
args:
- --custom-resource-state.config
- $(KSM_CUSTOM_RESOURCE_STATE_CONFIG)
env:
...
```
Add experimental kube_pod_ips metric to show all IPs on a pod.
This is useful for dual-stack clusters where pods will have at least one
IPv4 and one IPv6 address. Current kube_pod_info metric only shows
the single IP exposed by .status.podIP.
Signed-off-by: Braxton Schafer <bschafer@cloudflare.com>
Problem: In https://github.com/kubernetes/kube-state-metrics/pull/1723 a
potential panic in the pod metrics gathering was fixed by working around
a disconnect of `Spec.Containers` and `Status.ContainerStatuses`. The
slice storing the resulting metrics however was still defined based on
the length of the `Status.ContainerStatuses` list.
Solution: Make the slice dynamic and append metrics to it.
Signed-off-by: Jan Fajerski <jfajersk@redhat.com>
This test is added to ensure that ksm can be invoked as follows and that
this is a "documented" feature.
```
<ksm> --metric-denylist="
^kube_.+_created$,
^kube_.+_metadata_resource_version$,
^kube_pod_completion_time$,
^kube_pod_status_scheduled$
"
```
See: Usage in kube-prometheus jsonnet for example [1]
[1]: 9cf6111562/jsonnet/kube-prometheus/addons/ksm-lite.libsonnet (L18)
Signed-off-by: Sunil Thaha <sthaha@redhat.com>
The pkg/app/server test does not properly initialize KSM with an empty
metrics opt-in list. This results in opt-in metrics showing up in the
expected test results.
This commit changes the test to be in line with how KSM is initialized
in production code by passing in an empty opt-in list.
Both the PodDisruptionBudget and CronJob resources have been promoted
to v1 as of Kubernetes v1.21 release. The previous v1beta1 versions
are now deprecated, and will be removed in v1.25 and above. This
updates all references to the new v1 versions.
All other allowlist selectors are using plural form of resource name
except PDB. Actually it is a typo introduced by PR[1].
[1] https://github.com/kubernetes/kube-state-metrics/pull/1623
Signed-off-by: Arunprasad Rajkumar <arajkuma@redhat.com>
metric - introduce new kube_endpoint_ports metric:
* export all relevant port infomation (port name, port number and port protocol) from an endpoint
tests - make endpoint tests endpoint.spec aware:
* endpoint port struct with multiple ports need port names per port
* single port struct doesn't need a port name
* port protocol is per default TCP
Signed-off-by: Constanti, Mario <mario.constanti@daimler.com>
This commit introduces kube_*_labels and kube_*_annotations metrics to
poddisruptionbudget to keep in consistency with other k8s objects.
Signed-off-by: Arunprasad Rajkumar <arajkuma@redhat.com>
Prior to this PR, it is pretty hard and manual to diff the test failure expectation
vs actual. This PR simplifies using github.com/google/go-cmp/cmp
package.
Signed-off-by: Arunprasad Rajkumar <arajkuma@redhat.com>
This PR fixes the regression introduced on `kube_persistentvolumeclaim_labels` functionality after https://github.com/kubernetes/kube-state-metrics/pull/1468. This also implements `kube_persistentvolumeclaim_annotations`.
Signed-off-by: Arunprasad Rajkumar <arajkuma@redhat.com>
autoscaling/v2beta1 HorizontalPodAutoscaler is deprecated in v1.22+ and becomes
unavailable in v1.25+
This change updates the client to use autoscaling/v2beta2
Signed-off-by: Philip Gough <philip.p.gough@gmail.com>
Init container resource metrics diverged from the container ones
although they should be similar.
Signed-off-by: Damien Grisonnet <dgrisonn@redhat.com>
These metrics are superseded by the Pod resource metrics initiative in
Kubernetes. In 2.0.0, we removed the reworked container resource
metrics, but omitted the init container ones although they are also
covered by the Kubernetes effort.
Signed-off-by: Damien Grisonnet <dgrisonn@redhat.com>
* [FEATURE] Add --use-apiserver-cache flag to set resourceVersion=0 for ListWatch requests #1548
* [FEATURE] Introduce metrics for Kubernetes object annotations #1468
* [FEATURE] Introduce start time metric for containers in terminated state #1519
* [FEATURE] Introduce metrics for cronjob job history limits #1535
* [FEATURE] Add system_uuid dimension to kube_node_info metric #1535
* [FEATURE] Add available replica metric for statefulsets #1532
* [FEATURE] Add ready replica metric for deployments #1534
* [CHANGE] Update go clients for Kubernetes to support 1.22 #1545
* [CHANGE] Use new promlint package and update prometheus cli to 2.28.1 #1531
* [CHANGE] Replace multiListWatcher with independent listWatchers per namespace #1499
* [CHANGE] go.mod: Update and minimize dependencies #1529
* [BUGFIX] Use BuilderInterface instead of internal/store.Builder in metricshandler #1537
* [BUGFIX] Add WithAllowLabels to public BuilderInterface #1514
* Add ReadyReplicas field in Deployment status to deployment metrics family
* Depicts number of readyReplicas across all replicas sets owned by the deployment
Signed-off-by: Akshit Grover <akshit.grover2016@gmail.com>
Reviewing a pull request involves assesing in which way the introduced change
affects metrics cardinality. To ease the burder on the reviewer and to make
contributors aware of the constraint, this commit extends the pull request template
with a question about the effect on metrics cardinality.
The multiListerWatcher is a composite object encapsulating multiple
ListerWatchers and implements the ListerWatcher interface.
With the current implementation, when an individual lister fails, the
entire List operation fails. This causes no metrics to be shown when KSM
has no permissions to a single namespace.
In addition to this, the multiListerWatcher takes advantage of internal
implementation details if the client-go library by modifiying and
relying on the ResourceVersion metadata field. This introduces a bug
where reconnecting to the API server will break the multiListerWatcher
completely.
This commit replaces the multiListerWatcher with individual
ListerWatchers per each configured namespace, resolving both issues.
Signed-off-by: fpetkovski <filip.petkovsky@gmail.com>
The functions NewFilteredUnprivilegedNamespaceListWatchFromClient and
NewUnprivilegedNamespaceListWatchFromClient in the listwatch package are unused.
This commit removes them from the codebase.
Signed-off-by: fpetkovski <filip.petkovsky@gmail.com>
The `WithMetrics` method signature changed from
```
func (b *Builder) WithMetrics(r *prometheus.Registry) {
```
to
```
func (b *Builder) WithMetrics(r prometheus.Registerer) {
```
in #1223 but one occurrence was forgotten.
Signed-off-by: Lénaïc Huard <lenaic.huard@datadoghq.com>
<!-- Please use this template while reporting a bug and provide as much info as possible. Not doing so may result in your bug not being addressed in a timely manner. Thanks!
If the matter is security related, please disclose it privately see https://github.com/kubernetes/kube-state-metrics/blob/master/SECURITY.md
If the matter is security related, please disclose it privately see https://github.com/kubernetes/kube-state-metrics/blob/main/SECURITY.md
-->
**What happened**:
@ -18,10 +18,18 @@ If the matter is security related, please disclose it privately see https://gith
**How to reproduce it (as minimally and precisely as possible)**:
```bash
# An example: https://github.com/kubernetes/kube-state-metrics/issues/2223#issuecomment-1792850276
minikube start
...
go run main.go --custom-resource-state-only --custom-resource-state-config-file ksm-2223/custom-resource-config-file.yaml --kubeconfig ~/.kube/config
4. If the PR is unfinished, see how to mark it: https://git.k8s.io/community/contributors/guide/pull-requests.md#marking-unfinished-pull-requests
-->
**What this PR does / why we need it**:
<!-- markdownlint-disable-next-line MD041 -->
**What this PR does / why we need it:**
**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
**How does this change affect the cardinality of KSM:** *(increases, decreases or does not change cardinality)*
**Which issue(s) this PR fixes:** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*
BENCHSTAT_OUTPUT_FILE=result.txt make test-benchmark-compare
- run:|
echo "\`\`\`" >> "$GITHUB_STEP_SUMMARY"
cat result.txt >> "$GITHUB_STEP_SUMMARY"
echo "\`\`\`" >> "$GITHUB_STEP_SUMMARY"
cat <<EOL >> "$GITHUB_STEP_SUMMARY"
<hr />
The table shows the median and 95% confidence interval (CI) summaries for each benchmark comparing the HEAD and the BASE, and an A/B comparison under "vs base". The last column shows the statistical p-value with ten runs (n=10).
The last row has the Geometric Mean (geomean) for the given rows in the table.
Refer to <a href="https://pkg.go.dev/golang.org/x/perf/cmd/benchstat">benchstat's documentation</a> for more help.
EOL
ci-build-kube-state-metrics:
name:ci-build-kube-state-metrics
runs-on:ubuntu-latest
steps:
- name:Set up Go 1.x
uses:actions/setup-go@v2
with:
go-version:^1.16
id:go
- name:Check out code into the Go module directory
* This release builds with `k8s.io/client-go`: `v0.32.6`
* [FEATURE] Add a `reclaim_policy` label to the `kube_persistentvolume_info` metric by @SuperQ in <https://github.com/kubernetes/kube-state-metrics/pull/2615>
* [FEATURE] Use dlclark/regexp2 over standard library's package to support lookarounds by @rexagod in <https://github.com/kubernetes/kube-state-metrics/pull/2616>
* [BUGFIX] Report correct values in `kube_pod_status_reason` metric by @carlosmorenokm1 in <https://github.com/kubernetes/kube-state-metrics/pull/2644>
* [FEATURE] Add add `pathType` to `kube_ingress_path` by @rexagod in <https://github.com/kubernetes/kube-state-metrics/pull/2670>
* [FEATURE] Introduce object limits by @mrueg in <https://github.com/kubernetes/kube-state-metrics/pull/2626>
* [BUGFIX] Close reflectors once their corresponding CRDs are dropped by @rexagod in <https://github.com/kubernetes/kube-state-metrics/pull/2672>
* [FEATURE] Incorporate `WithAuthenticationAndAuthorization` to support endpoint authn/z by @mrueg in <https://github.com/kubernetes/kube-state-metrics/pull/2686>
## v2.15.0 / 2025-02-03
**Note:**
* This release builds with Golang `v1.23.5`
* This release builds with `k8s.io/client-go`: `v0.32.1`
* [BUGFIX] Fix CR cache for GVK all specified case by @chelseychen in <https://github.com/kubernetes/kube-state-metrics/pull/2567>
* [BUGFIX] Deduplicate tolerations before creating metric by @RiRa12621 in <https://github.com/kubernetes/kube-state-metrics/pull/2559>
* [BUGFIX] Make `$VERSION` 3rd-party independant by @rexagod in <https://github.com/kubernetes/kube-state-metrics/pull/2572>
* [BUGFIX] Fix NoNodePod naming in jsonnet by @mrueg in <https://github.com/kubernetes/kube-state-metrics/pull/2598>
* [BUGFIX] Panic in `util.GVRFromType` for structured types by @L3n41c in <https://github.com/kubernetes/kube-state-metrics/pull/2553>
* [FEATURE] Add external traffic policy to kube_service_info by @jahantech in <https://github.com/kubernetes/kube-state-metrics/pull/2584>
* [FEATURE] Promote kube_statefulset_ordinals_start from ALPHA -> STABLE by @pwschuurman in <https://github.com/kubernetes/kube-state-metrics/pull/2415>
* [FEATURE] Add timezone to kube_cronjob_info / Make kube_cronjob_next_schedule_time timezone-aware by @mrueg in <https://github.com/kubernetes/kube-state-metrics/pull/2376>
## v2.14.0 / 2024-11-08
**Note:**
* This release builds with Golang `v1.23.3`
* This release builds with `k8s.io/client-go`: `v0.31.2`
* This release removes `kube_endpoint_address_not_ready` and `kube_endpoint_address_available` which have been deprecated in 2022. Please use `kube_endpoint_address`as a replacement.
* [BUGFIX] Use --track-unscheduled-pods to select unscheduled pods in Daemonset sharding by @CatherineF-dev in <https://github.com/kubernetes/kube-state-metrics/pull/2388>
* [BUGFIX] Install tools so VERSION gets set by @mrueg in <https://github.com/kubernetes/kube-state-metrics/pull/2456>
* [BUGFIX] Syntax errors in kube-state-metrics.libsonnet by @jeffmccune in <https://github.com/kubernetes/kube-state-metrics/pull/2454>
* [BUGFIX] Set kube_job_status_failed metric even when there are no job.Status.Conditions present by @richabanker in <https://github.com/kubernetes/kube-state-metrics/pull/2485>
* [BUGFIX] de-duplication of custom resource metrics by @bartlettc22 in <https://github.com/kubernetes/kube-state-metrics/pull/2502>
* [BUGFIX] Configure sharding every time MetricsHandler.Run runs by @wallee94 in <https://github.com/kubernetes/kube-state-metrics/pull/2478>
* [BUGFIX] Panic in `util.GVRFromType` for core objects by @L3n41c in <https://github.com/kubernetes/kube-state-metrics/pull/2535>
* [BUGFIX] Big memory value overflow by @leiwingqueen in <https://github.com/kubernetes/kube-state-metrics/pull/2540>
* [BUGFIX] Expose empty labels by @mrueg in <https://github.com/kubernetes/kube-state-metrics/pull/2539>
* [BUGFIX] CustomResourceMetrics: Convert status condition Unknown to a valid value by @Haleygo in <https://github.com/kubernetes/kube-state-metrics/pull/2536>
* [CHANGE] Remove deprecated endpoint address metric by @mrueg in <https://github.com/kubernetes/kube-state-metrics/pull/2527>
* [FEATURE] Add new metric kube_job_status_suspended by @Indresh2410 in <https://github.com/kubernetes/kube-state-metrics/pull/2542>
* [FEATURE] Move endpoint ports into address metric by @mrueg in <https://github.com/kubernetes/kube-state-metrics/pull/2503>
* [ENHANCEMENT] Use concurrent map when storing metrics by @rarruda in <https://github.com/kubernetes/kube-state-metrics/pull/2510>
## v2.13.0 / 2024-07-18
**Note:**
* This release builds with Golang `v1.22.5`.
* This release builds with `k8s.io/client-go`: `v0.30.3`.
* This release adds read and write timeouts for requests. The defaults might have an impact on scrapes that take a long time.
* [BUGFIX] Pod autosharding: transition from labelselector to fieldselector by @pkoutsovasilis in <https://github.com/kubernetes/kube-state-metrics/pull/2347>
* [ENHANCEMENT] Add automatic detection of memory limits by @SuperQ in <https://github.com/kubernetes/kube-state-metrics/pull/2447>
* [FEATURE] Add `readyz` endpoint by @rexagod in <https://github.com/kubernetes/kube-state-metrics/pull/2442>
* [FEATURE] Add `livez` endpoint by @rexagod in <https://github.com/kubernetes/kube-state-metrics/pull/2418>
* [FEATURE] Add kube_persistentvolume_volume_mode metric by @ricardoapl in <https://github.com/kubernetes/kube-state-metrics/pull/2370>
* [FEATURE] Add read and write timeouts by @Pokom in <https://github.com/kubernetes/kube-state-metrics/pull/2412>
## v2.12.0 / 2024-04-02
**Note:**
* This release addresses a critical issue where scraping the exposition data for certain types caused metrics-backends to crash: <https://github.com/kubernetes/kube-state-metrics/issues/2248>.
* This release builds with `k8s.io/client-go`: `v0.29.3`.
* [BUGFIX] Fallback to `gauge` for `protobuf`-based negotiations by @rexagod in <https://github.com/kubernetes/kube-state-metrics/pull/2270>
* [ENHANCEMENT] Add `kube_pod_container_status_last_terminated_timestamp`by @tetianakravchenko in <https://github.com/kubernetes/kube-state-metrics/pull/2291>
* [FEATURE] Allow prefixing expandable paths by @rexagod in <https://github.com/kubernetes/kube-state-metrics/pull/2052>
## v2.11.0 / 2024-03-04
**Note:**
This release builds with Golang `v1.21.8`.
* [ENHANCEMENT] Add OpenSSF Scorecard to README by @dalehenries in <https://github.com/kubernetes/kube-state-metrics/pull/2277>
* [ENHANCEMENT] Generate OpenVX data for every release by @shafeeqes in <https://github.com/kubernetes/kube-state-metrics/pull/2276>
* [ENHANCEMENT] Add restartPolicy to `kube_pod_init_container_info` metric by @changhyuni in <https://github.com/kubernetes/kube-state-metrics/pull/2240>
* [FEATURE] Add `kube_node_status_addresses` metric by @stonith in <https://github.com/kubernetes/kube-state-metrics/pull/2252>
* [FEATURE] Add namespace label to `endpointslice` metrics by @mrueg in <https://github.com/kubernetes/kube-state-metrics/pull/2266>
* [FEATURE] Add opt-in `kube_persistentvolume_csi_attributes` metric by @machadovilaca in <https://github.com/kubernetes/kube-state-metrics/pull/2133>
* [FEATURE] Add new metric `kube_pod_scheduler` metric by @adinhodovic in <https://github.com/kubernetes/kube-state-metrics/pull/2222>
* [FEATURE] Support filtering annotations allow-list by `*` by @xonvanetta in <https://github.com/kubernetes/kube-state-metrics/pull/2234>
* [ENHANCEMENT] Support scraping pod metrics that are still in scheduling status and have no assigned nodes by @mickeyzzc in <https://github.com/kubernetes/kube-state-metrics/pull/2217>
* [FEATURE] Add backend resource info for `kube_ingress_path` by @rohitphatak in <https://github.com/kubernetes/kube-state-metrics/pull/2109>
## v2.10.1 / 2023-10-09
**Note:**
* This release addresses a regression introduced in [#2105](https://github.com/kubernetes/kube-state-metrics/pull/2105).
* [BUGFIX] Remove FieldSelector from non-namespaced resources by @mrueg and @dgrisonnet in [#2190](https://github.com/kubernetes/kube-state-metrics/pull/2190)
* [ENHANCEMENT] Bump Go to v1.20.8
## v2.10.0 / 2023-08-31
**Note:**
* Label and annotation metrics aren't exposed by default anymore to reduce the memory usage of the default configuration of kube-state-metrics. Before this change, they used to only include the name and namespace of the objects which is not relevant to users not opting in these metrics.
* [BUGFIX] Log no _info suffix in name only once per reading the configuration for custommetrics by @chrischdi in <https://github.com/kubernetes/kube-state-metrics/pull/2157>
* [BUGFIX] Don't crash on non-existent valueFrom path values by @chihshenghuang in <https://github.com/kubernetes/kube-state-metrics/pull/2140>
* [BUGFIX] Index out of range in metrics_store.SanitizeHeaders by @mrueg in <https://github.com/kubernetes/kube-state-metrics/pull/2166>
* [BUGFIX] Always extract the headers but only write it when we have custommetrics by @chrischdi in <https://github.com/kubernetes/kube-state-metrics/pull/2154>
* [BUGFIX] Add filtering for Lease metrics by @ntoofu in <https://github.com/kubernetes/kube-state-metrics/pull/2122>
* [FEATURE] Implement kube_pod_status_initialized_time by @opeco17 in <https://github.com/kubernetes/kube-state-metrics/pull/2148>
* [FEATURE] Disable labels and annotations metrics when metric-annotations-… by @opeco17 in <https://github.com/kubernetes/kube-state-metrics/pull/2145>
* [FEATURE] Add webhooks client config service metrics by @dgrisonnet in <https://github.com/kubernetes/kube-state-metrics/pull/2114>
* [FEATURE] Support kube_persistentvolumeclaim_deletion_timestamp by @maxime1907 in <https://github.com/kubernetes/kube-state-metrics/pull/2074>
* [FEATURE] Support kube_persistentvolume_deletion_timestamp by @maxime1907 in <https://github.com/kubernetes/kube-state-metrics/pull/2075>
* [FEATURE] Adds new metric `kube_pod_service_account` by @swarup-stripe in <https://github.com/kubernetes/kube-state-metrics/pull/2096>
* [FEATURE] Add volumemode to PVC info metric by @machadovilaca in <https://github.com/kubernetes/kube-state-metrics/pull/2134>
* [FEATURE] Enable metric-annotations-allowlist and metric-labels-allowlist for ResourceQuota by @opeco17 in <https://github.com/kubernetes/kube-state-metrics/pull/2175>
* [FEATURE] Allow field KV general matching by @rexagod in <https://github.com/kubernetes/kube-state-metrics/pull/2067>
* [FEATURE] Support hot reload for kubeconfig by @opeco17 in <https://github.com/kubernetes/kube-state-metrics/pull/2144>
* [FEATURE] Add support for endpoint topology routing hints by @MarkSRobinson in <https://github.com/kubernetes/kube-state-metrics/pull/2090>
## v2.9.2 / 2023-05-30
This release does not incorporate any user-facing changes. Re-running release procedures as the process for the previous release failed. Changes are listed in v2.9.0.
## v2.9.1 / 2023-05-29
This release does not incorporate any user-facing changes. Re-running release procedures as the process for the previous release failed. Changes are listed in v2.9.0.
## v2.9.0 / 2023-05-23
The changes mentioned below are only the user-facing ones. For a list of the complete set of changes, refer the changelog associated with the release tag.
**Note:**
* The deprecated experimental VerticalPodAutoscaler metrics are no longer supported, and have been removed. We recommend to use CustomResourceState metrics to gather metrics from custom resources like the Vertical Pod Autoscaler.
* #2004 regulated label names to adhere with [OTel-Prometheus standards](https://github.com/open-telemetry/opentelemetry-specification/blob/8946dfc6a2302f78b0224fcc3f4dfb816a7bb1f4/specification/compatibility/prometheus_and_openmetrics.md?plain=1#L224-L229), so existing label names that do not follow the same may be replaced by the ones that do. Please refer to the PR for more details.
* [BUGFIX] Adhere to OTel-Prometheus standard for labels #2004@rexagod
* [BUGFIX] Respect relative paths for label resolutions #2007@rexagod
* [BUGFIX] Support LabelsFromPath functionality for Info-typed metrics #2048@murphd40
@ -6,21 +6,49 @@ _As contributors and maintainers of this project, and in the interest of fosteri
## Getting Started
We have full documentation on how to get started contributing here:
We have full documentation on how to get started contributing here:
<!---
If your repo has certain guidelines for contribution, put them here ahead of the general k8s resources
-->
### Semantic Commit Messages
- [Contributor License Agreement](https://git.k8s.io/community/CLA.md) Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests
- [Kubernetes Contributor Guide](http://git.k8s.io/community/contributors/guide) - Main contributor documentation, or you can just jump directly to the [contributing section](http://git.k8s.io/community/contributors/guide#contributing)
- [Contributor Cheat Sheet](https://git.k8s.io/community/contributors/guide/contributor-cheatsheet/README.md) - Common resources for existing developers
We use [semantic commit messages](https://www.conventionalcommits.org/en/v1.0.0/) in this repository.
They follow this format: `<type>[optional scope]: <description>`
Examples for commit messages following this are:
`feat: allow provided config object to extend other configs`
You can also include a scope within parenthesis:
`fix(scope): Prevent wrong calculation of storage`
Here's a list of types that we use:
| Type | Explanation |
|---|---|
| feat | A new feature |
| fix | A bug fix |
| docs | Documentation only changes |
| style | Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) |
| refactor | A code change that neither fixes a bug nor adds a feature |
| perf | A code change that improves performance |
| test | Adding missing tests or correcting existing tests |
| build |Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm) |
| ci | Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs) |
| chore | Other changes that don't modify src or test files |
| revert | Reverts a previous commit |
### Further Information
* [Contributor License Agreement](https://git.k8s.io/community/CLA.md) Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests
* [Kubernetes Contributor Guide](http://git.k8s.io/community/contributors/guide) - Main contributor documentation, or you can just jump directly to the [contributing section](http://git.k8s.io/community/contributors/guide#contributing)
* [Contributor Cheat Sheet](https://git.k8s.io/community/contributors/guide/contributor-cheatsheet/README.md) - Common resources for existing developers
## Mentorship
- [Mentoring Initiatives](https://git.k8s.io/community/mentoring) - We have a diverse set of mentorship programs available that are always looking for volunteers!
* [Mentoring Initiatives](https://git.k8s.io/community/mentoring) - We have a diverse set of mentorship programs available that are always looking for volunteers!
## Contact Information
- [Join Slack](http://slack.k8s.io) to sign up and join the Kubernetes Slack. Please make sure to read our [Slack Guidelines](https://github.com/kubernetes/community/blob/master/communication/slack-guidelines.md) before participating.
- The [kube-state-metrics slack channel](https://kubernetes.slack.com/messages/CJJ529RUY) provides an effective communication platform to reach out to members and other users of the project. It offers an alternative to submitting a GitHub issue for when you have questions and issues.
* [Join Slack](http://slack.k8s.io) to sign up and join the Kubernetes Slack. Please make sure to read our [Slack Guidelines](https://github.com/kubernetes/community/blob/master/communication/slack-guidelines.md) before participating.
* The [kube-state-metrics slack channel](https://kubernetes.slack.com/messages/CJJ529RUY) provides an effective communication platform to reach out to members and other users of the project. It offers an alternative to submitting a GitHub issue for when you have questions and issues.
kube-state-metrics is welcoming contributions from the community. If you are interested in intensifying your contributions and becoming a maintainer, this doc describes the necessary steps.
As part of the Kubernetes project, we rely on the [community membership process](https://github.com/kubernetes/community/blob/master/community-membership.md). We do not adhere strictly to the numbers of contributions and reviews. Still as becoming a maintainer is a trust-based process and we desire positive outcomes for the project, we look for a long-term interest and engagement.
## Adding a new reviewer
* Ensure the new reviewer is a member of the [kubernetes organization](https://github.com/kubernetes/org/blob/main/config/kubernetes/org.yaml).
* Add the new reviewer to the [OWNERS](OWNERS) file to be able to review pull requests.
* Add the new reviewer to the [kube-state-metrics-maintainers group](https://github.com/kubernetes/org/blob/main/config/kubernetes/sig-instrumentation/teams.yaml), to gain write access to the kube-state-metrics repository (e.g. for creating new releases).
## Adding a new approver
* Ensure the new approver is already a reviewer in the [OWNERS](OWNERS) file.
* Add the new approver to the [OWNERS](OWNERS) file to be able to approve pull requests.
* Add the new approver to the [SECURITY_CONTACTS](SECURITY_CONTACTS) file to be able to get notified on security related incidents.
* Add the new approver to the [kube-state-metrics-admin group](https://github.com/kubernetes/org/blob/main/config/kubernetes/sig-instrumentation/teams.yaml), to get admin access to the kube-state-metrics repository.
* Add the new approver to the k8s.io [OWNERS](https://github.com/kubernetes/k8s.io/blob/main/k8s.gcr.io/images/k8s-staging-kube-state-metrics/OWNERS) file to be able to approve image promotion from the staging registry.
@find internal/store -type f -not -name '*_test.go' -exec sed -nE 's/.*"(kube_[^"]+)".*/\1/p'{}\;| sort -u > code_metrics
@diff -u0 code_metrics documented_metrics ||(echo"ERROR: Metrics with - are present in code but missing in documentation, metrics with + are documented but not found in code.";exit 1)
@echo OK
@rm -f code_metrics documented_metrics
@echo "- Checking for orphan documentation files"
@cd docs;for doc in *.md;doif["$$doc" !="README.md"]&& ! grep -q "$$doc" *.md;thenecho"ERROR: No link to documentation file $${doc} detected";exit 1;fi;done
@cd docs;for doc in $$(find metrics/* -name '*.md' | sed 's/.*\///');doif["$$doc" !="README.md"]&& ! grep -q "$$doc" *.md;thenecho"ERROR: No link to documentation file $${doc} detected";exit 1;fi;done
@echo OK
build-local:
@ -63,7 +74,8 @@ build-local:
build:kube-state-metrics
kube-state-metrics:
${DOCKER_CLI} run --rm -v "${PWD}:/go/src/k8s.io/kube-state-metrics" -w /go/src/k8s.io/kube-state-metrics golang:${GO_VERSION} make build-local
# Need to update git setting to prevent failing builds due to https://github.com/docker-library/golang/issues/452
${DOCKER_CLI} run --rm -v "${PWD}:/go/src/k8s.io/kube-state-metrics" -w /go/src/k8s.io/kube-state-metrics -e GOOS=$(OS) -e GOARCH=$(ARCH) golang:${GO_VERSION} git config --global --add safe.directory "*"&& make build-local
test-unit:
GOOS=$(shell uname -s | tr A-Z a-z)GOARCH=$(ARCH)$(TESTENVVAR) go test --race $(FLAGS)$(PKGS)
@ -74,12 +86,24 @@ test-rules:
shellcheck:
${DOCKER_CLI} run -v "${PWD}:/mnt" koalaman/shellcheck:stable $(shell find . -type f -name "*.sh" -not -path "*vendor*")
lint-markdown-format:
${DOCKER_CLI} run -v "${PWD}:/workdir" davidanson/markdownlint-cli2:v${MARKDOWNLINT_CLI2_VERSION} --config .markdownlint-cli2.jsonc
fix-markdown-format:
${DOCKER_CLI} run -v "${PWD}:/workdir" davidanson/markdownlint-cli2:v${MARKDOWNLINT_CLI2_VERSION} --fix --config .markdownlint-cli2.jsonc
kube-state-metrics is a simple service that listens to the Kubernetes API
kube-state-metrics (KSM) is a simple service that listens to the Kubernetes API
server and generates metrics about the state of the objects. (See examples in
the Metrics section below.) It is not focused on the health of the individual
Kubernetes components, but rather on the health of the various objects inside,
@ -26,56 +30,61 @@ the raw metrics. Note that the metrics exposed on the `/metrics` endpoint
reflect the current state of the Kubernetes cluster. When Kubernetes objects
are deleted they are no longer visible on the `/metrics` endpoint.
Note that any new features will be merged into master but released with v2.1.0 release, as currently v2.0.0 is in post feature freeze and only accepting bug fixes.
> [!NOTE]
> This README is generated from a [template](./README.md.tpl). Please make your changes there and run `make generate-template`.
## Table of Contents
- [Versioning](#versioning)
- [Kubernetes Version](#kubernetes-version)
- [Compatibility matrix](#compatibility-matrix)
- [Resource group version compatibility](#resource-group-version-compatibility)
- [Container Image](#container-image)
- [Metrics Documentation](#metrics-documentation)
- [Conflict resolution in label names](#conflict-resolution-in-label-names)
All additional compatibility is only best effort, or happens to still/already be supported.
#### Compatibility matrix
At most, 5 kube-state-metrics and 5 [kubernetes releases](https://github.com/kubernetes/kubernetes/releases) will be recorded below.
Generally, it is recommended to use the latest release of kube-state-metrics. If you run a very recent version of Kubernetes, you might want to use an unreleased version to have the full range of supported resources. If you run an older version of Kubernetes, you might need to run an older version in order to have full support for all resources. Be aware, that the maintainers will only support the latest release. Older versions might be supported by interested users of the community.
- `-` The Kubernetes cluster has features the client-go library can't use (additional API objects, deprecated APIs, etc).
**Note:** The `v2.0.0-alpha.2+` and `master` releases of kube-state-metrics work on Kubernetes v1.17 and v1.18 excluding Ingress or CertificateSigningRequest resource metrics. If you require those metrics and are on an older Kubernetes version, use v2.0.0-alpha.1 or v1.9.8 kube-state-metrics release.
| kube-state-metrics | Kubernetes client-go Version |
that ensures that there are no possible conflicts.
#### Enabling VerticalPodAutoscalers
#### ECMAScript regular expression support for allow and deny lists
Please note that the collector for `verticalpodautoscalers` is **disabled** by default; Vertical Pod Autoscaler metrics will not be collected until the collector is enabled. This is because Vertical Pod Autoscalers are managed as custom resources.
If you want to enable this collector,
the [instructions](./docs/verticalpodautoscaler-metrics.md#Configuration) are located in the [Vertical Pod Autoscaler Metrics](./docs/verticalpodautoscaler-metrics.md) documentation.
Starting from [#2616](https://github.com/kubernetes/kube-state-metrics/pull/2616/files), kube-state-metrics supports ECMAScript's `regexp` for allow and deny lists. This was incorporated as a workaround for the limitations of the `regexp` package in Go, which does not support lookarounds due to their non-linear time complexity. Please note that while lookarounds are now supported for allow and deny lists, regular expressions' evaluation time is capped at a minute to prevent performance issues.
### Kube-state-metrics self metrics
@ -134,14 +142,16 @@ If you encounter those errors in the metrics, it is most likely a configuration
> Note: These recommendations are based on scalability tests done over a year ago. They may differ significantly today.
Resource usage for kube-state-metrics changes with the Kubernetes objects (Pods/Nodes/Deployments/Secrets etc.) size of the cluster.
To some extent, the Kubernetes objects in a cluster are in direct proportion to the node number of the cluster.
As a general rule, you should allocate
As a general rule, you should allocate:
* 200MiB memory
* 250MiB memory
* 0.1 cores
For clusters of more than 100 nodes, allocate at least
Note that if CPU limits are set too low, kube-state-metrics' internal queues will not be able to be worked off quickly enough, resulting in increased memory consumption as the queue length grows. If you experience problems resulting from high memory allocation or CPU throttling, try increasing the CPU limits.
* 2MiB memory per node
* 0.001 cores per node
### Latency
These numbers are based on [scalability tests](https://github.com/kubernetes/kube-state-metrics/issues/124#issuecomment-318394185) at 30 pods per node.
In a 100 node cluster scaling test the latency numbers were as follows:
Note that if CPU limits are set too low, kube-state-metrics' internal queues will not be able to be worked off quickly enough, resulting in increased memory consumption as the queue length grows. If you experience problems resulting from high memory allocation, try increasing the CPU limits.
```text
"Perc50": 259615384 ns,
"Perc90": 475000000 ns,
"Perc99": 906666666 ns.
```
### A note on costing
By default, kube-state-metrics exposes several metrics for events across your cluster. If you have a large number of frequently-updating resources on your cluster, you may find that a lot of data is ingested into these metrics. This can incur high costs on some cloud providers. Please take a moment to [configure what metrics you'd like to expose](docs/cli-arguments.md), as well as consult the documentation for your Kubernetes environment in order to avoid unexpectedly high costs.
By default, kube-state-metrics exposes several metrics for events across your cluster. If you have a large number of frequently-updating resources on your cluster, you may find that a lot of data is ingested into these metrics. This can incur high costs on some cloud providers. Please take a moment to [configure what metrics you'd like to expose](docs/developer/cli-arguments.md), as well as consult the documentation for your Kubernetes environment in order to avoid unexpectedly high costs.
### kube-state-metrics vs. metrics-server
@ -195,9 +218,9 @@ The [metrics-server](https://github.com/kubernetes-incubator/metrics-server)
is a project that has been inspired by
[Heapster](https://github.com/kubernetes-retired/heapster) and is implemented
to serve the goals of core metrics pipelines in [Kubernetes monitoring
It is a cluster level component which periodically scrapes metrics from all
Kubernetes nodes served by Kubelet through Summary API. The metrics are
Kubernetes nodes served by Kubelet through Metrics API. The metrics are
aggregated, stored in memory and served in [Metrics API
format](https://git.k8s.io/metrics/pkg/apis/metrics/v1alpha1/types.go). The
metrics-server stores the latest values only and is not responsible for
@ -212,38 +235,89 @@ metrics-server it too is not responsible for exporting its metrics anywhere.
Having kube-state-metrics as a separate project also enables access to these
metrics from monitoring systems such as Prometheus.
### Horizontal scaling (sharding)
### Horizontal sharding
In order to scale kube-state-metrics horizontally, some automated sharding capabilities have been implemented. It is configured with the following flags:
In order to shard kube-state-metrics horizontally, some automated sharding capabilities have been implemented. It is configured with the following flags:
* `--shard` (zero indexed)
* `--total-shards`
Sharding is done by taking an md5 sum of the Kubernetes Object's UID and performing a modulo operation on it, with the total number of shards. The configured shard decides whether the object is handled by the respective instance of kube-state-metrics or not. Note that this means all instances of kube-state-metrics even if sharded will have the network traffic and the resource consumption for unmarshaling objects for all objects, not just the ones it is responsible for. To optimize this further, the Kubernetes API would need to support sharded list/watch capabilities. Overall memory consumption should be 1/n th of each shard compared to an unsharded setup. Typically, kube-state-metrics needs to be memory and latency optimized in order for it to return its metrics rather quickly to Prometheus.
Sharding is done by taking an md5 sum of the Kubernetes Object's UID and performing a modulo operation on it with the total number of shards. Each shard decides whether the object is handled by the respective instance of kube-state-metrics or not. Note that this means all instances of kube-state-metrics, even if sharded, will have the network traffic and the resource consumption for unmarshaling objects for all objects, not just the ones they are responsible for. To optimize this further, the Kubernetes API would need to support sharded list/watch capabilities. In the optimal case, memory consumption for each shard will be 1/n compared to an unsharded setup. Typically, kube-state-metrics needs to be memory and latency optimized in order for it to return its metrics rather quickly to Prometheus. One way to reduce the latency between kube-state-metrics and the kube-apiserver is to run KSM with the `--use-apiserver-cache` flag. In addition to reducing the latency, this option will also lead to a reduction in the load on etcd.
Sharding should be used carefully, and additional monitoring should be set up in order to ensure that sharding is set up and functioning as expected (eg. instances for each shard out of the total shards are configured).
Sharding should be used carefully and additional monitoring should be set up in order to ensure that sharding is set up and functioning as expected (eg. instances for each shard out of the total shards are configured).
##### Automated sharding
#### Automated sharding
There is also an experimental feature, that allows kube-state-metrics to auto discover its nominal position if it is deployed in a StatefulSet, in order to automatically configure sharding. This is an experimental feature and may be broken or removed without notice.
Automatic sharding allows each shard to discover its nominal position when deployed in a StatefulSet which is useful for automatically configuring sharding. This is an experimental feature and may be broken or removed without notice.
To enable automated sharding kube-state-metrics must be run by a `StatefulSet` and the pod names and namespace must be handed to the kube-state-metrics process via the `--pod` and `--pod-namespace` flags.
To enable automated sharding, kube-state-metrics must be run by a `StatefulSet` and the pod name and namespace must be handed to the kube-state-metrics process via the `--pod` and `--pod-namespace` flags. Example manifests demonstrating the autosharding functionality can be found in [`/examples/autosharding`](./examples/autosharding).
There are example manifests demonstrating the autosharding functionality in [`/examples/autosharding`](./examples/autosharding).
This way of deploying shards is useful when you want to manage KSM shards through a single Kubernetes resource (a single `StatefulSet` in this case) instead of having one `Deployment` per shard. The advantage can be especially significant when deploying a high number of shards.
The downside of using an auto-sharded setup comes from the rollout strategy supported by `StatefulSet`s. When managed by a `StatefulSet`, pods are replaced one at a time with each pod first getting terminated and then recreated. Besides such rollouts being slower, they will also lead to short downtime for each shard. If a Prometheus scrape happens during a rollout, it can miss some of the metrics exported by kube-state-metrics.
### Daemonset sharding for pod metrics
For pod metrics, they can be sharded per node with the following flag:
* `--node=$(NODE_NAME)`
Each kube-state-metrics pod uses FieldSelector (spec.nodeName) to watch/list pod metrics only on the same node.
Other metrics can be sharded via [Horizontal sharding](#horizontal-sharding).
### Setup
Install this project to your `$GOPATH` using `go get`:
```
go get k8s.io/kube-state-metrics
```bash
go get k8s.io/kube-state-metrics/v2
```
#### Building the Docker container
Simply run the following command in this root folder, which will create a
self-contained, statically-linked binary and build a Docker image:
```
```bash
make container
```
@ -252,34 +326,44 @@ make container
Simply build and run kube-state-metrics inside a Kubernetes pod which has a
service account token that has read-only access to the Kubernetes cluster.
### For users of prometheus-operator/kube-prometheus stack
#### For users of prometheus-operator/kube-prometheus stack
The ([`kube-prometheus`](https://github.com/prometheus-operator/kube-prometheus/)) stack installs kube-state-metrics as one of its [components](https://github.com/prometheus-operator/kube-prometheus#kube-prometheus); you do not need to install kube-state-metrics if you're using the kube-prometheus stack.
If you want to revise the default configuration for kube-prometheus, for example to enable non-default metrics, have a look at [Customizing Kube-Prometheus](https://github.com/prometheus-operator/kube-prometheus#customizing-kube-prometheus).
If you want to revise the default configuration for kube-prometheus, for example to enable non-default metrics, have a look at [Customizing Kube-Prometheus](https://github.com/prometheus-operator/kube-prometheus/blob/main/docs/customizing.md).
#### Kubernetes Deployment
To deploy this project, you can simply run `kubectl apply -f examples/standard` and a
Kubernetes service and deployment will be created. (Note: Adjust the apiVersion of some resource if your kubernetes cluster's version is not 1.8+, check the yaml file for more information).
To deploy this project, you can simply run `kubectl apply -f examples/standard` and a Kubernetes service and deployment will be created. (Note: Adjust the apiVersion of some resource if your kubernetes cluster's version is not 1.8+, check the yaml file for more information).
To have Prometheus discover kube-state-metrics instances it is advised to create a specific Prometheus scrape config for kube-state-metrics that picks up both metrics endpoints. Annotation based discovery is discouraged as only one of the endpoints would be able to be selected, plus kube-state-metrics in most cases has special authentication and authorization requirements as it essentially grants read access through the metrics endpoint to most information available to it.
**Note:** Google Kubernetes Engine (GKE) Users - GKE has strict role permissions that will prevent the kube-state-metrics roles and role bindings from being created. To work around this, you can give your GCP identity the cluster-admin role by running the following one-liner:
```
```bash
kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=$(gcloud info --format='value(config.account)')
```
Note that your GCP identity is case sensitive but `gcloud info` as of Google Cloud SDK 221.0.0 is not. This means that if your IAM member contains capital letters, the above one-liner may not work for you. If you have 403 forbidden responses after running the above command and `kubectl apply -f examples/standard`, check the IAM member associated with your account at https://console.cloud.google.com/iam-admin/iam?project=PROJECT_ID. If it contains capital letters, you may need to set the --user flag in the command above to the case-sensitive role listed at https://console.cloud.google.com/iam-admin/iam?project=PROJECT_ID.
Note that your GCP identity is case sensitive but `gcloud info` as of Google Cloud SDK 221.0.0 is not. This means that if your IAM member contains capital letters, the above one-liner may not work for you. If you have 403 forbidden responses after running the above command and `kubectl apply -f examples/standard`, check the IAM member associated with your account at <https://console.cloud.google.com/iam-admin/iam?project=PROJECT_ID>. If it contains capital letters, you may need to set the --user flag in the command above to the case-sensitive role listed at <https://console.cloud.google.com/iam-admin/iam?project=PROJECT_ID>.
After running the above, if you see `Clusterrolebinding "cluster-admin-binding" created`, then you are able to continue with the setup of this service.
#### Healthcheck Endpoints
The following healthcheck endpoints are available (`self` refers to the telemetry port, while `main` refers to the exposition port):
* `/healthz` (exposed on `main`): Returns a 200 status code if the application is running. We recommend to use this for the startup probe.
* `/livez` (exposed on `main`): Returns a 200 status code if the application is not affected by an outage of the Kubernetes API Server. We recommend to using this for the liveness probe.
* `/readyz` (exposed on `self`): Returns a 200 status code if the application is ready to accept requests and expose metrics. We recommend using this for the readiness probe.
Note that it is discouraged to use the telemetry metrics endpoint for any probe when proxying the exposition data.
#### Limited privileges environment
If you want to run kube-state-metrics in an environment where you don't have cluster-reader role, you can:
- give it `view` privileges on specific namespaces (using roleBinding) (*note: you can add this roleBinding to all the NS you want your serviceaccount to access*)
* give it `view` privileges on specific namespaces (using roleBinding) (*note: you can add this roleBinding to all the NS you want your serviceaccount to access*)
- then specify a set of namespaces (using the `--namespaces` option) and a set of kubernetes objects (using the `--resources`) that your serviceaccount has access to in the `kube-state-metrics` deployment configuration
* then specify a set of namespaces (using the `--namespaces` option) and a set of kubernetes objects (using the `--resources`) that your serviceaccount has access to in the `kube-state-metrics` deployment configuration
```yaml
spec:
@ -318,24 +403,43 @@ spec:
- '--namespaces=project1'
```
For the full list of arguments available, see the documentation in [docs/cli-arguments.md](./docs/cli-arguments.md)
For the full list of arguments available, see the documentation in [docs/developer/cli-arguments.md](./docs/developer/cli-arguments.md)
#### Helm Chart
Starting from the kube-state-metrics chart `v2.13.3` (kube-state-metrics image `v1.9.8`), the official [Helm chart](https://artifacthub.io/packages/helm/prometheus-community/kube-state-metrics/) is maintained in [prometheus-community/helm-charts](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-state-metrics). Starting from kube-state-metrics chart `v3.0.0` only kube-state-metrics images of `v2.0.0 +` are supported.
#### Development
When developing, test a metric dump against your local Kubernetes cluster by
running:
When developing, test a metric dump against your local Kubernetes cluster by running:
> Users can override the apiserver address in KUBE-CONFIG file with `--apiserver` command line.
To run the e2e tests locally see the documentation in [tests/README.md](./tests/README.md).
#### Developer Contributions
When developing, there are certain code patterns to follow to better your contributing experience and likelihood of e2e and other ci tests to pass. To learn more about them, see the documentation in [docs/developer/guide.md](./docs/developer/guide.md).
#### Community
This project is sponsored by [SIG Instrumentation](https://github.com/kubernetes/community/tree/master/sig-instrumentation).
There is also a channel for [#kube-state-metrics](https://kubernetes.slack.com/archives/CJJ529RUY) on Kubernetes' Slack.
You can also join the SIG Instrumentation [mailing list](https://groups.google.com/forum/#!forum/kubernetes-sig-instrumentation).
This will typically add invites for the following meetings to your calendar, in which topics around kube-state-metrics can be discussed.
* Regular SIG Meeting: [Thursdays at 9:30 PT (Pacific Time)](https://zoom.us/j/5342565819?pwd=RlVsK21NVnR1dmE3SWZQSXhveHZPdz09) (biweekly). [Convert to your timezone](http://www.thetimezoneconverter.com/?t=9:30&tz=PT%20%28Pacific%20Time%29).
* Regular Triage Meeting: [Thursdays at 9:30 PT (Pacific Time)](https://zoom.us/j/5342565819?pwd=RlVsK21NVnR1dmE3SWZQSXhveHZPdz09) (biweekly - alternating with regular meeting). [Convert to your timezone](http://www.thetimezoneconverter.com/?t=9:30&tz=PT%20%28Pacific%20Time%29).
All additional compatibility is only best effort, or happens to still/already be supported.
#### Compatibility matrix
At most, 5 kube-state-metrics and 5 [kubernetes releases](https://github.com/kubernetes/kubernetes/releases) will be recorded below.
Generally, it is recommended to use the latest release of kube-state-metrics. If you run a very recent version of Kubernetes, you might want to use an unreleased version to have the full range of supported resources. If you run an older version of Kubernetes, you might need to run an older version in order to have full support for all resources. Be aware, that the maintainers will only support the latest release. Older versions might be supported by interested users of the community.
| kube-state-metrics | Kubernetes client-go Version |
that ensures that there are no possible conflicts.
#### ECMAScript regular expression support for allow and deny lists
Starting from [#2616](https://github.com/kubernetes/kube-state-metrics/pull/2616/files), kube-state-metrics supports ECMAScript's `regexp` for allow and deny lists. This was incorporated as a workaround for the limitations of the `regexp` package in Go, which does not support lookarounds due to their non-linear time complexity. Please note that while lookarounds are now supported for allow and deny lists, regular expressions' evaluation time is capped at a minute to prevent performance issues.
### Kube-state-metrics self metrics
kube-state-metrics exposes its own general process metrics under `--telemetry-host` and `--telemetry-port` (default 8081).
kube-state-metrics also exposes list and watch success and error metrics. These can be used to calculate the error rate of list or watch resources.
If you encounter those errors in the metrics, it is most likely a configuration or permission issue, and the next thing to investigate would be looking
Resource usage for kube-state-metrics changes with the Kubernetes objects (Pods/Nodes/Deployments/Secrets etc.) size of the cluster.
To some extent, the Kubernetes objects in a cluster are in direct proportion to the node number of the cluster.
As a general rule, you should allocate:
* 250MiB memory
* 0.1 cores
Note that if CPU limits are set too low, kube-state-metrics' internal queues will not be able to be worked off quickly enough, resulting in increased memory consumption as the queue length grows. If you experience problems resulting from high memory allocation or CPU throttling, try increasing the CPU limits.
### Latency
In a 100 node cluster scaling test the latency numbers were as follows:
```text
"Perc50": 259615384 ns,
"Perc90": 475000000 ns,
"Perc99": 906666666 ns.
```
### A note on costing
By default, kube-state-metrics exposes several metrics for events across your cluster. If you have a large number of frequently-updating resources on your cluster, you may find that a lot of data is ingested into these metrics. This can incur high costs on some cloud providers. Please take a moment to [configure what metrics you'd like to expose](docs/developer/cli-arguments.md), as well as consult the documentation for your Kubernetes environment in order to avoid unexpectedly high costs.
### kube-state-metrics vs. metrics-server
The [metrics-server](https://github.com/kubernetes-incubator/metrics-server)
is a project that has been inspired by
[Heapster](https://github.com/kubernetes-retired/heapster) and is implemented
to serve the goals of core metrics pipelines in [Kubernetes monitoring
It is a cluster level component which periodically scrapes metrics from all
Kubernetes nodes served by Kubelet through Metrics API. The metrics are
aggregated, stored in memory and served in [Metrics API
format](https://git.k8s.io/metrics/pkg/apis/metrics/v1alpha1/types.go). The
metrics-server stores the latest values only and is not responsible for
forwarding metrics to third-party destinations.
kube-state-metrics is focused on generating completely new metrics from
Kubernetes' object state (e.g. metrics based on deployments, replica sets,
etc.). It holds an entire snapshot of Kubernetes state in memory and
continuously generates new metrics based off of it. And just like the
metrics-server it too is not responsible for exporting its metrics anywhere.
Having kube-state-metrics as a separate project also enables access to these
metrics from monitoring systems such as Prometheus.
### Horizontal sharding
In order to shard kube-state-metrics horizontally, some automated sharding capabilities have been implemented. It is configured with the following flags:
* `--shard` (zero indexed)
* `--total-shards`
Sharding is done by taking an md5 sum of the Kubernetes Object's UID and performing a modulo operation on it with the total number of shards. Each shard decides whether the object is handled by the respective instance of kube-state-metrics or not. Note that this means all instances of kube-state-metrics, even if sharded, will have the network traffic and the resource consumption for unmarshaling objects for all objects, not just the ones they are responsible for. To optimize this further, the Kubernetes API would need to support sharded list/watch capabilities. In the optimal case, memory consumption for each shard will be 1/n compared to an unsharded setup. Typically, kube-state-metrics needs to be memory and latency optimized in order for it to return its metrics rather quickly to Prometheus. One way to reduce the latency between kube-state-metrics and the kube-apiserver is to run KSM with the `--use-apiserver-cache` flag. In addition to reducing the latency, this option will also lead to a reduction in the load on etcd.
Sharding should be used carefully and additional monitoring should be set up in order to ensure that sharding is set up and functioning as expected (eg. instances for each shard out of the total shards are configured).
#### Automated sharding
Automatic sharding allows each shard to discover its nominal position when deployed in a StatefulSet which is useful for automatically configuring sharding. This is an experimental feature and may be broken or removed without notice.
To enable automated sharding, kube-state-metrics must be run by a `StatefulSet` and the pod name and namespace must be handed to the kube-state-metrics process via the `--pod` and `--pod-namespace` flags. Example manifests demonstrating the autosharding functionality can be found in [`/examples/autosharding`](./examples/autosharding).
This way of deploying shards is useful when you want to manage KSM shards through a single Kubernetes resource (a single `StatefulSet` in this case) instead of having one `Deployment` per shard. The advantage can be especially significant when deploying a high number of shards.
The downside of using an auto-sharded setup comes from the rollout strategy supported by `StatefulSet`s. When managed by a `StatefulSet`, pods are replaced one at a time with each pod first getting terminated and then recreated. Besides such rollouts being slower, they will also lead to short downtime for each shard. If a Prometheus scrape happens during a rollout, it can miss some of the metrics exported by kube-state-metrics.
### Daemonset sharding for pod metrics
For pod metrics, they can be sharded per node with the following flag:
* `--node=$(NODE_NAME)`
Each kube-state-metrics pod uses FieldSelector (spec.nodeName) to watch/list pod metrics only on the same node.
Other metrics can be sharded via [Horizontal sharding](#horizontal-sharding).
### Setup
Install this project to your `$GOPATH` using `go get`:
```bash
go get k8s.io/kube-state-metrics/v2
```
#### Building the Docker container
Simply run the following command in this root folder, which will create a
self-contained, statically-linked binary and build a Docker image:
```bash
make container
```
### Usage
Simply build and run kube-state-metrics inside a Kubernetes pod which has a
service account token that has read-only access to the Kubernetes cluster.
#### For users of prometheus-operator/kube-prometheus stack
The ([`kube-prometheus`](https://github.com/prometheus-operator/kube-prometheus/)) stack installs kube-state-metrics as one of its [components](https://github.com/prometheus-operator/kube-prometheus#kube-prometheus); you do not need to install kube-state-metrics if you're using the kube-prometheus stack.
If you want to revise the default configuration for kube-prometheus, for example to enable non-default metrics, have a look at [Customizing Kube-Prometheus](https://github.com/prometheus-operator/kube-prometheus/blob/main/docs/customizing.md).
#### Kubernetes Deployment
To deploy this project, you can simply run `kubectl apply -f examples/standard` and a Kubernetes service and deployment will be created. (Note: Adjust the apiVersion of some resource if your kubernetes cluster's version is not 1.8+, check the yaml file for more information).
To have Prometheus discover kube-state-metrics instances it is advised to create a specific Prometheus scrape config for kube-state-metrics that picks up both metrics endpoints. Annotation based discovery is discouraged as only one of the endpoints would be able to be selected, plus kube-state-metrics in most cases has special authentication and authorization requirements as it essentially grants read access through the metrics endpoint to most information available to it.
**Note:** Google Kubernetes Engine (GKE) Users - GKE has strict role permissions that will prevent the kube-state-metrics roles and role bindings from being created. To work around this, you can give your GCP identity the cluster-admin role by running the following one-liner:
```bash
kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=$(gcloud info --format='value(config.account)')
```
Note that your GCP identity is case sensitive but `gcloud info` as of Google Cloud SDK 221.0.0 is not. This means that if your IAM member contains capital letters, the above one-liner may not work for you. If you have 403 forbidden responses after running the above command and `kubectl apply -f examples/standard`, check the IAM member associated with your account at <https://console.cloud.google.com/iam-admin/iam?project=PROJECT_ID>. If it contains capital letters, you may need to set the --user flag in the command above to the case-sensitive role listed at <https://console.cloud.google.com/iam-admin/iam?project=PROJECT_ID>.
After running the above, if you see `Clusterrolebinding "cluster-admin-binding" created`, then you are able to continue with the setup of this service.
#### Healthcheck Endpoints
The following healthcheck endpoints are available (`self` refers to the telemetry port, while `main` refers to the exposition port):
* `/healthz` (exposed on `main`): Returns a 200 status code if the application is running. We recommend to use this for the startup probe.
* `/livez` (exposed on `main`): Returns a 200 status code if the application is not affected by an outage of the Kubernetes API Server. We recommend to using this for the liveness probe.
* `/readyz` (exposed on `self`): Returns a 200 status code if the application is ready to accept requests and expose metrics. We recommend using this for the readiness probe.
Note that it is discouraged to use the telemetry metrics endpoint for any probe when proxying the exposition data.
#### Limited privileges environment
If you want to run kube-state-metrics in an environment where you don't have cluster-reader role, you can:
* give it `view` privileges on specific namespaces (using roleBinding) (*note: you can add this roleBinding to all the NS you want your serviceaccount to access*)
* then specify a set of namespaces (using the `--namespaces` option) and a set of kubernetes objects (using the `--resources`) that your serviceaccount has access to in the `kube-state-metrics` deployment configuration
```yaml
spec:
template:
spec:
containers:
- name: kube-state-metrics
args:
- '--resources=pods'
- '--namespaces=project1'
```
For the full list of arguments available, see the documentation in [docs/developer/cli-arguments.md](./docs/developer/cli-arguments.md)
#### Helm Chart
Starting from the kube-state-metrics chart `v2.13.3` (kube-state-metrics image `v1.9.8`), the official [Helm chart](https://artifacthub.io/packages/helm/prometheus-community/kube-state-metrics/) is maintained in [prometheus-community/helm-charts](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-state-metrics). Starting from kube-state-metrics chart `v3.0.0` only kube-state-metrics images of `v2.0.0 +` are supported.
#### Development
When developing, test a metric dump against your local Kubernetes cluster by running:
> Users can override the apiserver address in KUBE-CONFIG file with `--apiserver` command line.
To run the e2e tests locally see the documentation in [tests/README.md](./tests/README.md).
#### Developer Contributions
When developing, there are certain code patterns to follow to better your contributing experience and likelihood of e2e and other ci tests to pass. To learn more about them, see the documentation in [docs/developer/guide.md](./docs/developer/guide.md).
#### Community
This project is sponsored by [SIG Instrumentation](https://github.com/kubernetes/community/tree/master/sig-instrumentation).
There is also a channel for [#kube-state-metrics](https://kubernetes.slack.com/archives/CJJ529RUY) on Kubernetes' Slack.
You can also join the SIG Instrumentation [mailing list](https://groups.google.com/forum/#!forum/kubernetes-sig-instrumentation).
This will typically add invites for the following meetings to your calendar, in which topics around kube-state-metrics can be discussed.
* Regular SIG Meeting: [Thursdays at 9:30 PT (Pacific Time)](https://zoom.us/j/5342565819?pwd=RlVsK21NVnR1dmE3SWZQSXhveHZPdz09) (biweekly). [Convert to your timezone](http://www.thetimezoneconverter.com/?t=9:30&tz=PT%20%28Pacific%20Time%29).
* Regular Triage Meeting: [Thursdays at 9:30 PT (Pacific Time)](https://zoom.us/j/5342565819?pwd=RlVsK21NVnR1dmE3SWZQSXhveHZPdz09) (biweekly - alternating with regular meeting). [Convert to your timezone](http://www.thetimezoneconverter.com/?t=9:30&tz=PT%20%28Pacific%20Time%29).
@ -6,33 +6,40 @@ We use [Semantic Versioning](http://semver.org/).
We maintain a separate branch for each minor release, named `release-<major>.<minor>`, e.g. `release-1.1`, `release-2.0`.
The usual flow is to merge new features and changes into the master branch and to merge bug fixes into the latest release branch. Bug fixes are then merged into master from the latest release branch. The master branch should always contain all commits from the latest release branch.
The usual flow is to merge new features and changes into the main branch and to merge bug fixes into the latest release branch. Bug fixes are then merged into main from the latest release branch. The main branch should always contain all commits from the latest release branch.
If a bug fix got accidentally merged into master, cherry-pick commits have to be created in the latest release branch, which then have to be merged back into master. Try to avoid that situation.
If a bug fix got accidentally merged into main, cherry-pick commits have to be created in the latest release branch, which then have to be merged back into main. Try to avoid that situation.
Maintaining the release branches for older minor releases happens on a best effort basis.
## Prepare your release
* Bump the version in the `VERSION` file in the root of the repository.
* Update the [data.yaml](data.yaml)
* Update the compat list
* Update the version key to refer to your new release
* Run `make examples`, which will re-generate all example manifests to use the new version.
* Run `make generate`, which will update the compatibility matrix in README.md
* Changelog entry
* Only include user relevant changes
* Entries in the [`CHANGELOG.md`](CHANGELOG.md) are meant to be in this order:
```
```text
[CHANGE]
[FEATURE]
[ENHANCEMENT]
[BUGFIX]
```
* All lines should be full sentences
* kube-state-metrics image tag used in Kubernetes deployment yaml config.
* Cut the new release branch, i.e., `release-1.2`, or merge/cherry-pick changes onto the minor release branch you intend to tag the release on
* Cut the new release tag, i.e., `v1.2.0-rc.0`
* Cut the new release branch, e.g. `release-1.2`, or merge/cherry-pick changes onto the minor release branch you intend to tag the release on
* Cut the new release tag, e.g. `v1.2.0-rc.0`
* Create a new **pre-release** on github
* New images are automatically built and pushed to `gcr.io/k8s-staging-kube-state-metrics/kube-state-metrics`
* Promote image by sending a PR to [kubernetes/k8s.io](https://github.com/kubernetes/k8s.io) repo. Follow the [example PR](https://github.com/kubernetes/k8s.io/pull/1260).
* Promote image by sending a PR to [kubernetes/k8s.io](https://github.com/kubernetes/k8s.io) repository. Follow the [example PR](https://github.com/kubernetes/k8s.io/pull/3798). Use [kpromo pr](https://github.com/kubernetes-sigs/promo-tools/blob/main/docs/promotion-pull-requests.md) to update the manifest files in this repository, e.g. `kpromo pr --fork=$YOURNAME -i --project=kube-state-metrics -t=v2.5.0`
* Create a PR to merge the changes of this release back into the main branch.
* Once the PR to promote the image is merged, mark the pre-release as a regular release.
Detects vulnerabilities as a result of the affected call-paths being invoked directly in the repository, while reducing false positives by ignoring dormant call-paths for package dependencies.
_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._
### From stable/kube-state-metrics
You can upgrade in-place:
1. [get repo info](#get-repo-info)
1. [upgrade](#upgrading-chart) your existing release name using the new chart repo
## Configuration
See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments:
```console
helm show values kube-state-metrics/kube-state-metrics
```
You may also `helm show values` on this chart's [dependencies](#dependencies) for additional options.
# This is an experimental feature and there are no stability guarantees.
autosharding:
enabled:false
replicas:1
# List of additional cli arguments to configure kube-state-metrics
# for example: --enable-gzip-encoding, --log-file, etc.
# all the possible args can be found here: https://github.com/kubernetes/kube-state-metrics/blob/master/docs/cli-arguments.md
extraArgs:[]
service:
port:8080
# Default to clusterIP for backward compatibility
type:ClusterIP
nodePort:0
loadBalancerIP:""
annotations:{}
customLabels:{}
hostNetwork:false
rbac:
# If true, create & use RBAC resources
create:true
# Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to it, rolename set here.
# useExistingRole: your-existing-role
# If set to false - Run without Cluteradmin privs needed - ONLY works if namespace is also set (if useExistingRole is set this name is used as ClusterRole or Role to bind to)
useClusterRole:true
serviceAccount:
# Specifies whether a ServiceAccount should be created, require rbac true
create:true
# The name of the ServiceAccount to use.
# If not set and create is true, a name is generated using the fullname template
name:
# Reference to one or more secrets to be used when pulling images
@ -6,10 +6,10 @@ Any contribution to improving this documentation or adding sample usages will be
## Table of Contents
- [Metrics Stages](#metrics-stages)
- [Exposed Metrics](#exposed-metrics)
- [Join Metrics](#join-metrics)
- [CLI arguments](#cli-arguments)
* [Metrics Stages](#metrics-stages)
* [Exposed Metrics](#exposed-metrics)
* [Join Metrics](#join-metrics)
* [CLI arguments](#cli-arguments)
## Metrics Stages
@ -21,39 +21,55 @@ Stages about metrics are grouped into three categories:
| STABLE | Metrics which should have very few backwards-incompatible changes outside of major version updates. |
| DEPRECATED | Metrics which will be removed once the deprecation timeline is met. |
## Opt-in Metrics
As of v2.3.0, kube-state-metrics supports additional opt-in metrics via the CLI flag `--metric-opt-in-list`. See the metric documentation to identify which metrics need to be specified.
## Exposed Metrics
Per group of metrics there is one file for each metrics. See each file for specific documentation about the exposed metrics:
Per group of metrics there is one file for each metrics.
See each file for specific documentation about the exposed metrics:
@ -63,17 +79,67 @@ can be used to extend single metrics output.
This example adds `label_release` to the set of default labels of the `kube_pod_status_ready` metric
and allows you select or group the metrics by Helm release label:
```
```promql
kube_pod_status_ready * on (namespace, pod) group_left(label_release) kube_pod_labels
```
Another useful example would be to query the memory usage of pods by its `phase`, such as `Running`:
```
```promql
sum(kube_pod_container_resource_requests{resource="memory"}) by (namespace, pod, node)
* on (namespace, pod) group_left() (sum(kube_pod_status_phase{phase="Running"}) by (pod, namespace) == 1)
```
## Metrics from Custom Resources
See [Custom Resource State Metrics](metrics/extend/customresourcestate-metrics.md) for experimental support for custom resources.
## CLI Arguments
Additionally, options for `kube-state-metrics` can be passed when executing as a CLI, or in a kubernetes / openshift environment. More information can be found here: [CLI Arguments](cli-arguments.md)
Additionally, options for `kube-state-metrics` can be passed when executing as a CLI, or in a kubernetes / openshift environment. More information can be found here: [CLI Arguments](developer/cli-arguments.md)
## Protecting /metrics endpoints
Kube-State-Metrics' metrics can contain sensitive information about the state of the cluster, which you as an operator might want to additionally protect from unauthorized access.
In order to achieve this, you need to enable the `--auth-filter` flag on kube-state-metrics.
With this, kube-state-metrics will only accept authenticated and authorized requests to the /metrics endpoints.
Kube-state-metrics uses Kubernetes' RBAC mechanisms for this, so this means that every scrape will trigger a request against the API Server for TokenReview and SubjectAccessReview.
The clients scraping the endpoint, need to use a token which can be provided by a ServiceAccount that can be set up the following way:
A ClusterRole providing access like this:
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: metrics-reader
rules:
- nonResourceURLs:
- "/metrics"
verbs:
- get
```
and a matching ClusterRoleBinding
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: metrics-reader-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: metrics-reader
subjects:
- kind: ServiceAccount
name: YOUR_SERVICE_ACCOUNT
namespace: NAMESPACE_OF_THE_SERVICE_ACCOUNT
```
Your client can then use either this ServiceAccount to gather metrics or you can create a token, that can be used to fetch data like this:
Or configured in the `args` section of your deployment configuration in a Kubernetes / Openshift context:
```yaml
spec:
template:
spec:
containers:
- args:
- '--telemetry-port=8081'
- '--kubeconfig=<KUBE-CONFIG>'
- '--apiserver=<APISERVER>'
```
## Available options:
[embedmd]:# (../help.txt)
```txt
$ kube-state-metrics -h
Usage of ./kube-state-metrics:
--add_dir_header If true, adds the file directory to the header of the log messages
--alsologtostderr log to standard error as well as files
--apiserver string The URL of the apiserver to use as a master
--enable-gzip-encoding Gzip responses when requested by clients via 'Accept-Encoding: gzip' header.
-h, --help Print Help text
--host string Host to expose metrics on. (default "::")
--kubeconfig string Absolute path to the kubeconfig file
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0)
--log_dir string If non-empty, write log files in this directory
--log_file string If non-empty, use this log file
--log_file_max_size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800)
--logtostderr log to standard error instead of files (default true)
--metric-allowlist string Comma-separated list of metrics to be exposed. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive.
--metric-denylist string Comma-separated list of metrics not to be enabled. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive.
--metric-labels-allowlist string Comma-separated list of additional Kubernetes label keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional labels provide a list of resource names in their plural form and Kubernetes label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'
--namespaces string Comma-separated list of namespaces to be enabled. Defaults to ""
--one_output If true, only write logs to their native severity level (vs also writing to each lower severity level)
--pod string Name of the pod that contains the kube-state-metrics container. When set, it is expected that --pod and --pod-namespace are both set. Most likely this should be passed via the downward API. This is used for auto-detecting sharding. If set, this has preference over statically configured sharding. This is experimental, it may be removed without notice.
--pod-namespace string Name of the namespace of the pod specified by --pod. When set, it is expected that --pod and --pod-namespace are both set. Most likely this should be passed via the downward API. This is used for auto-detecting sharding. If set, this has preference over statically configured sharding. This is experimental, it may be removed without notice.
--port int Port to expose metrics on. (default 8080)
--resources string Comma-separated list of Resources to be enabled. Defaults to "certificatesigningrequests,configmaps,cronjobs,daemonsets,deployments,endpoints,horizontalpodautoscalers,ingresses,jobs,leases,limitranges,mutatingwebhookconfigurations,namespaces,networkpolicies,nodes,persistentvolumeclaims,persistentvolumes,poddisruptionbudgets,pods,replicasets,replicationcontrollers,resourcequotas,secrets,services,statefulsets,storageclasses,validatingwebhookconfigurations,volumeattachments"
--shard int32 The instances shard nominal (zero indexed) within the total number of shards. (default 0)
--skip_headers If true, avoid header prefixes in the log messages
--skip_log_headers If true, avoid headers when opening log files
--stderrthreshold severity logs at or above this threshold go to stderr (default 2)
--telemetry-host string Host to expose kube-state-metrics self metrics on. (default "::")
--telemetry-port int Port to expose kube-state-metrics self metrics on. (default 8081)
--tls-config string Path to the TLS configuration file
--total-shards int The total number of shards. Sharding is disabled when total shards is set to 1. (default 1)
-v, --v Level number for the log level verbosity
--version kube-state-metrics build version information
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
This policy describes how kube-state-metrics maintainers consume third-party packages.
## Scope
This policy applies to all kube-state-metrics maintainers and all third-party packages used in the kube-state-metrics project.
## Policy
kube-state-metrics maintainers must follow these guidelines when consuming third-party packages:
* Only use third-party packages that are necessary for the functionality of kube-state-metrics.
* Use the latest version of all third-party packages whenever possible.
* Avoid using third-party packages that are known to have security vulnerabilities.
* Pin all third-party packages to specific versions in the kube-state-metrics codebase.
* Use a dependency management tool, such as Go modules, to manage third-party dependencies.
## Procedure
When adding a new third-party package to kube-state-metrics, maintainers must follow these steps:
1. Evaluate the need for the package. Is it necessary for the functionality of kube-state-metrics?
2. Research the package. Is it actively maintained? Does it have a good reputation?
3. Choose a version of the package. Use the latest version whenever possible.
4. Pin the package to the specific version in the kube-state-metrics codebase.
5. Update the kube-state-metrics documentation to reflect the new dependency.
## Enforcement
This policy is enforced by the kube-state-metrics maintainers.
Maintainers are expected to review each other's code changes to ensure that they comply with this policy.
## Exceptions
Exceptions to this policy may be granted by the kube-state-metrics project owners on a case-by-case basis.
## Credits
This policy was adapted from Kubescape's [Environment Dependencies Policy](https://github.com/kubescape/kubescape/blob/master/docs/environment-dependencies-policy.md).
Kube-State-Metrics' goal is to provide insights into the state of Kubernetes objects by exposing them as metrics.
This document provides guidelines with the goal to create a good user experience when using these metrics.
Please be aware that this document is introduced in a later stage of the project and there might be metrics that do not follow these best practices.
Feel encouraged to report these metrics and provide a pull request to improve them.
## General best practices
We follow [Prometheus](https://prometheus.io/docs/practices/naming/) best practices in terms of naming and labeling.
## Best practices for kube-state-metrics
### Avoid pre-computation
kube-state-metrics should expose metrics on an individual object level and avoid any sort of pre-computation unless it is required due to for example high cardinality on objects.
We prefer not to add metrics that can be derived from existing raw metrics. For example, we would not want to expose a metric called `kube_pod_total` as it can be computed with `count(kube_pod_info)`.
This way kube-state-metrics allows the user to have full control on how they want to use the metrics and gives them flexibility to do specific computation.
### Static object properties
An object usually has a stable set of properties that do not change during its lifecycle in Kubernetes.
This includes properties like name, namespace, uid etc. that have a 1:1 relationship with the object.
It is a good practice to group those together into an `_info` metric.
If there is a 1:n relationship (e.g. a list of ports), it should be in a separate metric to avoid generating too many metrics.
### Dynamic object properties
An object can also have a dynamic set of properties, which are usually part of the status field.
These change during the lifecycle of the object.
For example a pod can be in different states like "Pending", "Running" etc.
These should be part of a "State Set" that includes labels that identify the object as well as the dynamic property.
### Linked properties
If an object contains a substructure that links multiple properties together (e.g. endpoint address and port), those should be reported in the same metric.
### Optional properties
Some Kubernetes objects have optional fields. In case there is an optional value, the label should still be exposed, ideally as an empty string.
### Timestamps
Timestamps like creation time or modification time should be exposed as a value. The metric should end with `_timestamp_seconds`. The date value is represented in [UNIX epoch seconds](https://en.wikipedia.org/wiki/Unix_time).
### Cardinality
Some object properties can cause cardinality issues if they can contain a lot of different values or are linked together with multiple properties that also can change a lot.
In this case it is better to limit the number of values that can be exposed within kube-state-metrics by allowing only a few of them and have a default for others.
If for example the Kubernetes object contains a status field that contains an error message that can change a lot, it would be better to have a boolean `error="true"` label in case there is an error.
If there are some error messages that are worth exposing, those could be exposed and for any other message, a default value could be provided.
## Stability
We follow the stability framework derived from Kubernetes, in which we expose experimental and stable metrics.
Experimental metrics are recently introduced or expose alpha/beta resources in the Kubernetes API.
They can change anytime and should be used with caution.
They can be promoted to a stable metric once the object stabilized in the Kubernetes API or they were part of two consecutive releases and haven't observed any changes in them.
Stable metrics are considered frozen with the exception of new labels being added.
A stable metric or a label on a stable metric can be deprecated in release Major.Minor and the earliest point it will be removed is the release Major.Minor+2.
kube-state-metrics is a simple service that listens to the Kubernetes API server and generates metrics about the state of the objects.
Usage:
kube-state-metrics [flags]
kube-state-metrics [command]
Available Commands:
completion Generate completion script for kube-state-metrics.
help Help about any command
version Print version information.
Flags:
--add_dir_header If true, adds the file directory to the header of the log messages
--alsologtostderr log to standard error as well as files (no effect when -logtostderr=true)
--apiserver string The URL of the apiserver to use as a master
--auth-filter If true, requires authentication and authorization through Kubernetes API to access metrics endpoints
--auto-gomemlimit Automatically set GOMEMLIMIT to match container or system memory limit. (experimental)
--auto-gomemlimit-ratio float The ratio of reserved GOMEMLIMIT memory to the detected maximum container or system memory. (experimental) (default 0.9)
--config string Path to the kube-state-metrics options config YAML file. If this flag is set, the flags defined in the file override the command line flags.
--custom-resource-state-config string Inline Custom Resource State Metrics config YAML (experimental)
--custom-resource-state-config-file string Path to a Custom Resource State Metrics config file (experimental)
--custom-resource-state-only Only provide Custom Resource State metrics (experimental)
--enable-gzip-encoding Gzip responses when requested by clients via 'Accept-Encoding: gzip' header.
-h, --help Print Help text
--host string Host to expose metrics on. (default "::")
--kubeconfig string Absolute path to the kubeconfig file
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0)
--log_dir string If non-empty, write log files in this directory (no effect when -logtostderr=true)
--log_file string If non-empty, use this log file (no effect when -logtostderr=true)
--log_file_max_size uint Defines the maximum size a log file can grow to (no effect when -logtostderr=true). Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800)
--logtostderr log to standard error instead of files (default true)
--metric-allowlist string Comma-separated list of metrics to be exposed. This list comprises of exact metric names and/or *ECMAScript-based* regex patterns. The allowlist and denylist are mutually exclusive.
--metric-annotations-allowlist string Comma-separated list of Kubernetes annotations keys that will be used in the resource' labels metric. By default the annotations metrics are not exposed. To include them, provide a list of resource names in their plural form and Kubernetes annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. A single '*' can be provided per resource instead to allow any annotations, but that has severe performance implications (Example: '=pods=[*]').
--metric-denylist string Comma-separated list of metrics not to be enabled. This list comprises of exact metric names and/or *ECMAScript-based* regex patterns. The allowlist and denylist are mutually exclusive.
--metric-labels-allowlist string Comma-separated list of additional Kubernetes label keys that will be used in the resource' labels metric. By default the labels metrics are not exposed. To include them, provide a list of resource names in their plural form and Kubernetes label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any labels, but that has severe performance implications (Example: '=pods=[*]'). Additionally, an asterisk (*) can be provided as a key, which will resolve to all resources, i.e., assuming '--resources=deployments,pods', '=*=[*]' will resolve to '=deployments=[*],pods=[*]'.
--metric-opt-in-list string Comma-separated list of metrics which are opt-in and not enabled by default. This is in addition to the metric allow- and denylists
--namespaces string Comma-separated list of namespaces to be enabled. Defaults to ""
--namespaces-denylist string Comma-separated list of namespaces not to be enabled. If namespaces and namespaces-denylist are both set, only namespaces that are excluded in namespaces-denylist will be used.
--node string Name of the node that contains the kube-state-metrics pod. Most likely it should be passed via the downward API. This is used for daemonset sharding. Only available for resources (pod metrics) that support spec.nodeName fieldSelector. This is experimental.
--object-limit int The total number of objects to list per resource from the API Server. (experimental)
--one_output If true, only write logs to their native severity level (vs also writing to each lower severity level; no effect when -logtostderr=true)
--pod string Name of the pod that contains the kube-state-metrics container. When set, it is expected that --pod and --pod-namespace are both set. Most likely this should be passed via the downward API. This is used for auto-detecting sharding. If set, this has preference over statically configured sharding. This is experimental, it may be removed without notice.
--pod-namespace string Name of the namespace of the pod specified by --pod. When set, it is expected that --pod and --pod-namespace are both set. Most likely this should be passed via the downward API. This is used for auto-detecting sharding. If set, this has preference over statically configured sharding. This is experimental, it may be removed without notice.
--port int Port to expose metrics on. (default 8080)
--resources string Comma-separated list of Resources to be enabled. Defaults to "certificatesigningrequests,configmaps,cronjobs,daemonsets,deployments,endpoints,horizontalpodautoscalers,ingresses,jobs,leases,limitranges,mutatingwebhookconfigurations,namespaces,networkpolicies,nodes,persistentvolumeclaims,persistentvolumes,poddisruptionbudgets,pods,replicasets,replicationcontrollers,resourcequotas,secrets,services,statefulsets,storageclasses,validatingwebhookconfigurations,volumeattachments"
--server-idle-timeout duration The maximum amount of time to wait for the next request when keep-alives are enabled. Align with the idletimeout of your scrape clients. (default 5m0s)
--server-read-header-timeout duration The maximum duration for reading the header of requests. (default 5s)
--server-read-timeout duration The maximum duration for reading the entire request, including the body. Align with the scrape interval or timeout of scraping clients. (default 1m0s)
--server-write-timeout duration The maximum duration before timing out writes of the response. Align with the scrape interval or timeout of scraping clients.. (default 1m0s)
--shard int32 The instances shard nominal (zero indexed) within the total number of shards. (default 0)
--skip_headers If true, avoid header prefixes in the log messages
--skip_log_headers If true, avoid headers when opening log files (no effect when -logtostderr=true)
--stderrthreshold severity logs at or above this threshold go to stderr when writing to files and stderr (no effect when -logtostderr=true or -alsologtostderr=true) (default 2)
--telemetry-host string Host to expose kube-state-metrics self metrics on. (default "::")
--telemetry-port int Port to expose kube-state-metrics self metrics on. (default 8081)
--tls-config string Path to the TLS configuration file
--total-shards int The total number of shards. Sharding is disabled when total shards is set to 1. (default 1)
--track-unscheduled-pods This configuration is used in conjunction with node configuration. When this configuration is true, node configuration is empty and the metric of unscheduled pods is fetched from the Kubernetes API Server. This is experimental.
--use-apiserver-cache Sets resourceVersion=0 for ListWatch requests, using cached resources from the apiserver instead of an etcd quorum read.
-v, --v Level number for the log level verbosity
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
Use "kube-state-metrics [command] --help" for more information about a command.
This developer guide documentation is intended to assist all contributors in various code contributions.
Any contribution to improving this documentation will be appreciated.
## Table of Contents
- [Add New Kubernetes Resource Metric Collector](#add-new-kubernetes-resource-metric-collector)
* [Add New Kubernetes Resource Metric Collector](#add-new-kubernetes-resource-metric-collector)
* [Add New Metrics](#add-new-metrics)
### Add New Kubernetes Resource Metric Collector
The following steps are needed to introduce a new resource and its respective resource metrics.
- Reference your new resource(s) to the [docs/README.md](https://github.com/kubernetes/kube-state-metrics/blob/master/docs/README.md#exposed-metrics).
- Reference your new resource(s) in the [docs/cli-arguments.md](https://github.com/kubernetes/kube-state-metrics/blob/master/docs/cli-arguments.md#available-options) as part of the `--resources` flag.
- Create a new `<name-of-resource>.md` in the [docs](https://github.com/kubernetes/kube-state-metrics/tree/master/docs) directory to provide documentation on the resource(s) and metrics you implemented. Follow the formatting of all other resources.
- Add the resource(s) you are representing to the [examples/standard/cluster-role.yaml](https://github.com/kubernetes/kube-state-metrics/blob/master/examples/standard/cluster-role.yaml) under the appropriate `apiGroup` using the `verbs`: `list` and `watch`.
- Reference and add build functions for the new resource(s) in [internal/store/builder.go](https://github.com/kubernetes/kube-state-metrics/blob/master/internal/store/builder.go).
- Reference the new resource in [pkg/options/resource.go](https://github.com/kubernetes/kube-state-metrics/blob/master/pkg/options/resource.go).
- Add a sample Kubernetes manifest to be used by tests in the [tests/manifests/](https://github.com/kubernetes/kube-state-metrics/tree/master/tests/manifests) directory.
- Lastly, and most importantly, actually implement your new resource(s) and its test binary in [internal/store](https://github.com/kubernetes/kube-state-metrics/tree/master/internal/store). Follow the formatting and structure of other resources.
* Reference your new resource(s) to the [docs/README.md](./../README.md#exposed-metrics).
* Reference your new resource(s) in the [docs/developer/cli-arguments.md](./cli-arguments.md#available-options) as part of the `--resources` flag.
* Create a new `<name-of-resource>.md` in the [docs](./../docs) directory to provide documentation on the resource(s) and metrics you implemented. Follow the formatting of all other resources.
* Add the resource(s) you are representing to the [jsonnet/kube-state-metrics/kube-state-metrics.libsonnet](./../../jsonnet/kube-state-metrics/kube-state-metrics.libsonnet) under the appropriate `apiGroup` using the `verbs`: `list` and `watch`.
* Run `make examples/standard`, this should re-generate [examples/standard/cluster-role.yaml](./../../examples/standard/cluster-role.yaml) with the resource(s) added to [jsonnet/kube-state-metrics/kube-state-metrics.libsonnet](./../../jsonnet/kube-state-metrics/kube-state-metrics.libsonnet).
* Reference and add build functions for the new resource(s) in [internal/store/builder.go](./../../internal/store/builder.go).
* Reference the new resource in [pkg/options/resource.go](./../../pkg/options/resource.go).
* Add a sample Kubernetes manifest to be used by tests in the [tests/manifests/](./../../tests/manifests) directory.
* Lastly, and most importantly, actually implement your new resource(s) and its test binary in [internal/store](./../../internal/store). Follow the formatting and structure of other resources.
### Add New Metrics
* Make metrics experimental first when introducing them, refer [#1910](https://github.com/kubernetes/kube-state-metrics/pull/1910) for more information.
| kube_ingress_path | Gauge | `ingress`=<ingress-name><br>`namespace`=<ingress-namespace><br>`host`=<ingress-host><br>`path`=<ingress-path><br>`service_name`=<service name for the path><br>`service_port`=<service port for the path> | STABLE |
| kube_serviceaccount_info | Gauge | Information about a service account | | `namespace`=<serviceaccount-namespace><br>`serviceaccount`=<serviceaccount-name><br>`uid`=<serviceaccount-uid><br>`automount_token`=<serviceaccount-automount-token> | EXPERIMENTAL |
| kube_serviceaccount_secret | Gauge | Secret being referenced by a service account | | `namespace`=<serviceaccount-namespace><br>`serviceaccount`=<serviceaccount-name><br>`uid`=<serviceaccount-uid><br>`name`=<secret-name> | EXPERIMENTAL |
| kube_serviceaccount_image_pull_secret | Gauge | Secret being referenced by a service account for the purpose of pulling images | | `namespace`=<serviceaccount-namespace><br>`serviceaccount`=<serviceaccount-name><br>`uid`=<serviceaccount-uid><br>`name`=<secret-name> | EXPERIMENTAL |
| kube_serviceaccount_annotations | Gauge | Kubernetes annotations converted to Prometheus labels controlled via [--metric-annotations-allowlist](../../developer/cli-arguments.md) | | `namespace`=<serviceaccount-namespace><br>`serviceaccount`=<serviceaccount-name><br>`uid`=<serviceaccount-uid><br>`annotation_SERVICE_ACCOUNT_ANNOTATION`=<SERVICE_ACCOUNT_ANNOTATION> | EXPERIMENTAL |
| kube_serviceaccount_labels | Gauge | Kubernetes labels converted to Prometheus labels controlled via [--metric-labels-allowlist](../../developer/cli-arguments.md) | | `namespace`=<serviceaccount-namespace><br>`serviceaccount`=<serviceaccount-name><br>`uid`=<serviceaccount-uid><br>`label_SERVICE_ACCOUNT_LABEL`=<SERVICE_ACCOUNT_LABEL> | EXPERIMENTAL |
| kube_node_annotations | Gauge | Kubernetes annotations converted to Prometheus labels controlled via [--metric-annotations-allowlist](../../developer/cli-arguments.md) | | `node`=<node-address><br>`annotation_NODE_ANNOTATION`=<NODE_ANNOTATION> | EXPERIMENTAL |
| kube_node_info | Gauge | Information about a cluster node | | `node`=<node-address><br>`kernel_version`=<kernel-version><br>`os_image`=<os-image-name><br>`container_runtime_version`=<container-runtime-and-version-combination><br>`kubelet_version`=<kubelet-version><br>`kubeproxy_version`=<deprecated><br>`pod_cidr`=<pod-cidr><br>`provider_id`=<provider-id><br>`system_uuid`=<system-uuid><br>`internal_ip`=<internal-ip> | STABLE |
| kube_node_labels | Gauge | Kubernetes labels converted to Prometheus labels controlled via [--metric-labels-allowlist](../../developer/cli-arguments.md) | | `node`=<node-address><br>`label_NODE_LABEL`=<NODE_LABEL> | STABLE |
| kube_node_role | Gauge | The role of a cluster node | | `node`=<node-address><br>`role`=<NODE_ROLE> | EXPERIMENTAL |
| kube_node_spec_unschedulable | Gauge | Whether a node can schedule new pods | | `node`=<node-address> | STABLE |
| kube_node_spec_taint | Gauge | The taint of a cluster node. | | `node`=<node-address><br>`key`=<taint-key><br>`value=`<taint-value><br>`effect=`<taint-effect> | STABLE |
| kube_node_status_capacity | Gauge | The total amount of resources available for a node | `cpu`=<core><br>`ephemeral_storage`=<byte><br>`pods`=<integer><br>`attachable_volumes_*`=<byte><br>`hugepages_*`=<byte><br>`memory`=<byte> | `node`=<node-address><br>`resource`=<resource-name><br>`unit`=<resource-unit> | STABLE |
| kube_node_status_addresses | Gauge | The addresses of a node | | `node`=<node-address><br>`type`=<address-type><br>`address`=<address-value> | EXPERIMENTAL |
| kube_node_status_allocatable | Gauge | The amount of resources allocatable for pods (after reserving some for system daemons) | `cpu`=<core><br>`ephemeral_storage`=<byte><br>`pods`=<integer><br>`attachable_volumes_*`=<byte><br>`hugepages_*`=<byte><br>`memory`=<byte> | `node`=<node-address><br>`resource`=<resource-name><br>`unit`=<resource-unit> | STABLE |
| kube_node_status_condition | Gauge | The condition of a cluster node | | `node`=<node-address><br>`condition`=<node-condition><br>`status`=<true\|false\|unknown> | STABLE |
If both flags are provided, the inline configuration will take precedence.
When multiple entries for the same resource exist, kube-state-metrics will exit with an error.
This includes configuration which refers to a different API version.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: kube-state-metrics
namespace: kube-system
spec:
template:
spec:
containers:
- name: kube-state-metrics
args:
- --custom-resource-state-config
# in YAML files, | allows a multi-line string to be passed as a flag value
# see https://yaml-multiline.info
- |
kind: CustomResourceStateMetrics
spec:
resources:
- groupVersionKind:
group: myteam.io
version: "v1"
kind: Foo
metrics:
- name: active_count
help: "Count of active Foo"
each:
type: Gauge
...
```
It's also possible to configure kube-state-metrics to run in a `custom-resource-mode` only. In addition to specifying one of `--custom-resource-state-config*` flags, you could set `--custom-resource-state-only` to `true`.
With this configuration only the known custom resources configured in `--custom-resource-state-config*` will be taken into account by kube-state-metrics.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: kube-state-metrics
namespace: kube-system
spec:
template:
spec:
containers:
- name: kube-state-metrics
args:
- --custom-resource-state-config
# in YAML files, | allows a multi-line string to be passed as a flag value
# see https://yaml-multiline.info
- |
kind: CustomResourceStateMetrics
spec:
resources:
- groupVersionKind:
group: myteam.io
version: "v1"
kind: Foo
metrics:
- name: active_count
help: "Count of active Foo"
each:
type: Gauge
...
- --custom-resource-state-only=true
```
NOTE: The `customresource_group`, `customresource_version`, and `customresource_kind` common labels are reserved, and will be overwritten by the values from the `groupVersionKind` field.
### RBAC-enabled Clusters
Please be aware that kube-state-metrics needs list and watch permissions granted to `customresourcedefinitions.apiextensions.k8s.io` as well as to the resources you want to gather metrics from.
### Examples
The examples in this section will use the following custom resource:
# HELP kube_customresource_verticalpodautoscaler_status_recommendation_containerrecommendations_lowerbound Minimum memory resources the container can use before the VerticalPodAutoscaler updater evicts it.
# TYPE kube_customresource_verticalpodautoscaler_status_recommendation_containerrecommendations_lowerbound gauge
# HELP kube_customresource_verticalpodautoscaler_status_recommendation_containerrecommendations_lowerbound Minimum cpu resources the container can use before the VerticalPodAutoscaler updater evicts it.
# TYPE kube_customresource_verticalpodautoscaler_status_recommendation_containerrecommendations_lowerbound gauge
In v2.9.0 the `vericalpodautoscalers` resource was removed from the list of default resources. In order to generate metrics for `verticalpodautoscalers`, you can use the following Custom Resource State config:
```yaml
# Using --resource=verticalpodautoscalers, we get the following output:
# HELP kube_verticalpodautoscaler_annotations Kubernetes annotations converted to Prometheus labels.
# TYPE kube_verticalpodautoscaler_annotations gauge
The above configuration was tested on [this](https://github.com/kubernetes/autoscaler/blob/master/vertical-pod-autoscaler/examples/hamster.yaml) VPA configuration, with an added annotation (`foo: 123`).
#### All VerticalPodAutoscaler Metrics
As an addition for the above configuration, here's the complete `CustomResourceStateMetrics` spec to re-enable all of the VPA metrics which are removed from the list of the default resources:
<details>
<summary>VPA CustomResourceStateMetrics</summary>
```yaml
kind: CustomResourceStateMetrics
spec:
resources:
- groupVersionKind:
group: autoscaling.k8s.io
kind: "VerticalPodAutoscaler"
version: "v1"
labelsFromPath:
namespace: [metadata, namespace]
target_api_version: [spec, targetRef, apiVersion]
target_kind: [spec, targetRef, kind]
target_name: [spec, targetRef, name]
verticalpodautoscaler: [metadata, name]
metricNamePrefix: "kube"
metrics:
# kube_verticalpodautoscaler_annotations
- name: "verticalpodautoscaler_annotations"
help: "Kubernetes annotations converted to Prometheus labels."
each:
type: Info
info:
labelsFromPath:
annotation_*: [metadata, annotations]
name: [metadata, name]
# kube_verticalpodautoscaler_labels
- name: "verticalpodautoscaler_labels"
help: "Kubernetes labels converted to Prometheus labels."
The configuration supports three kind of metrics from the [OpenMetrics specification](https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md).
The metric type is specified by the `type` field and its specific configuration at the types specific struct.
#### Gauge
> Gauges are current measurements, such as bytes of memory currently used or the number of items in a queue. For gauges the absolute value is what is of interest to a user. [[0]](https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#gauge)
Gauges produce values of type float64 but custom resources can be of all kinds of types.
Kube-state-metrics performs implicit type conversions for a lot of type.
Supported types are:
* (u)int32/64, int, float32 and byte are cast to float64
* `nil` is generally mapped to `0.0` if NilIsZero is `true`, otherwise it will throw an error
* for bool `true` is mapped to `1.0` and `false` is mapped to `0.0`
* for string the following logic applies
* `"true"` and `"yes"` are mapped to `1.0`, `"false"`, `"no"` and `"unknown"` are mapped to `0.0` (all case-insensitive)
* RFC3339 times are parsed to float timestamp
* Quantities like "250m" or "512Gi" are parsed to float using <https://github.com/kubernetes/apimachinery/blob/master/pkg/api/resource/quantity.go>
* Percentages ending with a "%" are parsed to float
* finally the string is parsed to float using <https://pkg.go.dev/strconv#ParseFloat> which should support all common number formats. If that fails an error is yielded
##### Example for status conditions on Kubernetes Controllers
```yaml
kind: CustomResourceStateMetrics
spec:
resources:
- groupVersionKind:
group: myteam.io
kind: "Foo"
version: "v1"
labelsFromPath:
name:
- metadata
- name
namespace:
- metadata
- namespace
metrics:
- name: "foo_status"
help: "status condition "
each:
type: Gauge
gauge:
path: [status, conditions]
labelsFromPath:
type: ["type"]
valueFrom: ["status"]
```
This will work for kubernetes controller CRs which expose status conditions according to the kubernetes api (<https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#Condition>):
> StateSets represent a series of related boolean values, also called a bitset. If ENUMs need to be encoded this MAY be done via StateSet. [[1]](https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#stateset)
```yaml
kind: CustomResourceStateMetrics
spec:
resources:
- groupVersionKind:
group: myteam.io
kind: "Foo"
version: "v1"
metrics:
- name: "status_phase"
help: "Foo status_phase"
each:
type: StateSet
stateSet:
labelName: phase
path: [status, phase]
list: [Pending, Bar, Baz]
```
Metrics of type `StateSet` will generate a metric for each value defined in `list` for each resource.
The value will be 1, if the value matches the one in list.
> Info metrics are used to expose textual information which SHOULD NOT change during process lifetime. Common examples are an application's version, revision control commit, and the version of a compiler. [[2]](https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#info)
Metrics of type `Info` will always have a value of 1.
# For generally matching against a field in an object schema, use the following syntax:
[metadata, "name=foo"] # if v, ok := metadata[name]; ok && v == "foo" { return v; } else { /* ignore */ }
```
### Wildcard matching of version and kind fields
The Custom Resource State (CRS hereon) configuration also allows you to monitor all versions and/or kinds that come under a group. It watches
the installed CRDs for this purpose. Taking the aforementioned `Foo` object as reference, the configuration below allows
you to monitor all objects under all versions *and* all kinds that come under the `myteam.io` group.
```yaml
kind: CustomResourceStateMetrics
spec:
resources:
- groupVersionKind:
group: "myteam.io"
version: "*" # Set to `v1 to monitor all kinds under `myteam.io/v1`. Wildcard matches all installed versions that come under this group.
kind: "*" # Set to `Foo` to monitor all `Foo` objects under the `myteam.io` group (under all versions). Wildcard matches all installed kinds that come under this group (and version, if specified).
* For cases where the GVKs defined in a CRD have multiple versions under a single group for the same kind, as expected, the wildcard value will resolve to *all* versions, but a query for any specific version will return all resources under all versions, in that versions' representation. This basically means that for two such versions `A` and `B`, if a resource exists under `B`, it will reflect in the metrics generated for `A` as well, in addition to any resources of itself, and vice-versa. This logic is based on the [current `list`ing behavior](https://github.com/kubernetes/client-go/issues/1251#issuecomment-1544083071) of the client-go library.
* The introduction of this feature further discourages (and discontinues) the use of native objects in the CRS featureset, since these do not have an explicit CRD associated with them, and conflict with internal stores defined specifically for such native resources. Please consider opening an issue or raising a PR if you'd like to expand on the current metric labelsets for them. Also, any such configuration will be ignored, and no metrics will be generated for the same.
| kube_endpointslice_endpoints_hints | Gauge | Each line is a hint applied to an endpoint-slice | `endpointslice`=<endpointslice-name><br>`namespace`=<endpointslice-namespace><br>`address`=<endpointslice-address[0]><br>`for_zone`=<endpointslice-hint> | EXPERIMENTAL |
| kube_endpointslice_labels | Gauge | Kubernetes labels converted to Prometheus labels controlled via [--metric-labels-allowlist](../../developer/cli-arguments.md) | `endpointslice`=<endpointslice-name><br>`namespace`=<endpointslice-namespace><br>`label_ENDPOINTSLICE_LABEL`=<ENDPOINTSLICE_LABEL> | EXPERIMENTAL |
| kube_ingress_annotations | Gauge | Kubernetes annotations converted to Prometheus labels controlled via [--metric-annotations-allowlist](../../developer/cli-arguments.md) | `ingress`=<ingress-name><br>`namespace`=<ingress-namespace><br>`annotation_INGRESS_ANNOTATION`=<ANNOTATION_LABEL> | EXPERIMENTAL |
| kube_ingress_info | Gauge | | `ingress`=<ingress-name><br>`namespace`=<ingress-namespace><br>`ingressclass`=<ingress-class> or `_default` if not set | STABLE |
| kube_ingress_labels | Gauge | Kubernetes labels converted to Prometheus labels controlled via [--metric-labels-allowlist](../../developer/cli-arguments.md) | `ingress`=<ingress-name><br>`namespace`=<ingress-namespace><br>`label_INGRESS_LABEL`=<INGRESS_LABEL> | STABLE |
| kube_ingress_path | Gauge | | `ingress`=<ingress-name><br>`namespace`=<ingress-namespace><br>`host`=<ingress-host><br>`path`=<ingress-path><br>`path_type`=<ingress-path type><br> If path served by Service Backend <br>`service_name`=<service name for the path><br>`service_port`=<service port for the path><br> If path served by Resource Backend <br>`resource_api_group`=<resource backend api group><br>`resource_kind`=<resource backend kind><br>`resource_name`=<resource backend name> | STABLE |
| kube_service_spec_type | Gauge | Type about service | | `service`=<service-name><br>`namespace`=<service-namespace><br>`uid`=<service-uid><br>`type`=<ClusterIP\|NodePort\|LoadBalancer\|ExternalName> | STABLE |
| kube_service_spec_external_ip | Gauge | Service external ips. One series for each ip | | `service`=<service-name><br>`namespace`=<service-namespace><br>`uid`=<service-uid><br>`external_ip`=<external-ip> | STABLE |
| kube_service_status_load_balancer_ingress | Gauge | Service load balancer ingress status | | `service`=<service-name><br>`namespace`=<service-namespace><br>`uid`=<service-uid><br>`ip`=<load-balancer-ingress-ip><br>`hostname`=<load-balancer-ingress-hostname> | STABLE |
| kube_persistentvolume_csi_attributes | Gauge | CSI attributes of the Persistent Volume, disabled by default, manage with [--metric-opt-in-list](../../developer/cli-arguments.md)) | | `persistentvolume`=<persistentvolume-name><br>`csi_mounter`=<csi-mounter><br>`csi_map_options`=<csi-map-options> | EXPERIMENTAL |
| kube_persistentvolume_volume_mode | Gauge | Volume Mode information for the PersistentVolume. | | `persistentvolume`=<persistentvolume-name><br>`volumemode`=<volumemode> | EXPERIMENTAL |
## Useful metrics queries
### How to retrieve non-standard PV state
It is not straightforward to get the PV states for certain cases like "Terminating" since it is not stored behind a field in the `PersistentVolume.Status`.
So to mimic the [logic](https://github.com/kubernetes/kubernetes/blob/v1.27.2/pkg/printers/internalversion/printers.go#L1838) used by the `kubectl` command line, you will need to compose multiple metrics.
Here is an example of a Prometheus rule that can be used to alert on a PV that has been in the `Terminating` state for more than `5m`.
* An empty string will be used if PVC has no storage class.
## Useful metrics queries
### How to retrieve non-standard PVC state
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`.
So to mimic the [logic](https://github.com/kubernetes/kubernetes/blob/v1.27.2/pkg/printers/internalversion/printers.go#L1883) used by the `kubectl` command line, you will need to compose multiple metrics.
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`.