Metrics¶
The controller serves Prometheus metrics on port 8443. Alongside the standard controller-runtime, Go runtime and client-go families, cmp-issuer publishes what its own enrollments did.
Every series carries the same three labels:
| Label | Values |
|---|---|
issuer_kind |
CMPIssuer or CMPClusterIssuer |
issuer |
namespace/name for a CMPIssuer, name for a CMPClusterIssuer |
operation |
enrollment or renewal |
operation separates the first issuance of a certificate from a re-enrollment. cert-manager stamps
each CertificateRequest with the revision it will become, so anything past the first is a renewal. A
CertificateRequest written by hand carries no revision and counts as an enrollment. Note that
cmp-issuer renews by sending a fresh P10CR rather than a CMP Key Update Request, so a renewal is the
same protocol exchange as an enrollment. See P10CR renewal and KUR.
What is published¶
| Metric | Type | Labels beyond the three above | Meaning |
|---|---|---|---|
cmp_issuer_enrollment_total |
counter | result is issued or failed |
Completed attempts. A wait for a server that has not answered is not an attempt |
cmp_issuer_enrollment_duration_seconds |
histogram | result |
Time from recording the CMP transaction to its outcome, including every poll and confirmation wait |
cmp_issuer_enrollment_failures_total |
counter | failure, classification |
Failures by the CMP failure that ended them and whether that failure is retried |
cmp_issuer_enrollment_polls_total |
counter | none | Waits for a server that accepted a request but has not returned or confirmed the certificate |
cmp_issuer_enrollment_confirmations_total |
counter | confirmation is Explicit or Implicit |
Completed enrollments by whether the server required certConf |
failure carries the CMP failure name, such as badRequest, badMessageCheck, signerNotTrusted or
systemUnavail, plus issuerConfiguration for a failure that never reached the server and
unclassified for one that carries no CMP failure information. classification is Permanent,
Retryable, Security or Unknown, matching the classification field of the CMP enrollment
failed log line, which also names the protocol step the failure came from.
The duration is measured from the CMPTransaction record, not from the current reconcile, so an
enrollment a server queued for ten minutes is observed as ten minutes rather than as several short
reconciles. A retried failure is counted once per attempt.
Example queries¶
Enrollment failure rate over the last hour, split by whether it was a renewal:
sum by (operation) (rate(cmp_issuer_enrollment_total{result="failed"}[1h]))
/ sum by (operation) (rate(cmp_issuer_enrollment_total[1h]))
Renewals that are failing, by cause, which is the query that tells you whether a CA changed a profile:
sum by (issuer, failure) (increase(cmp_issuer_enrollment_failures_total{operation="renewal"}[24h]))
The 95th percentile enrollment time per issuer, to catch a CA that has started queueing:
histogram_quantile(0.95, sum by (le, issuer) (rate(cmp_issuer_enrollment_duration_seconds_bucket{result="issued"}[30m])))
Authentication failures, which usually mean a rotated shared secret or an expired signing certificate:
sum by (issuer) (increase(cmp_issuer_enrollment_failures_total{failure="badMessageCheck"}[15m])) > 0
Reaching the endpoint¶
Every scrape is authenticated with a TokenReview and authorized with a SubjectAccessReview, so the
scraping ServiceAccount needs the cmp-issuer-metrics-reader ClusterRole the installation creates:
kubectl create clusterrolebinding prometheus-cmp-issuer-metrics --clusterrole=cmp-issuer-metrics-reader --serviceaccount=monitoring:prometheus
Set prometheus.enabled=true to have the chart create a ServiceMonitor. By default the endpoint
presents a certificate the controller generates for localhost, which no scraper that checks the
server name can verify, so the ServiceMonitor skips verification. Set
metrics.tls.certManager.enabled=true to have cert-manager issue a certificate for the Service name
instead, and the ServiceMonitor verifies it. See installation.
metrics.secure=false serves plain HTTP with no authentication, for a collector that cannot present a
token. Pair it with networkPolicy.enabled=true.