作者:来自 Elastic Mirko BezCarles SalvadorLorenzo Soligo

在现代分布式系统中,TLS 证书是将一切连接在一起并保证安全的关键。证书不仅用于加密用户流量;它们是整个系统信任的基础构建块。

实际上,证书过期不仅仅是一个小的技术问题。它会直接影响你最关键的系统:

  • 你的 CI/CD 流水线因为无法信任内部镜像仓库而停滞。
  • 你的单点登录(SSO)系统失效,所有内部用户无法访问。
  • 外部客户端会看到可怕的浏览器警告,破坏用户信任并触发大量支持工单。
  • 服务间无法通信,导致你的 SLO 受损。

在 Kubernetes 中,证书通常由 cert-manager 等工具动态生成并自动续期。在不太幸运的情况下,证书可能被存放在 Secrets 和 ConfigMaps 中,这会给盘点带来挑战。拥有十几份关键证书却没有集中方式了解它们即将过期的情况,这既不罕见也并非难事。

此外,仅监控外部负载均衡器的证书可能带来巨大内部风险,因为许多证书从未暴露给外部用户。

在这篇博客中,我们将指导你如何使用 OpenTelemetry Collector、x509-certificate-exporter 和 Elastic Observability,建立全面的、覆盖整个集群的证书监控。

经典方法:HTTP 监控

在 Elastic Observability 中,监控 TLS 证书过期的经典方法是将其视为其他服务可用性检查。历史上,这通常通过 Heartbeat 实现,或更近期使用 Elastic Observability 的 Synthetics。这些工具会对公共 HTTPS 端点执行外部检查,并自动提取证书的有效期,从而可以在 Kibana 中配置 Synthetics TLS 证书规则,在证书即将过期(例如 30 天内)时触发告警。

虽然对面向外部的服务有效,但在处理 Kubernetes 时,这种 “经典” 方法存在两个主要不足:

  • 它仅适用于通过 HTTP(S) 暴露的证书,这意味着无法用于内部服务、数据库或使用其他协议的消息队列。换句话说,这无法监控像 Kafka 这样的常见关键 TLS 证书。
  • 监控 agent 必须能够访问端点。在分段或私有的 Kubernetes 环境中,部署具有必要访问权限的 agent 往往会带来不必要的复杂性或安全风险。

要实现真正的集群级可见性,我们需要从源头检查证书:在 Kubernetes Secrets 或 ConfigMaps 中。

Kubernetes 原生方法:监控 Secrets 和 ConfigMaps

直接在 Kubernetes Secrets 和 ConfigMaps 中监控 TLS 证书过期,是获取内部、非 HTTP 暴露证书可见性的唯一可靠方式,例如用于服务网格、内部镜像仓库或数据库的证书。在本节中,我们将使用 OpenTelemetry Collector 来监控证书过期。

OpenTelemetry Collector 提供了一种机制,可以通过 k8sobjects receiver 从 Kubernetes API(包括 Secrets)读取最新信息。然而,该 receiver 只获取原始 TLS 证书资源数据,OpenTelemetry Transformation Language (OTTL) 无法正确解析这些数据。因此,我们需要使用专用的 exporter 来收集证书数据,并以可解析的格式输出结果。

行业标准解决方案

如上所述,仅从 Kubernetes API 读取证书信息并不可行。因此,我们将使用一个专用的轻量级 exporter(具体为流行的 x509-certificate-exporter)来收集 TLS 证书数据并输出结果,从而让 OpenTelemetry Collector 的 Prometheus receiver 可以无缝抓取这些数据并发送到 Elastic Observability。该方法可以立即且轻松地监控 cert-manager 生成的证书以及自管理的证书,例如为 ECK 创建的证书。

一个完整的可运行配置示例和用于搭建完整本地开发环境的脚本可在此获取。你可以在阅读本指南时跟随使用并尝试示例。请注意,虽然该仓库使用的是 Elastic Distribution of OpenTelemetry (EDOT),但也可以轻松适配为使用 OpenTelemetry Collector。

Helm Chart 配置

我们使用官方 Helm Chart 配置了 x509-certificate-exporter,并采用以下最小配置:

secretsExporter:
  secretTypes:
  - type: kubernetes.io/tls
    key: tls.crt
  # For ECK that uses different secret types
  - type: Opaque
    key: tls.crt
  - type: Opaque
    key: ca.crt
  configMapKeys:
  - tls.crt
  - ca.crt

# Create a service to have a stable endpoint for scraping metrics
service:
  create: true
  # -- TCP port to expose the Service on
  port: 9793

# Disable prometheus service monitor and prometheus rules
prometheusServiceMonitor:
  create: false
prometheusRules:
  create: false

我们参考了 reference values.yaml,以了解众多配置选项。

OpenTelemetry Collector 配置

随后,我们配置 OpenTelemetry Collector,从该服务抓取指标:

prometheus/cert-expiration:
  config:
    scrape_configs:
      - job_name: "cert-expiration"
        scrape_interval: 60m
        static_configs:
          - targets:
              - "x509-certificate-exporter.monitoring.svc.cluster.local:9793"

我们特意使用了 60 分钟的长抓取间隔,因为证书过期属于低频关注事项。

在 Kibana 中可视化数据

