☰
OpenShift 基础设施组件监控插桩最佳实践:healthz / metrics / pprof 端点规范与实现验证
2026/9/25 5:39:37 网站建设 项目流程
  • 测试
  • 云原生
  • 质量保障

【免费下载链接】origin

Conformance test suite for OpenShift

项目地址:https://gitcode.com/gh_mirrors/or/origin
点击查看免费下载

导读

本文基于 OpenShift Origin(openshift/origin)仓库中的官方提案文档 instrumentation-of-services.md,系统讲解 OpenShift 集群中所有基础设施组件(路由器、API Server、OAuth 服务器、监控组件等)必须遵循的服务插桩(instrumentation)规范:如何通过统一的/healthz、/metrics、/healthz/ready与/debug/pprof/*端点暴露存活状态、就绪状态、业务指标与性能画像,并给出 Prometheus 指标命名、安全认证与异常豁免的完整要求。读完本文,你将掌握为 OpenShift 组件接入健康检查、监控指标与性能剖析的标准接口约定,并能在本仓库的 e2e 测试与监控测试源码中找到对应的可验证实现。

一、统一端点约定:所有 OpenShift 组件必须暴露的接口

提案文档首先给出了一个硬性要求:所有 OpenShift 组件 MUST 在其公共 HTTPS 端口(若无 HTTPS 端口则用公共 HTTP 端口)上暴露以下两个端点:

端点响应约定语义
/healthz返回 HTTP 200 与文本ok表示实例进程存活(liveness)
/metrics以 Prometheus 文本格式返回一组合理的指标用于刻画该服务器的健康与性能状态

通过 Service 或 Route 暴露的组件,MUST 额外暴露以下端点:

端点响应约定语义
/healthz/ready返回 HTTP 200 与文本ok表示实例已就绪,可以开始接收网络流量(readiness)

此外还有两条补充规则:

  • 仅提供 TCP 端点的组件:应监听一个独立的端口,并在该端口上暴露上述对应的检查端点(即把 HTTP 健康检查挂在独立端口上,避免与业务 TCP 端口冲突)。
  • 已有社区等价端点的组件:若组件从上游社区原样(as-is)采用了与上述端点等价的现有端点(例如 kube-apiserver 的/readyz),则 MAY 直接沿用,不必重复实现一套。

从本仓库的测试代码可以印证这些约定在真实组件中的落地情况。以集群路由器(HAProxy router)为例,test/extended/router/metrics.go 中的 e2e 测试明确断言:路由器必须在 metrics 端口上暴露健康检查,测试通过http://<host>:<metricsPort>/healthz期望返回 200。测试在BeforeEach中从openshift-ingress命名空间的router-internal-defaultEndpoints 里按端口名metrics提取 metrics 端口号:

// 从 Endpoints 中按名称提取 metrics 端口 for _, port := range subset.Ports { if port.Name == "metrics" { metricsPort = port.Port break } } o.Expect(metricsPort).NotTo(o.BeZero())

而test/extended/router/certs.go、test/extended/router/scoped.go、test/extended/router/stress.go等多处 e2e 测试(如 certs.go)则将Path: "/healthz/ready"配置为后端 Pod 的 HTTP 就绪探针(readinessProbe),这正是“通过 Service/Route 暴露的组件必须提供/healthz/ready”这一规则在探针场景中的直接应用。

对于“社区等价端点”的例外条款,kube-apiserver 是最典型的例子:上游 Kubernetes 的 apiserver 提供的是/readyz(而非/healthz/ready),本仓库的 test/extended/apiserver/health_endpoints.go 即通过readyz?verbose=true来验证 apiserver 各子检查项的就绪状态,并配合 test/extended/apiserver/graceful_termination.go 断言 API 负载均衡器会跟随/readyz停止/恢复向 apiserver 发送请求。

二、Metrics 指标:为什么选 Prometheus 格式

文档明确说明选用 Prometheus 格式的两点理由:

  1. 与上游 Kubernetes 社区保持一致;
  2. 它是 Go 生态系统的天然契合格式(Go 官方指标库即输出 Prometheus 文本格式)。

因此,对于不原生提供 Prometheus 端点的 COTS(商用现货)软件,规范要求使用适配器(adapter)来暴露 Prometheus 指标——适配器既可以打进其进程内,也可以作为sidecar 容器伴随运行;Java 组件虽然可以使用 JMX,但仍然推荐适配到 Prometheus 格式。

指标内容:度量业务而非进程琐碎

文档强调,要暴露的指标应代表服务本身的业务度量(business measurements),并引用了 Prometheus 官方 instrumentation 实践指南:

  • 如果组件的职责是处理请求,就捕获请求的计数(count)、耗时(duration)与类型(types);
  • 如果组件内部有队列,就报告队列深度(queue depth)与队列吞吐(throughput);
  • 标签与命名遵循 Prometheus 官方 naming 实践(如_total后缀用于计数器、单位嵌入名称等)。

若指标值或标签包含敏感信息,应考虑匿名化(anonymizing)或归类(categorizing);若信息本质上是多租户(multi-tenant)的,则继续阅读下文安全一节。

Go 程序的落地路径

  • Go 程序应通过现有 Prometheus 客户端库轻松集成(例如github.com/prometheus/client_golang/prometheus);
  • 优先使用现成的 Prometheus exporter;只有在特定框架下适配指标成本过高、或无法合入上游时,才考虑自行适配。

本仓库 e2e 测试对路由器 metrics 端点的断言可以作为“业务度量”的极佳范例:test/extended/router/metrics.go 验证了以下指标族:

  • 路由/后端维度:haproxy_backend_connections_total、haproxy_server_http_responses_total(带code标签区分 2xx/5xx)、haproxy_server_connections_total、haproxy_server_bytes_in_total/haproxy_server_bytes_out_total;
  • 通用 exporter 指标:haproxy_up、haproxy_exporter_scrape_interval、haproxy_exporter_total_scrapes、haproxy_exporter_csv_parse_failures;
  • 进程维度:haproxy_process_resident_memory_bytes、haproxy_process_max_fds;
  • 路由器自身模板渲染耗时:template_router_reload_seconds、template_router_write_config_seconds。

测试还使用 Prometheus 官方expfmt解析器(p.TextToMetricFamilies)将抓取到的文本转换为 MetricFamily 结构再逐项断言,这正是文档“用 Prometheus 格式暴露业务指标”约定的端到端验证——从端点抓取、格式解析到语义断言一条链路全部覆盖。

三、Profiling 性能剖析:/debug/pprof/*的使用边界

对于高流量(high traffic)或已知性能瓶颈且使用 Go 编写的组件,文档要求(SHOULD)暴露/debug/pprof/*系列端点。

同时有一个不可妥协的前提:这些端点 MUST 通过认证与授权保护,因为性能剖析数据可能导致信息泄露(information disclosure)——例如 goroutine 栈中的变量、堆内存中的字符串等都可能泄漏内部状态。

路由器再次提供了完整实现样板:test/extended/router/metrics.go 中的 e2e 测试断言:

  1. 未提供用户名密码访问http://<host>:<metricsPort>/debug/pprof/heap必须返回401 或 403;
  2. 使用认证凭据访问/debug/pprof/heap?debug=1时,响应内容必须包含# runtime.MemStats标记(即 Go 运行时堆剖析输出的标准头)。
g.By("preventing access without a username and password") err := expectURLStatusCodeExec(ns, execPodName, fmt.Sprintf("http://%s/debug/pprof/heap", net.JoinHostPort(host, strconv.Itoa(int(metricsPort)))), 401, 403) o.Expect(err).NotTo(o.HaveOccurred()) g.By("at /debug/pprof") results, err := getAuthenticatedURLViaPod(ns, execPodName, fmt.Sprintf("http://%s/debug/pprof/heap?debug=1", net.JoinHostPort(host, strconv.Itoa(int(metricsPort)))), username, password) o.Expect(err).NotTo(o.HaveOccurred()) o.Expect(results).To(o.ContainSubstring("# runtime.MemStats"))

这一测试完整落地了“pprof 必须认证 + 认证后可读取剖析数据”的双重要求。

四、安全:健康检查与指标端点的访问控制

文档在安全一节给出了三条明确原则:

1. 健康检查:本地可达即可

健康检查(/healthz、/healthz/ready)必须能在 Pod 或本地网络上被访问,这样远端探针代理(如 kubelet、监控 Agent)才能访问它们。对于更复杂、可能泄露密码、磁盘路径、用户身份信息等敏感数据的检查,则 MAY 引入认证与授权。

2. Metrics 端点:泄露租户信息时 MUST 认证

如果 metrics 端点会泄露租户信息(pod 名、service 名、namespace 名或用户身份信息),则SHOULD 使用认证保护。文档给出的推荐做法是:

  • 使用BASIC 认证,密码通过环境变量或 Secret提供——并明确点名“参考路由器的实现”;
  • 对于系统级组件(如 controller manager、scheduler、kubelet、router),可以可选地利用集群内生的授权能力(如 kubelet 的 authn/authz、apiserver 的 RBAC)。

路由器的实现恰好是本仓库中可以直接引用的范例:test/extended/router/metrics.go 展示了凭据的来源——从openshift-ingress命名空间读取名为router-stats-default的 Secret,其中包含statsUsername与statsPassword两个字段;同时测试还创建一个prometheus-k8sServiceAccount 的 bearer token 用于抓取。随后测试断言:

  • 未认证访问/metrics返回401 或 403(见 metrics.go);
  • 用router-stats-default提供的用户名密码认证后可以读取指标(metrics.go)。

OAuth 服务器同样验证了这一安全模型:test/extended/oauth/requestheaders.go 断言/metrics端点“匿名不可见”“未认证用户不应能访问”,而 requestheaders.go 进一步验证/metrics需要“有权访问该端点的用户”的 token。

3. 泄露租户信息的 metrics 必须走 TLS

文档特别强调:暴露租户信息并使用认证的组件,MUST 使用 HTTPS 提供 metrics——这是一条通用基础设施要求:所有用户信息都必须经 TLS 传输。

本仓库中与之呼应的佐证:监控系统对路由器 metrics 的抓取目标 URL 即为https://.*/metrics(test/extended/router/metrics.go),由router-internal-default这个 Prometheus job 以 HTTPS 抓取;同时 test/extended/apiserverauth/apiserver_util.go 中 apiserver 的/healthz也是通过https://地址访问的。

