- 指标监控
- 可观测性
- 告警
- 运维
【免费下载链接】zabbix
Real-time monitoring of IT components and services, such as networks, servers, VMs, applications and the cloud.
导读
本文围绕 Zabbix 官方模板Kubernetes Scheduler by HTTP展开,介绍如何在不依赖任何外部脚本的前提下,通过 HTTP agent 从 Kubernetes Scheduler 的/metricsPrometheus 端点批量采集调度器运行指标,并完成内存、CPU、REST Client 请求、调度成功率与调度延迟(分位数)的全方位监控与告警。读完本文,你将掌握该模板的部署前置条件、宏参数配置、监控项与预处理链路的内部原理,以及调度延迟直方图的自动发现与分位数计算机制。
模板概览:为什么用 HTTP 采集 Scheduler 指标
Kubernetes Scheduler by HTTP是 Zabbix 为 Kubernetes 控制面组件提供的官方模板之一,位于仓库 templates/app/kubernetes_http/kubernetes_scheduler_http/ 目录下。它的核心设计思路是:
- 零外部脚本:所有指标都由 Zabbix Server/Proxy 内置的 HTTP agent 直接抓取,无需在集群内部署 exporter 或自定义采集脚本;
- 批量采集:模板通过单个 HTTP 请求抓取 Scheduler 的
/metrics端点原始文本,再借助Prometheus pattern / Prometheus to JSON预处理能力,将原始指标拆解为数十个独立监控项,实现"一次抓取、多处复用"(即 README 中所说的Zabbix bulk data collection)。
该模板的 YAML 定义文件为 template_kubernetes_scheduler.yaml,由官方模板工具 "Templator" 生成,wizard_ready标记为YES,即模板可直接在 Zabbix 8.0 的模板向导中使用。模板自带Scheduler overview仪表盘,包含 "General"(内存、REST Client 查询速率、调度尝试速率)与 "Latencies"(Binding、E2e、Scheduling algorithm 三类延迟)两个页面。
适用版本与已验证环境
- Zabbix 版本要求:8.0 及以上(README 明确标注 "Zabbix version: 8.0 and higher"),模板导出 YAML 头部的
zabbix_export: version: '8.0'也印证了这一点; - 已验证的 Kubernetes 版本:Kubernetes Scheduler 1.19.10;
- 注意事项:部分指标可能因 Scheduler 实例的版本与配置差异而无法采集,模板对此已在 README 中明确提示。
部署前置与 Setup
1. 配置 Scheduler 的绑定地址(关键前提)
Scheduler 的指标端点默认绑定在回环地址,Zabbix 需要通过 HTTP 访问该端点,因此可能需要为 kube-scheduler 设置--binding-address选项,使其监听 Zabbix Server/Proxy 可达的地址。对使用kubeadm创建的集群,只需修改静态 Pod 清单文件(修改会立即生效):
/etc/kubernetes/manifests/kube-scheduler.yaml2. 准备 API 鉴权 Token
模板通过Authorization: Bearer {$KUBE.API.TOKEN}请求头访问/metrics端点(见 YAML 中Get Scheduler metrics监控项的headers定义)。在 kubernetes_http 目录总览 中,官方给出了通过 Helm Chart 部署后获取 Token 的方式:
kubectl get secret zabbix-zabbix-helm-chart -n monitoring -o jsonpath={.data.token} | base64 -d3. 导入模板并创建主机
- 将 template_kubernetes_scheduler.yaml 导入 Zabbix;
- 为 Scheduler 创建主机并关联
Kubernetes Scheduler by HTTP模板,为主机配置 Zabbix 可访问的接口(HTTP 监控项需要主机接口); - 在模板或主机级覆盖以下宏:{$KUBE.SCHEDULER.SERVER.URL}、{$KUBE.API.TOKEN},并按需调整触发器阈值宏(详见下一节)。
宏参数详解
模板共定义了 4 个用于采集与告警的宏(README 中均列出),加上 YAML 中macros段补充的配置元数据(含 secret 类型、输入校验正则与优先级),汇总如下:
| 宏 | 描述 | 默认值 | YAML 中的配置细节 |
|---|---|---|---|
| {$KUBE.API.TOKEN} | API 授权 Token(Bearer Token) | 空 | 类型为SECRET_TEXT(在 Zabbix 界面中作为加密文本存储),required: YES,优先级 1 |
| {$KUBE.SCHEDULER.SERVER.URL} | Scheduler metrics 端点 URL | https://localhost:10259/metrics | 普通 TEXT 宏,优先级 2,对应 HTTP 监控项的url字段 |
| {$KUBE.SCHEDULER.HTTP.CLIENT.ERROR} | REST Client 请求失败(5xx)告警阈值 | 2 | TEXT 宏,优先级 3,校验正则^-?([0-9]+|(([0-9]+)\.([0-9]+)))$,即允许整数或小数,不小于 0 |
| {$KUBE.SCHEDULER.UNSCHEDULABLE} | "unschedulable" 调度失败告警阈值 | 2 | TEXT 宏,优先级 4,位于 "Thresholds" 配置分组,同样带数值校验正则 |
| {$KUBE.SCHEDULER.ERROR} | "error" 调度失败告警阈值 | 2 | TEXT 宏,优先级 5,位于 "Thresholds" 配置分组,带数值校验正则 |
实操提示:
{$KUBE.SCHEDULER.SERVER.URL}默认指向https://localhost:10259/metrics,这是 kube-scheduler 默认的安全端口(10258 为旧版非安全端口,1.19 及以后默认使用 10259)。若你的集群通过--secure-port或端口转发暴露端点,务必在宏中覆盖为实际可达地址;Token 宏建议在 Zabbix 前端中以 Secret 类型填写,避免明文出现在配置导出文件中。
监控项体系:从原始抓取到派生指标
模板的监控项以1 个 HTTP 主监控项 + 16 个依赖型监控项的结构组织,所有依赖项都以kubernetes.scheduler.get_metrics为master_item(即 YAML 中的master_item: key: kubernetes.scheduler.get_metrics),从同一份抓取结果中取值。
主监控项
| 名称 | 类型 | Key | 关键配置 |
|---|---|---|---|
| Get Scheduler metrics | HTTP agent | kubernetes.scheduler.get_metrics | 请求{$KUBE.SCHEDULER.SERVER.URL},timeout: 15s,value_type: TEXT,history: 0(原始文本不保留历史,仅作为派生源);请求头Authorization: Bearer {$KUBE.API.TOKEN};预处理为CHECK_NOT_SUPPORTED(参数-1),即任意错误都标记为不支持并丢弃该值 |
进程级指标(依赖项)
| 名称 | Key | 单位 | 预处理链路 |
|---|---|---|---|
| Virtual memory, bytes | kubernetes.scheduler.process_virtual_memory_bytes | B | Prometheus patternVALUE(process_virtual_memory_bytes),失败时 Discard value |
| Resident memory, bytes | kubernetes.scheduler.process_resident_memory_bytes | B | Prometheus patternVALUE(process_resident_memory_bytes),失败时 Discard value |
| CPU | kubernetes.scheduler.cpu.util | % | VALUE(process_cpu_seconds_total)→Change per second→Custom multiplier 100(把累加的 CPU 秒数换算为每秒使用比例,再乘以 100 得到百分比) |
| Goroutines | kubernetes.scheduler.go_goroutines | 无 | Prometheus patternSUM(go_goroutines),失败时 Discard value |
| Go threads | kubernetes.scheduler.go_threads | 无 | VALUE(go_threads),失败时 Discard value |
| Fds open | kubernetes.scheduler.open_fds | 无 | VALUE(process_open_fds),失败时 Discard value |
| Fds max | kubernetes.scheduler.max_fds | 无 | VALUE(process_max_fds),失败时 Discard value |
REST Client 请求指标(依赖项)
模板按 HTTP 状态码维度对rest_client_requests_total{code =~ "2.."}等 Prometheus 计数器做按秒求速率(Change per second)处理,共 4 个监控项:
| 名称 | Key | Prometheus 模式 |
|---|---|---|
| REST Client requests: 2xx, rate | kubernetes.scheduler.client_http_requests_200.rate | SUM(rest_client_requests_total{code =~ "2.."}) |
| REST Client requests: 3xx, rate | kubernetes.scheduler.client_http_requests_300.rate | SUM(rest_client_requests_total{code =~ "3.."}) |
| REST Client requests: 4xx, rate | kubernetes.scheduler.client_http_requests_400.rate | SUM(rest_client_requests_total{code =~ "4.."}) |
| REST Client requests: 5xx, rate | kubernetes.scheduler.client_http_requests_500.rate | SUM(rest_client_requests_total{code =~ "5.."}) |
以上每个监控项都带component: rest与http-code: xxx标签,可用于图形筛选与仪表盘聚合。
调度尝试指标(依赖项)
对scheduler_schedule_attempts_total按result标签拆分并计算每秒速率:
| 名称 | Key | Prometheus 模式 | 语义 |
|---|---|---|---|
| Schedule attempts: scheduled | kubernetes.scheduler.scheduler_schedule_attempts.scheduled.rate | SUM(scheduler_schedule_attempts_total{result = "scheduled"}) | 每秒成功调度 Pod 的次数 |
| Schedule attempts: unschedulable | kubernetes.scheduler.scheduler_schedule_attempts.unschedulable.rate | SUM(scheduler_schedule_attempts_total{result = "unschedulable"}) | 每秒因资源不足等原因无法调度的次数 |
| Schedule attempts: error | kubernetes.scheduler.scheduler_schedule_attempts.error.rate | SUM(scheduler_schedule_attempts_total{result = "error"}) | 每秒因内部错误调度失败次数 |
告警触发器
模板内置 3 个 Warning 级别触发器,全部基于5 分钟窗口的min()聚合与阈值宏比较,可有效过滤瞬时抖动:
| 触发器名称 | 表达式 | 说明 | 故障标签 |
|---|---|---|---|
| Kubernetes Scheduler: Too many REST Client errors | min(/Kubernetes Scheduler by HTTP/kubernetes.scheduler.client_http_requests_500.rate,5m)>{$KUBE.SCHEDULER.HTTP.CLIENT.ERROR} | Scheduler 的 REST Client 请求 5xx 错误率过高,表明其与 API Server 通信异常 | scope: availability |
| Kubernetes Scheduler: Too many unschedulable pods | min(/Kubernetes Scheduler by HTTP/kubernetes.scheduler.scheduler_schedule_attempts.unschedulable.rate,5m)>{$KUBE.SCHEDULER.UNSCHEDULABLE} | "unschedulable" 即 Pod 无法被调度(如节点资源不足、污点/容忍不匹配) | scope: performance |
| Kubernetes Scheduler: Too many schedule attempts with errors | min(/Kubernetes Scheduler by HTTP/kubernetes.scheduler.scheduler_schedule_attempts.error.rate,5m)>{$KUBE.SCHEDULER.ERROR} | "error" 表示调度器内部问题,属于更严重的故障信号 | scope: performance |
三个触发器的event_name均会动态展开为 "over {$...} for 5m" 形式,便于在告警消息中直接看到触发阈值。三者的默认阈值宏均为2,即 5 分钟内对应速率均值超过 2 次/秒才告警;YAML 中通过regex约束其值必须为数值且不小于 0。
调度延迟监控:三个直方图的自动发现与分位数计算
模板最具技术深度的部分,是用三条 LLD 规则(依赖型)对 Scheduler 暴露的 Prometheus histogram 类型指标做发现与分位数计算,覆盖调度器的完整延迟链路:
| LLD 规则 | Key | 描述 | Prometheus to JSON 查询 |
|---|---|---|---|
| Scheduling algorithm histogram | kubernetes.scheduler.scheduling_algorithm.discovery | 调度算法耗时分布(选点过程) | {__name__=~ "scheduler_scheduling_algorithm_duration_seconds_*"} |
| Binding histogram | kubernetes.scheduler.binding.discovery | Binding(绑定)耗时分布 | {__name__=~ "scheduler_binding_duration_seconds_*"} |
| e2e scheduling histogram | kubernetes.controller.e2e_scheduling.discovery | 端到端调度耗时分布(算法 + Binding) | {__name__=~ "scheduler_e2e_scheduling_duration_*", result =~ ".*"} |
发现链路的三个预处理步骤
以 Binding histogram 为例,其 LLD 规则预处理依次为:
- Prometheus to JSON:将
scheduler_binding_duration_seconds_*系列指标转为 JSON 数组; - JavaScript:遍历 JSON,对
*_count系列生成{#TYPE}: 'totals'宏,对*_bucket系列提取{#LE}桶上界,产出 LLD 宏数据:JSON.parse(value).forEach(function (item) { if (item.name === "scheduler_binding_duration_seconds_count"){ result.push({'{#TYPE}': 'totals', '{#SINGLETON}': ''}); } else if (item.name === "scheduler_binding_duration_seconds_bucket"){ result.push({'{#TYPE}': 'buckets', '{#LE}': item.labels.le}); } }); return JSON.stringify(result); - Discard unchanged with heartbeat: 3h:当发现结果 3 小时内无变化时丢弃,避免重复入库。
随后通过两条LLD overrides过滤:{#TYPE}为buckets的启用 "bucket" 原型,{#TYPE}为totals的启用非 bucket 原型(见 YAML 中overrides段的LIKE/NOT_LIKE规则)。
桶原型与分位数计算原型
每条直方图 LLD 规则下都有两类监控项原型:
- Bucket 原型(依赖项,如
kubernetes.scheduler.binding_duration[{#LE}]):用 Prometheus pattern 抓取对应le桶的累计计数,history: 1h、trends: '0',仅服务于分位数计算; - 分位数原型(计算项 Calculated):p50 / p90 / p95 / p99 四个分位,统一使用 Zabbix 计算监控项函数
bucket_percentile,例如:bucket_percentile(//kubernetes.scheduler.binding_duration[*],5m,50) bucket_percentile(//kubernetes.scheduler.binding_duration[*],5m,90) bucket_percentile(//kubernetes.scheduler.binding_duration[*],5m,95) bucket_percentile(//kubernetes.scheduler.binding_duration[*],5m,99)
该函数在 Zabbix 表达式引擎中实现,见 expr_eval.c(其中MATCH_STRING("bucket_percentile", ...)及对应求值分支),其原理是:从 Prometheus histogram 的累计桶计数中,在 5 分钟窗口内按桶间差分估算出指定分位的延迟秒数,输出单位为s。同理,Scheduling algorithm 与 e2e 两条规则分别通过kubernetes.scheduler.scheduling_algorithm_duration[*]与kubernetes.scheduler.e2e_scheduling_bucket[*,"{#RESULT}"]计算对应分位。e2e 规则额外按{#RESULT}宏区分scheduled/unschedulable/error等调度结果,因此其分位原型 Key 形如kubernetes.scheduler.e2e_scheduling_p90["{#RESULT}"]。
注意:分位原型默认
discover: NO_DISCOVER,需由 LLD overrides 按{#TYPE}匹配后显式启用,因此 LLD 规则的实际产出数量是动态的、与端点暴露的桶数量一致。
延迟图形原型
三条规则各带一个图形原型,将 p50/p90/p95/p99 四条曲线叠加,分别命名为Kubernetes Scheduler: [{#SINGLETON}]Binding latency、Kubernetes Scheduler: [{#SINGLETON}]Scheduling algorithm duration、Kubernetes Scheduler: ["{#RESULT}"] E2e latency。结合内置Scheduler overview仪表盘的 "Latencies" 页(按 1 列布局依次展示这三个图形原型),即可在一个页面内观察调度延迟全链路的分位趋势。
底层原理:Prometheus 预处理如何落地
模板中大量使用的Prometheus pattern与Prometheus to JSON是 Zabbix 8.0 预处理框架的原生能力,其执行入口在 pp_execute.c,内部以ZBX_PREPROC_PROMETHEUS_PATTERN、ZBX_PREPROC_PROMETHEUS_TO_JSON两个预处理类型分发处理(另有pp_cache.c负责结果缓存)。这意味着:
- 所有派生监控项都不产生额外网络请求,完全复用主监控项
kubernetes.scheduler.get_metrics的抓取文本,这正是 "Most of the metrics are collected in one go" 的实现基础; - 当某条 Prometheus pattern 在原始文本中匹配不到时,多数监控项配置了
⛔️Custom on fail: Discard value(即error_handler: DISCARD_VALUE),避免因单指标缺失导致监控项进入不支持状态或产生错误数据——这也解释了 README 中"部分指标可能因版本/配置差异而采集不到"的容错设计。
使用注意事项与排障清单
- 网络可达性:若 Zabbix Proxy 无法直连 Scheduler 的 10259 端口,务必先修改
/etc/kubernetes/manifests/kube-scheduler.yaml中的--binding-address(或使用 kube-proxy / 端口转发方案),否则主监控项将因连接失败被CHECK_NOT_SUPPORTED丢弃; - Token 有效性:
{$KUBE.API.TOKEN}使用 Bearer 方案(YAML 中请求头为Authorization: Bearer ...),Token 过期或错误会导致 401,表现为 REST Client 4xx 指标持续增长并触发相关告警; - 阈值语义:
{$KUBE.SCHEDULER.UNSCHEDULABLE}与{$KUBE.SCHEDULER.ERROR}均为 5 分钟窗口内的速率均值上限,在业务高峰期若出现大量 Pending Pod,可按实际调度频率调大阈值避免误报; - 指标缺失:不同 Kubernetes 版本暴露的 histogram 桶与标签可能不同(如 e2e 的
result标签),若 LLD 未发现任何原型,请先用curl -k -H "Authorization: Bearer <token>" https://<scheduler>:10259/metrics核对端点输出是否符合模板的 Prometheus 查询模式。
小结
Kubernetes Scheduler by HTTP模板完整覆盖了 Scheduler 进程资源(内存/CPU/文件描述符/Go 运行时)、REST Client 通信质量(2xx~5xx 请求速率)、调度结果(scheduled/unschedulable/error 速率)以及调度延迟分位(算法耗时、Binding 耗时、端到端耗时)四个维度,并自带告警与仪表盘。其"单次 HTTP 抓取 + Prometheus 预处理 + bucket_percentile 分位计算 + LLD 动态发现"的组合,为同类 Kubernetes 控制面组件(API Server、Controller Manager、Kubelet 等,见 kubernetes_http 目录总览)的监控模板提供了可复用的标准范式。导入模板后,只需按上文配置好端点 URL 与 API Token,即可获得对调度器运行状态的实时可观测能力。
- 指标监控
- 可观测性
- 告警
- 运维
【免费下载链接】zabbix
Real-time monitoring of IT components and services, such as networks, servers, VMs, applications and the cloud.
相关推荐
Zabbix 监控 Kubernetes API Server 实战:基于 HTTP 的官方模板深入解析
Zabbix 监控 Kubernetes API Server 实战:基于 HTTP 的官方模板深入解析 本文基于仓库 templates/app/kubern
指标监控可观测性告警运维DeepSeek Harness Desktop 布局所有权架构:Advanced / Extended 模式下的 `layout` 服务独占与冲突拒绝
DeepSeek Harness Desktop 布局所有权架构:Advanced / Extended 模式下的 layout 服务独占与冲突拒绝 本篇技术指
指标监控可观测性告警运维@toon-format/cli 完全指南:JSON 与 TOON 双向转换、Token 统计与流式处理实战
@toon format/cli 完全指南:JSON 与 TOON 双向转换、Token 统计与流式处理实战 导读 @toon format/cli 是 TOO
指标监控可观测性告警运维
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考