mirror of
https://github.com/enix/x509-certificate-exporter.git
synced 2026-08-23 22:16:39 +00:00
248 lines
9.5 KiB
YAML
248 lines
9.5 KiB
YAML
# Secrets-only, fully tuned.
|
|
#
|
|
# Everything the cluster-watching side of the chart can do, in one
|
|
# place. No `hostPathsExporter` block — the chart's default
|
|
# (`daemonSets: {}`) produces nothing on its own, so there's nothing
|
|
# to disable here.
|
|
#
|
|
# Walk through every section before applying — most fields are
|
|
# placeholders (made-up node-selector labels, sample namespace opt-in
|
|
# labels, illustrative resources, Alertmanager routing labels,
|
|
# Secret names for the mTLS / BasicAuth scrape credentials, …).
|
|
# Inline comments call out what each one expects.
|
|
---
|
|
# ─── secretsExporter: workload + scope + hardening ────────────────────────────
|
|
secretsExporter:
|
|
enabled: true
|
|
|
|
# Two replicas for HA. The exporter is idempotent — both replicas
|
|
# observe the same Secret/ConfigMap state via independent watches —
|
|
# so two replicas double-count nothing. They just double the scrape
|
|
# capacity and survive a node drain.
|
|
replicas: 2
|
|
|
|
# Anti-affinity so the two replicas never co-locate on one node.
|
|
affinity:
|
|
podAntiAffinity:
|
|
preferredDuringSchedulingIgnoredDuringExecution:
|
|
- weight: 100
|
|
podAffinityTerm:
|
|
topologyKey: kubernetes.io/hostname
|
|
labelSelector:
|
|
matchLabels:
|
|
app.kubernetes.io/name: x509-certificate-exporter
|
|
app.kubernetes.io/component: secrets
|
|
|
|
# Schedule on observability-tier nodes if you have that pool.
|
|
nodeSelector:
|
|
workload-tier: observability
|
|
|
|
tolerations:
|
|
- key: workload-tier
|
|
operator: Equal
|
|
value: observability
|
|
effect: NoSchedule
|
|
|
|
priorityClassName: monitoring-cluster-critical
|
|
|
|
resources:
|
|
requests:
|
|
cpu: 50m
|
|
memory: 64Mi
|
|
limits:
|
|
memory: 256Mi
|
|
|
|
# ─── What to watch ──────────────────────────────────────────────────────────
|
|
# Multiple Secret types, demonstrating every passphrase strategy.
|
|
secretTypes:
|
|
# Standard PEM in kubernetes.io/tls (cert-manager output, ingress, …)
|
|
- type: kubernetes.io/tls
|
|
key: tls.crt
|
|
|
|
# Opaque PEM under a non-conventional key (legacy bundles)
|
|
- type: Opaque
|
|
key: cert.pem
|
|
|
|
# Multiple keys via regex — handy for full-chain bundles next to
|
|
# individual leaves
|
|
- type: Opaque
|
|
keyPatterns:
|
|
- '^.*\.crt$'
|
|
- '^.*\.pem$'
|
|
|
|
# PKCS#12 with passphrase as a sibling key in the same Secret
|
|
- type: Opaque
|
|
key: keystore.p12
|
|
format: pkcs12
|
|
pkcs12:
|
|
passphraseKey: keystore-passphrase
|
|
|
|
# PKCS#12 truststore — same passphrase pattern, different filename
|
|
- type: Opaque
|
|
key: truststore.p12
|
|
format: pkcs12
|
|
pkcs12:
|
|
passphraseKey: keystore-passphrase
|
|
|
|
# PKCS#12 with passphrase pulled from a separate Secret in another
|
|
# namespace — useful when the keystore lives in a workload namespace
|
|
# but the passphrase is centrally managed in `secrets-pkcs12-vault`.
|
|
- type: Opaque
|
|
key: vault.p12
|
|
format: pkcs12
|
|
pkcs12:
|
|
passphraseSecretRef:
|
|
namespace: secrets-pkcs12-vault
|
|
name: shared-keystore-passphrase
|
|
key: passphrase
|
|
|
|
# Passwordless PKCS#12 — try the empty passphrase before erroring out.
|
|
- type: Opaque
|
|
key: keystore-empty.p12
|
|
format: pkcs12
|
|
pkcs12:
|
|
tryEmptyPassphrase: true
|
|
|
|
# JKS truststore — sibling passphrase key, same semantics as PKCS#12.
|
|
- type: Opaque
|
|
key: truststore.jks
|
|
format: jks
|
|
jks:
|
|
passphraseKey: jks-passphrase
|
|
|
|
# JKS with passphrase centrally managed (mirrors the PKCS#12 vault
|
|
# pattern above — `jks.passphraseSecretRef` accepts the same shape).
|
|
- type: Opaque
|
|
key: vault.jks
|
|
format: jks
|
|
jks:
|
|
passphraseSecretRef:
|
|
namespace: secrets-jks-vault
|
|
name: shared-jks-passphrase
|
|
key: passphrase
|
|
|
|
# ConfigMaps holding PEM material (e.g. cluster-issuer CA bundles)
|
|
configMapKeys:
|
|
- tls.crt
|
|
- ca.crt
|
|
|
|
# ─── Filtering ──────────────────────────────────────────────────────────────
|
|
# Excluding kube-system / kube-public is conventional — those Secrets
|
|
# are mostly bootstrap tokens whose expiry the cluster manages itself.
|
|
# Entries are shell-glob patterns (`*`, `?`, `[abc]`) or literal names.
|
|
excludeNamespaces:
|
|
- kube-system
|
|
- kube-public
|
|
- kube-node-lease
|
|
# Glob example — exclude every ephemeral preview namespace:
|
|
# - "preview-*"
|
|
|
|
# Opt-in via namespace label: only scan namespaces that have explicitly
|
|
# opted in. Comment out if you want cluster-wide-by-default.
|
|
includeNamespaceLabels:
|
|
- "x509-certificate-exporter/watch=true"
|
|
|
|
# Per-Secret opt-out — even in an opted-in namespace, individual
|
|
# Secrets can be skipped.
|
|
excludeLabels:
|
|
- "x509-certificate-exporter/ignore=true"
|
|
|
|
# ─── Surface Secret metadata onto metrics ───────────────────────────────────
|
|
# Lifts these labels from each Secret onto its emitted series, prefixed
|
|
# with `secret_label_`. Useful for routing alerts by team / service.
|
|
exposeSecretLabels:
|
|
- app.kubernetes.io/name
|
|
- app.kubernetes.io/instance
|
|
- team
|
|
- environment
|
|
|
|
# ─── API-server load shaping ────────────────────────────────────────────────
|
|
# Throttle client-go to friendly defaults; matters on clusters with
|
|
# 100k+ Secrets and a beefy `--include-namespace-labels` selector that
|
|
# forces a wide initial list.
|
|
kubeApiRateLimits:
|
|
enabled: true
|
|
queriesPerSecond: 10
|
|
burstQueries: 20
|
|
|
|
# Internal parse cache — keeps re-parsing identical Secret payloads
|
|
# cheap when watch events fire on unrelated Secret fields. Chart
|
|
# defaults (enabled: true, maxDuration: 300) suit most clusters; bump
|
|
# `maxDuration` if Secrets are very chatty on non-cert fields and you
|
|
# want to lower CPU at the cost of slightly staler error counters.
|
|
cache:
|
|
maxDuration: 3600 # seconds
|
|
|
|
# ─── Pod customisation ──────────────────────────────────────────────────────
|
|
# Mount server TLS material referenced by webConfiguration below.
|
|
# Adapt the Secret name to your cert-manager Certificate /
|
|
# SealedSecret / ExternalSecrets setup.
|
|
extraVolumes:
|
|
- name: server-tls
|
|
secret:
|
|
secretName: x509-exporter-server-tls
|
|
extraVolumeMounts:
|
|
- name: server-tls
|
|
mountPath: /mnt/tls
|
|
readOnly: true
|
|
|
|
# ─── Securing the /metrics endpoint (mTLS + BasicAuth) ────────────────────────
|
|
# Web configuration consumed by prometheus/exporter-toolkit. The chart
|
|
# wires this as a Secret + volume mount + `--web.config.file`.
|
|
webConfiguration: |
|
|
basic_auth_users:
|
|
# Generate with: htpasswd -nBC 12 prometheus
|
|
prometheus: $2y$12$REPLACE_WITH_BCRYPT_HASH
|
|
|
|
tls_server_config:
|
|
cert_file: /mnt/tls/tls.crt
|
|
key_file: /mnt/tls/tls.key
|
|
client_auth_type: RequireAndVerifyClientCert
|
|
client_ca_file: /mnt/tls/ca.crt
|
|
|
|
prometheusServiceMonitor:
|
|
# mTLS + BasicAuth wiring — tell Prometheus how to reach /metrics.
|
|
# The Secret named here must contain `username`, `password`, and the
|
|
# CA / client cert / client key — see
|
|
# https://prometheus-operator.dev/docs/api-reference/api/#monitoring.coreos.com/v1.Endpoint
|
|
# `scheme: https` is mandatory here: the exporter serves TLS (see
|
|
# webConfiguration above) and the chart refuses to render basicAuth
|
|
# credentials over plaintext HTTP.
|
|
scheme: https
|
|
basicAuth:
|
|
username:
|
|
name: x509-exporter-scrape-creds
|
|
key: username
|
|
password:
|
|
name: x509-exporter-scrape-creds
|
|
key: password
|
|
tlsConfig:
|
|
caFile: /etc/prometheus/secrets/x509-exporter-scrape-ca/ca.crt
|
|
serverName: x509-certificate-exporter.monitoring.svc
|
|
|
|
# ─── PrometheusRule (alerting thresholds + routing labels) ────────────────────
|
|
prometheusRules:
|
|
# Tighter renewal alert (default: 28 days). Tune to match your cert
|
|
# rotation SLO — for cert-manager + LE, 14 days is plenty.
|
|
warningDaysLeft: 14
|
|
criticalDaysLeft: 7
|
|
alertOnSourceErrors: true
|
|
alertOnCertificateError: true
|
|
# Add labels that your Alertmanager router uses to route to the right
|
|
# team channel.
|
|
extraLabels:
|
|
team: platform
|
|
service: x509-certificate-exporter
|
|
|
|
# ─── Metrics shape ────────────────────────────────────────────────────────────
|
|
# Per-cert error metrics: enable when you want one failed-cert series
|
|
# per offending Secret in addition to the source-level counters. Useful
|
|
# in dashboards but inflates cardinality on ~thousands of bad certs.
|
|
exposePerCertificateErrorMetrics: true
|
|
|
|
# ─── Grafana dashboard ────────────────────────────────────────────────────────
|
|
# Materialise the bundled dashboard as a sidecar-discovered ConfigMap.
|
|
# Requires Grafana running with the dashboards sidecar enabled.
|
|
grafana:
|
|
createDashboard: true
|