五、Push Metrics:为什么应作为最后手段

部分组件可能需要向远端 Agent推送较大量的指标。文档对此的态度非常明确:这在技术上是允许的,但 SHOULD 作为最后手段(last resort)。

理由如下:

  • 设计良好的 Prometheus 端点应能干净地扩展到约 1k–10k 个租户,这已经覆盖当前集群规模的边界("within our cluster size bounds today");
  • **推送指标需要申请例外(exception)**才能实施。

也就是说,Pull 模型(Prometheus 主动抓取)是默认且推荐的方式,Push 模型只有在 Pull 确实无法满足(例如指标量极大、组件生命周期过短等)时才允许,并且必须走例外审批流程。

本仓库对“Pull 抓取”的验证同样充分:should enable openshift-monitoring to pull metrics测试(test/extended/router/metrics.go)调用 Prometheus 的/api/v1/targets?state=active接口,断言router-internal-default这个 job 存在一个 health 为up、抓取 URL 匹配^https://.*/metrics$的活动 target——即集群监控系统确实通过 Pull 方式从路由器拉取指标。

六、Exceptions 例外:可被豁免,但缺失即 Bug

最后,文档给出了一个务实而强硬的收尾条款:

可以对这些要求授予例外(exceptions),但无法暴露这些信息的组件就无法被监控。请把这类信息的缺失视为一个 Bug。

