Cloud Native 7 min read

How to Monitor Kubernetes Certificate Expiration with Prometheus and ssl_exporter

Learn how to install ssl_exporter in a kubeadm‑created Kubernetes cluster, configure Prometheus to scrape SSL certificate metrics, and set up alert rules that warn when certificates approach expiration or TLS connections fail, ensuring continuous security compliance.

Ops Development Stories
Ops Development Stories
Ops Development Stories
How to Monitor Kubernetes Certificate Expiration with Prometheus and ssl_exporter

The default certificate validity period for a kubeadm‑created cluster is one year, and renewing certificates is quick, but monitoring their expiration is essential for reliable operations.

Prometheus, the leading cloud‑native monitoring system, can be used together with ssl_exporter to expose SSL certificate metrics such as start/end dates and OCSP status.

Installation

<code>apiVersion: v1
kind: Service
metadata:
  labels:
    name: ssl-exporter
  name: ssl-exporter
spec:
  ports:
    - name: ssl-exporter
      protocol: TCP
      port: 9219
      targetPort: 9219
  selector:
    app: ssl-exporter
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ssl-exporter
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ssl-exporter
  template:
    metadata:
      name: ssl-exporter
      labels:
        app: ssl-exporter
    spec:
      initContainers:
        # Install kube ca cert as a root CA
        - name: ca
          image: alpine
          command:
            - sh
            - -c
            - |
              set -e
              apk add --update ca-certificates
              cp /var/run/secrets/kubernetes.io/serviceaccount/ca.crt /usr/local/share/ca-certificates/kube-ca.crt
              update-ca-certificates
              cp /etc/ssl/certs/* /ssl-certs
          volumeMounts:
            - name: ssl-certs
              mountPath: /ssl-certs
      containers:
        - name: ssl-exporter
          image: ribbybibby/ssl-exporter:v0.6.0
          ports:
            - name: tcp
              containerPort: 9219
          volumeMounts:
            - name: ssl-certs
              mountPath: /etc/ssl/certs
      volumes:
        - name: ssl-certs
          emptyDir: {}
</code>

Apply the manifests:

<code>kubectl apply -f .</code>

After the pod is running, verify it:

<code># kubectl get po -n monitoring -l app=ssl-exporter
NAME                                 READY   STATUS    RESTARTS   AGE
ssl-exporter-7ff4759679-f4qbs        1/1     Running   0          21m
</code>

Next, create a Prometheus scrape configuration for the exporter.

<code>- job_name: ssl-exporter
  metrics_path: /probe
  static_configs:
  - targets:
    - kubernetes.default.svc:443
  relabel_configs:
  - source_labels: [__address__]
    target_label: __param_target
  - source_labels: [__param_target]
    target_label: instance
  - target_label: __address__
    replacement: ssl-exporter.monitoring:9219
</code>

Save the above as

prometheus-additional.yaml

, then create a secret containing it:

<code>kubectl delete secret additional-config -n monitoring
kubectl -n monitoring create secret generic additional-config --from-file=prometheus-additional.yaml
</code>

Modify the existing

prometheus-prometheus.yaml

to reference the additional scrape config:

<code>  additionalScrapeConfigs:
    name: additional-config 
    key: prometheus-additional.yaml 
</code>

Apply the updated Prometheus configuration:

<code>kubectl apply -f prometheus-prometheus.yaml</code>

In the Prometheus web UI you should now see the ssl_exporter target being scraped:

Prometheus target list
Prometheus target list

Use the metric

ssl_cert_not_after

to calculate remaining days until expiration:

<code>(ssl_cert_not_after - time()) / 3600 / 24</code>
Certificate expiration metric
Certificate expiration metric

Monitor TLS connectivity with

ssl_tls_connect_success

:

TLS connection metric
TLS connection metric

Alerting

Define alert rules to notify when certificates are near expiration or TLS connections fail:

<code>apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: monitoring-ssl-tls-rules
  namespace: monitoring
  labels:
    prometheus: k8s
    role: alert-rules
spec:
  groups:
  - name: check_ssl_validity
    rules:
    - alert: "K8S cluster certificate expires in 30 days"
      expr: (ssl_cert_not_after - time()) / 3600 / 24 < 30
      for: 1h
      labels:
        severity: critical
      annotations:
        description: "K8S cluster certificate will expire in {{ printf \"%.1f\" $value }} days, please renew soon."
        summary: "K8S cluster certificate expiration warning"
  - name: ssl_connect_status
    rules:
    - alert: "K8S cluster certificate connectivity abnormal"
      expr: ssl_tls_connect_success == 0
      for: 1m
      labels:
        severity: critical
      annotations:
        summary: "K8S cluster certificate connection abnormal"
        description: "K8S cluster {{ $labels.instance }} certificate connection abnormal"
</code>

When the conditions are met, Prometheus will fire the alerts, which can be routed to your alertmanager for notification.

Alert rule status
Alert rule status
Cloud NativeKubernetesalertingPrometheuscertificate monitoringssl_exporter
Ops Development Stories
Written by

Ops Development Stories

Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.