数据摄取后,我们可以使用 Discover 进行探索。可以选择 metrics-* 数据视图,并使用过滤器 data_stream.dataset : "prometheusreceiver.otel" 搜索数据。

示例文档如下:

{
  "@timestamp": "2025-12-19T09:43:45.317Z",
  "_metric_names_hash": "7d113f55b70019d9",
  "attributes": {
    "issuer_CN": "tls-cert.example.com",
    "issuer_O": "TLS Cert",
    "secret_key": "tls.crt",
    "secret_name": "tls-cert-secret",
    "secret_namespace": "test-certs",
    "serial_number": "250887723804527203192865532237673843132727735771",
    "subject_CN": "tls-cert.example.com",
    "subject_O": "TLS Cert"
  },
  "data_stream": {
    "dataset": "prometheusreceiver.otel",
    "namespace": "default",
    "type": "metrics"
  },
  "metrics": {
    "x509_cert_expired": 0,
    "x509_cert_not_after": 1768488242,
    "x509_cert_not_before": 1765896242
  },
  "resource": {
    "attributes": {
      "server.address": "x509-certificate-exporter.monitoring.svc.cluster.local",
      "server.port": "9793",
      "service.instance.id": "x509-certificate-exporter.monitoring.svc.cluster.local:9793",
      "service.name": "cert-expiration",
      "url.scheme": "http"
    }
  },
  "scope": {
    "name": "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver",
    "version": "9.2.2"
  }
}

x509-certificate-exporter 报告的核心指标是 x509_cert_not_after,它表示证书过期日期的 Unix Epoch 时间戳(以秒为单位)。该指标关联了一些属性。在 Secrets 的情况下,以下属性是相关的:

  • secret_namespace:包含证书的 Secret 所在的命名空间。
  • secret_name:包含证书的 Secret 名称。
  • secret_key:Secret 中存储证书的具体键。

在 ConfigMaps 的情况下,我们可以从 filepath 属性推断出相关属性。

最后,我们可以利用 ES|QL 计算证书剩余的有效天数。在以下示例中,我们将使用 TS 命令,它针对时间序列数据进行了优化并且推荐使用。

针对 Secrets:

TS metrics-*
| WHERE metrics.x509_cert_not_after is not NULL
| STATS expiration_date = MAX(LAST_OVER_TIME(metrics.x509_cert_not_after)) by attributes.secret_namespace, attributes.secret_name, attributes.secret_key
| EVAL remaining_days = DATE_DIFF("days", NOW(), TO_DATETIME (1000 * expiration_date))
| EVAL expiration_date = TO_DATETIME(1000 * expiration_date)
| SORT expiration_date ASC

针对 ConfigMaps:

TS metrics-*
| WHERE metrics.x509_cert_not_after IS NOT NULL
| WHERE attributes.filepath IS NOT NULL
| DISSECT attributes.filepath "k8s/%{namespace}/%{configmap}"
| WHERE configmap != "kube-root-ca.crt" // Filter out the Kubernetes API server certificate's signing CA
| STATS expiration_date = MAX(LAST_OVER_TIME(metrics.x509_cert_not_after)) by namespace, configmap, filename
| EVAL remaining_days = DATE_DIFF("days", NOW(), TO_DATETIME (1000 * expiration_date))
| EVAL expiration_date = TO_DATETIME(1000 * expiration_date)
| SORT expiration_date ASC

基于这些核心查询,我们可以轻松构建一个仪表板,显示集群中所有证书的剩余有效天数:

并且可以通过在查询后添加条件,为即将过期的证书创建告警:

WHERE remaining_days < 30

结论

在这篇博客中,我们探讨了如何使用 OpenTelemetry Collector 在 Kubernetes 集群内监控 TLS 证书过期。我们讨论了传统基于 HTTP 的监控方法的局限性,并介绍了一种 Kubernetes 原生方案,利用 x509-certificate-exporter 直接从 Kubernetes Secrets 和 ConfigMaps 提取证书过期数据。该方法为集群中使用的所有证书提供了全面可见性,包括未通过 HTTP(S) 暴露的证书。

为简化说明,我们仅关注在 Kubernetes 上使用 OpenTelemetry Collector 监控证书过期。然而,该方法也可以通过经典 Elastic Agent 配合 Prometheus 输入包轻松应用(可在此了解如何使用 input packages),并且可以扩展到通过在虚拟机或裸机服务器上部署 x509-certificate-exporter 来监控证书。

最后值得注意的是,Elastic Observability 提供了官方支持的 OpenTelemetry Collector 发行版,称为 Elastic Distributions of OpenTelemetry (EDOT)

如果你是 Elastic 用户,可以考虑使用 EDOT Collector 配合 OpenTelemetry 监控证书:由于 Elastic Observability 支持,它更容易管理并保持更新。当然,你也可以使用上游 OTel 组件。

接下来是什么?

现在 Elastic 支持 Rule TemplatesOpenTelemetry content packs,我们的近期目标是向集成仓库贡献内容,使证书监控的部署对用户更简单。请关注更多更新!

查看 Elastic OpenTelemetry 的其他资源:

还可以注册 Elastic Cloud,在 Elastic 中使用 OpenTelemetry 试用你的应用。

原文:https://www.elastic.co/observability-labs/blog/edot-certificate-monitoring

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