<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Kube-State-Metrics | Manuel Rüger</title><link>https://manuelrueger.de/tags/kube-state-metrics/</link><atom:link href="https://manuelrueger.de/tags/kube-state-metrics/index.xml" rel="self" type="application/rss+xml"/><description>Kube-State-Metrics</description><generator>Hugo Blox Builder (https://hugoblox.com)</generator><language>en-us</language><lastBuildDate>Mon, 19 Jun 2023 00:00:00 +0000</lastBuildDate><image><url>https://manuelrueger.de/media/icon_hu_d95d4b5e989aed06.png</url><title>Kube-State-Metrics</title><link>https://manuelrueger.de/tags/kube-state-metrics/</link></image><item><title>Monitoring Open Policy Agent/Gatekeeper violations with kube-state-metrics</title><link>https://manuelrueger.de/blog/post/monitoring-open-policy-agent/gatekeeper-violations-with-kube-state-metrics/</link><pubDate>Mon, 19 Jun 2023 00:00:00 +0000</pubDate><guid>https://manuelrueger.de/blog/post/monitoring-open-policy-agent/gatekeeper-violations-with-kube-state-metrics/</guid><description>&lt;p>This article explains how kube-state-metrics can be used to monitor Open Policy Agent&amp;rsquo;s Gatekeeper policy audit violations, what to take care about and where kube-state-metrics&amp;rsquo; Custom Resource state might evolve to.&lt;/p>
&lt;details class="print:hidden xl:hidden" >
&lt;summary>Table of Contents&lt;/summary>
&lt;div class="text-sm">
&lt;nav id="TableOfContents">
&lt;ul>
&lt;li>&lt;a href="#introduction">Introduction&lt;/a>&lt;/li>
&lt;li>&lt;a href="#exposing-violations-as-prometheus-metrics">Exposing Violations as Prometheus Metrics&lt;/a>
&lt;ul>
&lt;li>&lt;a href="#custom-resource-definitions-in-gatekeeper">Custom Resource Definitions in Gatekeeper&lt;/a>&lt;/li>
&lt;li>&lt;a href="#custom-resource-state-in-kube-state-metrics">Custom Resource State in kube-state-metrics&lt;/a>&lt;/li>
&lt;li>&lt;a href="#collecting-metrics-from-all-constraints-via-wildcard-matching">Collecting metrics from all constraints via wildcard matching&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;a href="#caveats-with-this-approach">Caveats with this approach&lt;/a>
&lt;ul>
&lt;li>&lt;a href="#unexposed-violations">Unexposed Violations&lt;/a>&lt;/li>
&lt;li>&lt;a href="#high-cardinality-data">High Cardinality Data&lt;/a>&lt;/li>
&lt;li>&lt;a href="#kubernetes-resource-version-upgrades">Kubernetes Resource Version Upgrades&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;a href="#summary">Summary&lt;/a>&lt;/li>
&lt;/ul>
&lt;/nav>
&lt;/div>
&lt;/details>
&lt;h2 id="introduction">Introduction&lt;/h2>
&lt;p>
is a policy engine that allows you to enforce policies on various systems.
With
, it provides a service, that utilizes an admission controller webhook to enforce policies on Kubernetes resources.
This means, whenever a Kubernetes resource changes through a request to the Kubernetes API, a rule-based decision to allow or deny this action is made.
To organize and manage these rules, Gatekeeper makes use of Kubernetes&amp;rsquo; Custom Resource Definitions (CRDs).
Gatekeeper does not only allow checking against its policies at admission.
It also provides an audit service, that can regularly check resources in the Kubernetes cluster.&lt;/p>
&lt;p>
is a microservice that makes the state of the Kubernetes&amp;rsquo; REST API available as
metrics.
It queries the API and exposes the gathered information on a metrics HTTP endpoint.
Recently, it gained support for
.
This is a flexible way to query and extract user-defined information from the Kubernetes API.&lt;/p>
&lt;h2 id="exposing-violations-as-prometheus-metrics">Exposing Violations as Prometheus Metrics&lt;/h2>
&lt;h3 id="custom-resource-definitions-in-gatekeeper">Custom Resource Definitions in Gatekeeper&lt;/h3>
&lt;p>Gatekeeper uses two custom resource definitions to manage policies.
A ConstraintTemplate (group: templates.gatekeeper.sh), that contains the rule definition.
A corresponding constraint (group: constraints.gatekeeper.sh) allows setting enforcement actions and stores information from the audit.&lt;/p>
&lt;p>Here is an
of how this looks like according to the docs from Open Policy Agent:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">apiVersion&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">templates.gatekeeper.sh/v1beta1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ConstraintTemplate&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">metadata&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">k8srequiredlabels&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">spec&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">crd&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">spec&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">names&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">K8sRequiredLabels&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="l">...&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">targets&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">target&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">admission.k8s.gatekeeper.sh&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">rego&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="sd">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> package k8srequiredlabels
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> violation[{&amp;#34;msg&amp;#34;: msg, &amp;#34;details&amp;#34;: {&amp;#34;missing_labels&amp;#34;: missing}}] {
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> provided := {label | input.review.object.metadata.labels[label]}
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> required := {label | label := input.parameters.labels[_]}
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> missing := required - provided
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> count(missing) &amp;gt; 0
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> msg := sprintf(&amp;#34;you must provide labels: %v&amp;#34;, [missing])
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> }&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This policy checks for specific metadata labels in the object.
If the labels are not included in the object, it will return a violation.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">apiVersion&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">constraints.gatekeeper.sh/v1beta1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">K8sRequiredLabels&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">metadata&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">namespaces-must-have-gatekeeper-label&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">spec&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">enforcementAction&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">warn&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">match&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">kinds&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">apiGroups&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">kinds&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Namespace&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">parameters&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c"># Note that &amp;#34;labels&amp;#34; is now contained in an array item, rather than an object key under &amp;#34;parameters&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">labels&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;gatekeeper&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This constraint will limit the policy enforcement to Kubernetes namespace objects and require a label with the key gatekeeper to be set.
Its enforcement action is set to warn.
This means it will omit a warning when applying a resource that violates the policy.&lt;/p>
&lt;p>If we run&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">kubectl get k8srequiredlabels.constraints.gatekeeper.sh/v1 namespaces-must-have-gatekeeper-label -o yaml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>we receive this output:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">apiVersion&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">constraints.gatekeeper.sh/v1beta1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">K8sRequiredLabels&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">metadata&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">namespaces-must-have-gatekeeper-label&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="l">...&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">status&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">totalViolations&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">violations&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">enforcementAction&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">warn&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Namespace&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">message: &amp;#39;you must provide labels&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;gatekeeper&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="l">&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">kube-system&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="l">...&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If you enable Gatekeeper to audit your objects regularly, this object will include besides the total number of violations, also a report from the latest audit run in the status key.
Unfortunately, Gatekeeper does not expose this level of detail via a Prometheus exporter itself.
There have been separate specialized exporters like
built in the past.
In the next paragraph, we will see how kube-state-metrics, as a generic exporter, can provide the same level of information.&lt;/p>
&lt;h3 id="custom-resource-state-in-kube-state-metrics">Custom Resource State in kube-state-metrics&lt;/h3>
&lt;p>If you run kube-state-metrics already in your cluster, you can now generate metrics on policy violations with the Custom Resource State.
And if you don&amp;rsquo;t run kube-state-metrics, this might be a good opportunity to
it on your cluster to get better insights.&lt;/p>
&lt;p>Before we can expose Custom Resource State metrics, we need to define them via a configuration.
kube-state-metrics supports the configuration of Custom Resource State via command line arguments or a config file.
In this example, we assume you have a config file, so you can include the following snippets in it.&lt;/p>
&lt;p>Add the following paragraph to your kube-state-metrics&amp;rsquo; Custom Resource State configuration:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">CustomResourceStateMetrics&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">spec&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">resources&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">groupVersionKind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">group&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">constraints.gatekeeper.sh&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;K8sRequiredLabels&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">version&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;v1beta1&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">metrics&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;gatekeeper_violations_total&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">help&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Number of violations&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">each&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">type&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Gauge&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">gauge&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">path&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="l">status, totalViolations]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;gatekeeper_violation_info&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">help&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Information about the detected violation&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">each&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">type&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Info&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">info&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">path&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="l">status, violations]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">labelsFromPath&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">enforcement_action&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="l">enforcementAction]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">violating_kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="l">kind]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">violating_message&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="l">message]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">violating_name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="l">name]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">violating_namespace&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="l">namespace]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>and the following metric series will be exported:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-gdscript3" data-lang="gdscript3">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># HELP kube_customresource_gatekeeper_violations_total Number of violations&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># TYPE kube_customresource_gatekeeper_violations_total gauge&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">kube_customresource_gatekeeper_violations_total&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="n">customresource_group&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;constraints.gatekeeper.sh&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">customresource_kind&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;k8srequiredlabels&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">customresource_version&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;v1beta1&amp;#34;&lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="mi">35&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># HELP kube_customresource_gatekeeper_violation Violations detected&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># TYPE kube_customresource_gatekeeper_violation gauge&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">kube_customresource_gatekeeper_violation&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="n">customresource_group&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;constraints.gatekeeper.sh&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">customresource_kind&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;Namespace&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">customresource_version&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;v1&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">enforcementAction&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;warn&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">violating_message&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;you must provide labels: [&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">gatekeeper&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">]&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">violating_kind&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;Namespace&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">violating_name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;kube-system&amp;#34;&lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="mi">1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">...&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>These metric series can now be ingested into Prometheus or a similar TSDB and be used for alerting or visualizing violations on a dashboard.&lt;/p>
&lt;h3 id="collecting-metrics-from-all-constraints-via-wildcard-matching">Collecting metrics from all constraints via wildcard matching&lt;/h3>
&lt;p>With kube-state-metrics v2.9.2 and later, another helpful feature around Custom Resource State got included:
kube-state-metrics supports wildcards for the kind as well as version keys now.
This allows to collect every violation from every constraint CRD created by gatekeeper with the following configuration:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">CustomResourceStateMetrics&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">spec&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">resources&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">groupVersionKind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">group&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;constraints.gatekeeper.sh&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;*&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">version&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;v1beta1&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">metrics&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;gatekeeper_violations_total&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">help&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Number of violations&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">each&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">type&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Gauge&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">gauge&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">path&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="l">status, totalViolations]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;gatekeeper_violation_info&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">help&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Information about the detected violation&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">each&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">type&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Info&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">info&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">path&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="l">status, violations]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">labelsFromPath&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">enforcement_action&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="l">enforcementAction]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">violating_kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="l">kind]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">violating_message&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="l">message]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">violating_name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="l">name]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">violating_namespace&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="l">namespace]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>As you might have already spotted, this time the namespace is included in the labelsFromPath map.
Objects violating policy can be namespaced or non-namespaced.
If the specified path - in this case, the namespace key - does not exist, no label will be added to the metric series.
If the path exists, you will see the label appear in the metric series.&lt;/p>
&lt;p>Add a new Constraint to your cluster. This time a &amp;ldquo;team&amp;rdquo; label on Deployments is desired:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">apiVersion&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">constraints.gatekeeper.sh/v1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">K8sRequiredLabels&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">metadata&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">deployments-must-have-team-label&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">spec&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">enforcementAction&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">warn&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">match&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">kinds&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">apiGroups&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">kinds&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Deployment&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">parameters&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c"># Note that &amp;#34;labels&amp;#34; is now contained in an array item, rather than an object key under &amp;#34;parameters&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">labels&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;team&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This will generate the following metrics:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-gdscript3" data-lang="gdscript3">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># HELP kube_customresource_gatekeeper_violations_total Number of violations&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># TYPE kube_customresource_gatekeeper_violations_total gauge&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">kube_customresource_gatekeeper_violations_total&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="n">customresource_group&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;constraints.gatekeeper.sh&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">customresource_kind&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;k8srequiredlabels&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">customresource_version&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;v1&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;namespaces-must-have-gatekeeper-label&amp;#34;&lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="mi">35&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">kube_customresource_gatekeeper_violations_total&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="n">customresource_group&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;constraints.gatekeeper.sh&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">customresource_kind&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;k8srequiredlabels&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">customresource_version&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;v1&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;deployments-must-have-team-label&amp;#34;&lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="mi">39&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># HELP kube_customresource_gatekeeper_violation Violations detected&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># TYPE kube_customresource_gatekeeper_violation info&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">kube_customresource_gatekeeper_violation&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="n">customresource_group&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;constraints.gatekeeper.sh&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">customresource_kind&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;k8srequiredlabels&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">customresource_version&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;v1&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">enforcementAction&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;warn&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">violating_message&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;you must provide labels: [&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">gatekeeper&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">]&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">violating_kind&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;Namespace&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">violating_name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;kube-system&amp;#34;&lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="mi">1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">kube_customresource_gatekeeper_violation&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="n">customresource_group&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;constraints.gatekeeper.sh&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">customresource_kind&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;k8srequiredlabels&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">customresource_version&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;v1&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">enforcementAction&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;warn&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">violating_message&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;you must provide labels: [&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">team&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">]&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">violating_kind&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;Deployment&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">violating_name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;coredns&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">violating_namespace&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;kube-system} 1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">...&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="caveats-with-this-approach">Caveats with this approach&lt;/h2>
&lt;p>When using custom resource state metrics, there are a couple of things to keep in mind, as they might cause issues on your cluster or confusion for consumers.&lt;/p>
&lt;h3 id="unexposed-violations">Unexposed Violations&lt;/h3>
&lt;p>Gatekeeper has a flag called &lt;code>--constraint-violations-limit&lt;/code> which limits the number of violations added to the Constraint custom resource. You might need to increase it to get more data on violations. Be aware that Kubernetes limits how big a custom resource object can grow.
This does not affect the total count of violations, which is always showing the correct count.&lt;/p>
&lt;h3 id="high-cardinality-data">High Cardinality Data&lt;/h3>
&lt;p>With this approach, there is a chance to feed data with high cardinality into Prometheus. This means, if you decide to expose values like Pod IDs or other values that change a lot, Prometheus&amp;rsquo; database will grow in space and queries might take longer.&lt;/p>
&lt;h3 id="kubernetes-resource-version-upgrades">Kubernetes Resource Version Upgrades&lt;/h3>
&lt;p>Using a wildcard for the version of the resource you want to monitor does not provide a useful benefit as Kubernetes automatically upgrades the version before exposing it on its API.&lt;/p>
&lt;h2 id="summary">Summary&lt;/h2>
&lt;p>To sum it all up, in this example we have seen that Custom Resource State is a powerful tool to collect metrics from Custom Resources and its configuration offers a great flexibility to the user.
We can define individual metric series to be extracted from the Kubernetes API and customize metric series labels to meet specific needs as well as apply it over multiple kinds and different versions of the same CRD group.&lt;/p>
&lt;p>If you are interested in more Custom Resource State configurations, I have started a repository to collect more
.&lt;/p>
&lt;p>Finally, I want to thank
,
,
,
and
for their work on the implementation in kube-state-metrics.&lt;/p></description></item></channel></rss>