3、证书生命周期指标设计

证书轮换调度器的核心决策依据来自对证书生命周期的精确观测。如果 Prometheus 无法感知证书的“剩余有效期”、“颁发时间”和“轮换耗时”,调度器将陷入盲目操作——要么过早轮换造成资源浪费,要么过晚轮换导致服务中断。本章定义这三类关键指标的数据模型、标签策略和采集规范。

3.1 指标设计总览

证书生命周期指标遵循 Prometheus 四种核心指标类型中的 Gauge 和 Histogram。Gauge 用于描述当前状态(剩余有效期、颁发时间),Histogram 用于记录轮换操作的耗时分布。所有指标统一使用 cert_ 前缀,便于在 PromQL 中通过 {__name__=~"cert_.*"} 快速筛选。

指标名称 类型 描述 单位
cert_remaining_seconds Gauge 证书距离过期时间的剩余秒数 秒
cert_not_before_timestamp Gauge 证书颁发时间(Unix 时间戳) 秒
cert_rotation_duration_seconds Histogram 轮换操作从开始到完成的耗时 秒
cert_rotation_attempts_total Counter 轮换尝试总次数(含失败) 次数
设计原则:所有时间相关指标统一使用秒为单位,避免在 PromQL 中做单位换算。时间戳指标使用 Unix 时间戳(秒级),便于与 time() 函数直接计算差值。

3.2 证书剩余有效期指标

cert_remaining_seconds 是调度器最核心的输入指标。它直接决定了“是否需要立即轮换”以及“轮换的紧急程度”。该指标必须携带足够的标签信息,以便调度器能够区分不同证书实例。

# HELP cert_remaining_seconds Remaining seconds until certificate expiration
# TYPE cert_remaining_seconds gauge
cert_remaining_seconds{
  cert_name="kube-apiserver",
  cert_issuer="kubernetes-ca",
  cert_domain="apiserver.cluster.local",
  cert_serial="3a:4b:5c:6d"
} 864000

标签设计规范:

  • cert_name:证书的标识名称,如 kube-apiserver、etcd-peer。
  • cert_issuer:签发该证书的 CA 名称。
  • cert_domain:证书的 SAN(Subject Alternative Name)或通用名称。
  • cert_serial:证书序列号,用于区分同一名称下的不同版本证书。
避坑提示:不要将 cert_serial 作为唯一标签,因为序列号在证书轮换后会变化。调度器应使用 cert_name + cert_domain 作为逻辑主键,cert_serial 仅用于追踪版本变更。

3.3 证书颁发时间指标

cert_not_before_timestamp 记录了证书的生效时间(即 notBefore 字段)。该指标有两个关键用途:

  1. 计算证书已存活时间:time() - cert_not_before_timestamp 得到证书已使用时长。
  2. 检测时钟偏移:如果 cert_not_before_timestamp 大于当前时间,说明系统时钟存在偏移或证书尚未生效。
# HELP cert_not_before_timestamp Unix timestamp of certificate notBefore field
# TYPE cert_not_before_timestamp gauge
cert_not_before_timestamp{
  cert_name="kube-apiserver",
  cert_issuer="kubernetes-ca",
  cert_domain="apiserver.cluster.local"
} 1.720000e+09

结合 cert_remaining_seconds,可以推导出证书的总有效期:

# PromQL: 计算证书总有效期(秒)
cert_remaining_seconds + (time() - cert_not_before_timestamp)

3.4 轮换耗时指标

cert_rotation_duration_seconds 使用 Histogram 类型,记录每次轮换操作的耗时分布。调度器根据该指标的 P99 或 P95 分位数来设定轮换超时阈值,避免因单次轮换卡死而阻塞后续调度。

# HELP cert_rotation_duration_seconds Duration of certificate rotation operations
# TYPE cert_rotation_duration_seconds histogram
cert_rotation_duration_seconds_bucket{
  cert_name="kube-apiserver",
  le="0.5"
} 10
cert_rotation_duration_seconds_bucket{
  cert_name="kube-apiserver",
  le="1.0"
} 25
cert_rotation_duration_seconds_bucket{
  cert_name="kube-apiserver",
  le="2.5"
} 30
cert_rotation_duration_seconds_bucket{
  cert_name="kube-apiserver",
  le="5.0"
} 32
cert_rotation_duration_seconds_bucket{
  cert_name="kube-apiserver",
  le="+Inf"
} 32
cert_rotation_duration_seconds_sum{
  cert_name="kube-apiserver"
} 45.6
cert_rotation_duration_seconds_count{
  cert_name="kube-apiserver"
} 32

Bucket 边界设计建议:

场景 推荐 Bucket 边界(秒) 说明
本地文件证书轮换 0.1, 0.5, 1.0, 2.5, 5.0 操作轻量,毫秒级完成
远程 API 签发证书 0.5, 1.0, 2.5, 5.0, 10.0 涉及网络请求,延迟较高
集群级证书轮换(含重启) 1.0, 5.0, 15.0, 30.0, 60.0 包含服务重启和健康检查

3.5 指标关联与调度决策链路

下图展示了证书生命周期指标如何被调度器消费,并最终生成轮换决策:

证书生命周期指标 → 调度决策链路 cert_remaining_seconds cert_not_before_timestamp cert_rotation_duration_seconds PromQL 计算:剩余比例 / 轮换耗时 P99 / 已存活时间 调度器决策:立即轮换 / 延迟轮换 / 跳过轮换 执行轮换 → 更新 cert_rotation_duration_seconds

3.6 指标采集最佳实践

为确保指标数据的准确性和调度器的可靠性,在采集端需遵循以下规范:

  • 采集频率:证书剩余有效期指标建议每 15 秒采集一次,轮换耗时指标每次轮换完成后立即上报。
  • 标签稳定性:避免在标签值中包含时间戳、随机数等高频变化字段,防止 Prometheus 存储爆炸。
  • 空值处理:如果证书尚未颁发(notBefore 在未来),cert_remaining_seconds 应返回 -1 表示“未生效”,而非 0。
  • 指标注册:使用 Go 语言的 prometheus.MustRegister 在程序启动时注册所有指标,避免运行时动态注册导致指标丢失。
关键结论:证书生命周期指标是轮换调度器的“眼睛”。cert_remaining_seconds 提供当前状态快照,cert_not_before_timestamp 提供时间参考系,cert_rotation_duration_seconds 提供操作性能基线。三者结合,调度器才能做出“何时轮换、是否超时、是否异常”的精准判断。