- 云原生
- 后端
- 开发工具
- 微服务
【免费下载链接】operator-sdk
SDK for building Kubernetes applications. Provides high level APIs, useful abstractions, and project scaffolding.
导读
本文以 operator-sdk 仓库内置的监控示例项目memcached-operator为核心,深入讲解 Operator 暴露的 Prometheus 指标(Operator Metrics)从定义、注册、采集到文档自动生成的完整链路。你将理解docs/monitoring/metrics.md这份自动生成文档的由来与含义,掌握指标命名、Counter 类型选择、指标文档生成工具monitoring/metricsdocs的工作原理,并结合告警规则(Alerting Rules)、runbook 与规则单测,学会为自有 Operator 建立一套"指标定义 → 文档生成 → 告警 → 自检"的完整可观测性方案。
一、文档定位:一份由工具自动生成的指标清单
先看关联文档全文(位于 metrics.md):
Operator Metrics:本文档旨在帮助不熟悉该 Operator 所暴露指标的读者。本指标文档由工具
monitoring/metricsdocs自动生成,反映了 Operator 暴露的全部指标。
其正文只有一个指标条目,外加一段"开发新指标"的维护说明。这份文档内容虽短,但它定义了一种可复用的工程模式:指标清单不应靠人手维护,而应由代码自动生成,保证"文档即真相"。
文档中提到的生成工具 metricsdocs.go 实际做的事是:
- 调用
monitoring.ListMetrics()从指标描述表中取出所有指标; - 按指标名排序,保证输出顺序稳定;
- 用 Go 标准库
text/template渲染出一段固定模板; - 把渲染结果打印到标准输出,重定向写入
docs/monitoring/metrics.md。
也就是说,当前 metrics.md 的每一个标题、每一句说明都是模板运行的产物,模板源码与文档内容一一对应,这也是文档结构为何如此紧凑的原因。
二、指标清单详解:memcached_deployment_size_undesired_count_total
文档列出的唯一指标:
- 指标名:
memcached_deployment_size_undesired_count_total - 说明:Deployment 规模未达到期望状态的总次数(Total number of times the deployment size was not as desired)
- 类型:Counter(计数器)
2.1 指标的语义
从 metrics.go 源码看,该指标的注释明确了业务含义:它统计"为了保证集群中 Deployment 副本数等于 CR(Custom Resource)的size字段所期望的数量,而不得不执行修正操作的次数"。
换句话说,当用户通过MemcachedCR 声明期望副本数后,控制器发现实际 Deployment 副本数与期望不一致、需要纠正时,该计数器就加一。这是典型的期望状态偏离检测指标,指标值持续增长通常意味着集群无法满足用户的资源诉求。
2.2 指标的定义结构:名称、帮助文本与类型
指标并非散落在代码各处,而是集中定义在一个"描述表"中:
type MetricDescription struct { Name string Help string Type string } var metricDescription = map[string]MetricDescription{ "MemcachedDeploymentSizeUndesiredCountTotal": { Name: "memcached_deployment_size_undesired_count_total", Help: "Total number of times the deployment size was not as desired.", Type: "Counter", }, }这样的设计有两点好处:
- 单一事实来源:指标名、帮助文本、类型只定义一处,
ListMetrics()可直接把这张表导出给文档生成器,杜绝文档与代码不同步; - 便于检索:
Type字段(此处为Counter)被metricsdocs直接渲染进文档,读者无需查源码即可知道该用 PromQL 的哪种函数处理。
2.3 指标的实际创建与注册
描述表之外,指标本体通过 Prometheus 客户端库创建,并注册进 controller-runtime 的全局注册表:
MemcachedDeploymentSizeUndesiredCountTotal = prometheus.NewCounter( prometheus.CounterOpts{ Name: metricDescription["MemcachedDeploymentSizeUndesiredCountTotal"].Name, Help: metricDescription["MemcachedDeploymentSizeUndesiredCountTotal"].Help, }, ) func RegisterMetrics() { metrics.Registry.MustRegister(MemcachedDeploymentSizeUndesiredCountTotal) }这里的关键点:
- 选用
prometheus.NewCounter而非 Gauge/Histogram,是因为该指标只增不减,语义上符合"累计发生次数"; - 注册目标是
sigs.k8s.io/controller-runtime/pkg/metrics提供的metrics.Registry,而非裸的 Prometheus 默认注册表。controller-runtime 会基于此注册表暴露/metrics端点,这正是 Operator 与 Prometheus 集成的标准入口。
2.4 指标在哪里被"打点"
从控制器实现看指标的实际触发点(memcached_controller.go):
size := memcached.Spec.Size if *found.Spec.Replicas != size { // Increment MemcachedDeploymentSizeUndesiredCountTotal metric by 1 monitoring.MemcachedDeploymentSizeUndesiredCountTotal.Inc() found.Spec.Replicas = &size if err = r.Update(ctx, found); err != nil { ... } }流程很清晰:Reconcile 逻辑比较"期望副本数(CR.Spec.Size)"与"当前 Deployment 实际副本数",不一致时先Inc()计数,再更新 Deployment 去纠正偏差。因此这个指标实际上度量的是调和循环(reconcile loop)中期望状态与真实状态的偏差频率,是判断 Operator 是否在"反复修补、却修不动"的关键信号。
三、指标文档的生成机制:make generate-metricsdocs
文档明确指出:开发新指标或修改旧指标后,需运行:
make generate-metricsdocs来重新生成文档。对应 Makefile 目标(memcached-operator 的 Makefile):
.PHONY: generate-metricsdocs generate-metricsdocs: mkdir -p $(shell pwd)/docs/monitoring go run -ldflags="${LDFLAGS}" ./monitoring/metricsdocs > docs/monitoring/metrics.md该目标做两件事:
- 确保
docs/monitoring目录存在; - 运行
monitoring/metricsdocs程序,把渲染出的文档整体覆盖写回docs/monitoring/metrics.md。
因此正确的工作流是:
- 在
monitoring/metrics.go的描述表中新增一条MetricDescription; - 在代码中创建对应的 Prometheus 指标对象并加入
RegisterMetrics(); - 在 Reconcile 逻辑中调用
Inc()/Add()打点; - 运行
make generate-metricsdocs让文档自动包含新指标; - 提交时同时提交代码与文档,保持两者一致。
3.1 生成模板:文档结构的源头
metricsdocs的模板(metricsdocs.go)逐字定义了文档的骨架:
# Operator Metrics This document aims to help users ... ## Operator Metrics List {{range .}} ### {{.Name}} {{.Help}} Type: {{.Type}}. {{end}} ## Developing new metrics ...这意味着任何新增的指标都会自动生成一个### 指标名小节,格式为"帮助文本 + Type: 类型",无需手动编辑文档。若你认为默认模板不合理,文档的指引是:按需修改monitoring/metricsdocs本身——这也是"文档由工具生成"模式的完整闭环。
3.2 从源码推断的设计要点
sort.Slice按指标名排序:保证多人协作提交时文档输出稳定、diff 干净;- 模板执行失败会
panic:宁可构建失败,也不产出残缺文档; - 输出通过 stdout 重定向写入文件:工具无副作用、可测试,也便于在 CI 中校验文档是否为最新。
四、让指标产生告警:PrometheusRule 与 runbook
仅有指标还不够,生产环境中通常需要配套告警规则。memcached-operator的 alerts.go 定义了名为memcached-operator-rules的PrometheusRuleCR,包含三类规则:
4.1 告警规则一:MemcachedDeploymentSizeUndesired
Alert: MemcachedDeploymentSizeUndesired Expr: increase(memcached_deployment_size_undesired_count_total[5m]) >= 3 For: (未设置,立即触发) Annotations: description: "Memcached-sample deployment size was not as desired more than 3 times in the last 5 minutes." Labels: severity: warning runbook_url: .../runbooks/MemcachedDeploymentSizeUndesired.md含义:最近 5 分钟内副本偏差修正次数达到 3 次及以上即告警(warning级别),并附带 runbook 链接。这正对应 2.4 节中 Reconcile 的Inc()打点——指标每增长一次,代表一次"期望与实际的偏差"。
4.2 告警规则二:MemcachedOperatorDown
Alert: MemcachedOperatorDown Expr: memcached_operator_up_total == 0 For: 5m Annotations: description: "No running memcached-operator pods were detected in the last 5 min." Labels: severity: critical runbook_url: .../runbooks/MemcachedOperatorDown.md含义:memcached_operator_up_total为 0 持续 5 分钟,即控制器 Manager 疑似宕机,属critical级别。注意这里的For: 5m表示需持续满足条件 5 分钟才触发,与第一条规则(无 For,立即触发)形成对比。
4.3 配套的 Recording Rule
Record: memcached_operator_up_total Expr: sum(up{pod=~'memcached-operator-controller-manager-.*'} or vector(0))这条规则把"控制器 Manager 是否在线"聚合成单一指标:Pod 在线则取值 1(来自up),全部下线时用vector(0)兜底为 0,从而让== 0的判断始终可计算。
4.4 runbook:告警的处置手册
两条告警都通过runbook_url标签指向对应 runbook:
- MemcachedDeploymentSizeUndesired.md:说明触发含义(可用副本数与期望配置不匹配)、影响(集群内分布式内存缓存不可用)、诊断步骤(定位
memcached-sample的命名空间、查看 Deployment 与控制器日志)、缓解方向(排查节点资源耗尽、内存不足、节点宕机等); - MemcachedOperatorDown.md:说明控制器 Manager Pod 超过 5 分钟无运行实例的影响(Memcached CR 生命周期管理完全失效),诊断命令(
kubectl describe deploy查看事件、kubectl get nodes排查节点 NotReady)与缓解思路。
runbook 的Meaning / Impact / Diagnosis / Mitigation四段式结构,是值得复用到自有 Operator 的标准告警文档模板。
五、规则自检:用 Prometheus 单元测试验证告警
为防告警规则"上线才发现写错",memcached-operator还内置了规则单测流水线,由三部分组成:
- rule-spec-dumper.go:将
monitoring.NewPrometheusRuleSpec()序列化为 JSON 写到临时文件,作为被测规则输入; - prom-rules-tests.yaml:Prometheus 官方单测格式的用例文件,通过
input_series喂入两个指标的时间序列,并在不同eval_time断言告警是否触发; - verify-rules.sh:编排整个校验过程。
测试用例的断言逻辑很典型:
eval_time: 4m(未满 5 分钟):期望MemcachedDeploymentSizeUndesired与MemcachedOperatorDown均不触发(exp_alerts: []),验证"过早不告警";eval_time: 5m:两条告警均触发,并逐字段校验 description、severity、runbook_url;eval_time: 14m:再次断言不触发——因为MemcachedDeploymentSizeUndesired用的是increase(...[5m]) >= 3,在时间窗内增长未达阈值时告警会自然熄灭;eval_time: 15m:两条告警再次触发。
运行方式:
make prom-rules-verify对应 Makefile 目标会先构建rule-spec-dumper,再执行verify-rules.sh把 dump 出的规则喂给 Prometheus 官方单测。这套"代码生成规则 → 单测校验 → 随 CI 执行"的流水线,可有效防止告警表达式回归。
六、如何扩展指标:从新增到文档化的完整清单
综合全文,为memcached-operator(或仿照它搭建的自有 Operator)新增一个指标的完整步骤:
定义描述:在 metrics.go 的
metricDescriptionmap 中新增MetricDescription{Name, Help, Type}条目,字段含义如下:字段 含义 示例值 NamePrometheus 指标名,遵循 _total/_count等命名约定memcached_deployment_size_undesired_count_totalHelp指标的人类可读说明,会原样渲染进文档 Total number of times the deployment size was not as desired.Type指标类型,文档中直接展示 Counter创建并注册指标:用
prometheus.NewCounter/NewGauge/NewHistogram创建对象,并在RegisterMetrics()中通过metrics.Registry.MustRegister(...)注册,确保/metrics端点可采集;业务打点:在 Reconcile 或业务函数中按语义调用
Inc()/Add()等;重新生成文档:运行
make generate-metricsdocs,新指标自动以### 指标名小节进入metrics.md;(可选)配套告警:在 alerts.go 中新增规则,并同步编写 runbook;
(可选)补充单测:在
prom-rules-tests.yaml中为告警表达式新增input_series与alert_rule_test断言,运行make prom-rules-verify验证。
七、核心文件速查
| 作用 | 仓库相对路径 |
|---|---|
| 指标文档(本文讲解对象) | docs/monitoring/metrics.md |
| 指标定义、注册与列表导出 | monitoring/metrics.go |
| 文档生成工具(模板渲染) | monitoring/metricsdocs/metricsdocs.go |
| 文档生成 Makefile 目标 | Makefile |
| 指标打点位置(Reconcile) | internal/controller/memcached_controller.go |
| 告警与 Recording Rule 定义 | monitoring/alerts.go |
| runbook:副本偏差告警 | docs/monitoring/runbooks/memcachedDeploymentSizeUndesired.md |
| runbook:Operator 宕机告警 | docs/monitoring/runbooks/memcachedOperatorDown.md |
| 规则单测用例与流水线 | prom-rule-ci/prom-rules-tests.yaml、prom-rule-ci/verify-rules.sh |
结语
metrics.md虽短,却浓缩了一套完整的 Operator 可观测性工程范式:指标集中在描述表中定义、文档由模板工具自动生成、Counter 在 Reconcile 中打点、告警规则与 runbook 配套、规则通过 Prometheus 单测自检。理解这份文档的生成机制,等于理解了如何让"指标代码、指标文档、告警规则"三者始终保持同步——这正是用 operator-sdk 构建生产级 Operator 时最容易被忽视、却最值得复用的实践之一。
- 云原生
- 后端
- 开发工具
- 微服务
【免费下载链接】operator-sdk
SDK for building Kubernetes applications. Provides high level APIs, useful abstractions, and project scaffolding.
相关推荐
Safety-DB入门教程:如何使用Python包安全数据库
Safety DB入门教程:如何使用Python包安全数据库 Safety DB是一个Python包安全数据库,它收集了已知的Python包安全漏洞信息,帮助开
Operator SDK Helm Operator 实战:memcached Helm Chart 部署、配置与升级指南
Operator SDK Helm Operator 实战:memcached Helm Chart 部署、配置与升级指南 本指南围绕 Operator SDK
云原生后端开发工具微服务Prometheus Operator监控Ruby应用:性能指标采集实战
Prometheus Operator监控Ruby应用:性能指标采集实战 在Kubernetes环境中监控Ruby应用时,你是否遇到过指标采集配置复杂、监控目标
云原生可观测性
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考