这意味着:

  • 例外申请是存在且允许的(尤其针对 Push Metrics 场景);
  • 但任何无法提供健康检查、就绪检查或指标端点的组件,本质上都会变成监控盲区;
  • 因此团队应当把“组件缺少可观测信息”当作缺陷来处理,而不是长期接受。

七、规范落地全景:从提案到测试的印证路径

为了帮助读者在本仓库中继续深挖,下表汇总了本文所有关键规则对应的源码/测试证据位置:

规范条款仓库中的验证/实现位置
组件须暴露/healthztest/extended/router/metrics.go(路由器 metrics 端口/healthz返回 200);test/extended/apiserverauth/apiserver_util.go(apiserver HTTPS/healthz)
Service/Route 暴露组件须有/healthz/readytest/extended/router/certs.go、scoped.go、stress.go(作为后端 readinessProbe 路径)
社区等价端点可直接沿用(/readyz)test/extended/apiserver/health_endpoints.go、graceful_termination.go
/metrics业务度量 + Prometheus 格式test/extended/router/metrics.go(haproxy_*、template_router_*等指标族断言)
/debug/pprof/*必须认证test/extended/router/metrics.go(未认证 401/403,认证后返回# runtime.MemStats)
metrics 泄露租户信息须 BASIC 认证(Secret 提供密码)test/extended/router/metrics.go(router-stats-defaultSecret 的statsUsername/statsPassword)
未认证访问/metrics被拒绝test/extended/router/metrics.go;test/extended/oauth/requestheaders.go
监控系统 Pull 抓取 HTTPS metricstest/extended/router/metrics.go(target URL 匹配^https://.*/metrics$)
组件健康端点的持续监控(disruption 场景)pkg/monitortests/network/disruptioningress/monitortest.go(对 oauth/console 等 route 的/healthz做可用性监控)

结语:给组件开发者的检查清单

把提案文档浓缩成一份可直接对照的验收清单:

  1. 组件是否在公共 HTTPS(或 HTTP)端口上暴露了/healthz(返回 200 +ok)与/metrics(Prometheus 格式)?
  2. 若组件通过 Service/Route 暴露,是否额外提供了/healthz/ready?
  3. 仅 TCP 端点的组件,是否在独立端口上挂出了上述 HTTP 检查?
  4. 指标是否刻画了业务度量(请求计数/耗时/类型、队列深度/吞吐),而非仅仅进程琐碎?
  5. 指标或标签中是否含敏感信息?是否已匿名化/归类?
  6. 指标是否泄露租户信息?若是,是否已用 BASIC 认证(密码来自环境变量或 Secret)保护,且通过 HTTPS 提供服务?
  7. Go 高流量/瓶颈组件是否暴露了经认证的/debug/pprof/*?
  8. 若无法满足上述任何一项,是否已申请例外?——如果既无法暴露信息也没有例外,请把它当作 Bug 修复,因为无法被监控的组件等于运行在黑盒里。

遵循这套插桩规范,OpenShift 中的每一个基础设施组件都能被 kubelet 探针、Prometheus 抓取与集群监控链路完整覆盖,这也是整个 OpenShift 集群可观测性体系能够运转的地基。

  • 测试
  • 云原生
  • 质量保障

【免费下载链接】origin

Conformance test suite for OpenShift

项目地址:https://gitcode.com/gh_mirrors/or/origin
点击查看免费下载
上一篇:告别夜间护眼烦恼:awesome-shadcn-ui暗黑模式实现全解析
下一篇:ComfyUI极速出图三步走:Boogu-Image Turbo模型新手友好实战指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询