7. Prometheus无法采集容器metrics
一个普通问题的排查流程,排查过程中摸索了一遍 prometheus-operator 如何处理业务逻辑,这里做下记录。
K8s 集群的监控组件采用 prometheus-operator 管理,operator 和相关 CRD 通过 helm 安装,operator 孵化出 alertmanager、prometheus、node-exporter 等组件。
问题出现在一个启用 IPv6 的客户集群,现象是可以查看到节点的监控数据,如节点 CPU、内存、使用率等,但是无法采集到运行在节点上的 Pod 监控数据。
定位问题原因,修复数据异常。
最开始不清楚 prometheus 的采集逻辑,怀疑是 prometheus 访问节点和 node-exporter 异常(pull方式下是由 prometheus 主动发起连接)。
远程登录进入 prometheus 检查网络连接正常,执行 ss -atupn 确认存在 9100 和 10250 的端口连接。
网络联通性行测试:在 prometheus 中使用 curl 访问 kubelet 和 node-exporter 正常。
环境中只有一个节点上的 Pod 有监控数据,其他节点都没有。
检查后台服务日志,确认情况如下:
节点 172.16.1.13 有Pod的监控统计数据,请求参数如下:
/mapis/cluster/cks-xgtjgdzespaz86wp/monitoring.cestc.cn/v1beta1/namespaces/eves/pods/signature-bbbbf9df-bcbbfbf8c-2vzcd?&end=1679040537&metrics_filter=pod_cpu_usage%7Cpod_memory_usage_wo_cache%7Cpod_net_bytes_transmitted%7Cpod_net_bytes_received&start=1679038737&step=36s×=50
节点 172.16.1.14 (运行着prometheus),没有Pod监控统计数据,请求参数如下:
/mapis/cluster/cks-xgtjgdzespaz86wp/monitoring.cestc.cn/v1beta1/namespaces/eves/pods/generate-1382f435-648f97b968-8vxnp?&end=1679040587&metrics_filter=pod_cpu_usage%7Cpod_memory_usage_wo_cache%7Cpod_net_bytes_transmitted%7Cpod_net_bytes_received&start=1679038787&step=36s×=50
到底是没有采集到,还是采集到了但查询 prometheus 失败?
- 确认 prometheus 的HTTP API文档:https://prometheus.io/docs/prometheus/latest/querying/api/
- 登录 prometheus 使用curl模拟查询
结果确认采集到的 metrics 中只有 172.16.1.13 来源的数据,其他节点都没有:
查看prometheus-operator的Pod存在错误日志:
通过代码定位到了出错的位置(prometheus-operator-v0.39.0):
- Pod 指标由 kubelet 暴露,实际上是从 cadvisor 采集
- prometheus-operator 启动参数指定了 kubelet-service,会创建和更新该 service 和 endpoint
- 配置 rule 后,prometheus 就会访问 service,采集到 Pod 指标
IPv6 或者双栈环境下,创建 service 后系统会自动补全 IPFamily 字段,而 v0.39.0 版本的 operator 在更新 service 和 endpoint 时没有先同步字段,产生了修改 immutable 字段的行为,导致更新 service 失败,函数直接返回:
参考社区的修复办法,在更新 service 前先拷贝 immutable 字段(最新版本的 service 对 IPFamily 做了调整来支持双栈):
基于 v0.39.0 版本的 prometheus-operator 修复问题,更新到下个版本,故障集群直接替换 prometheus-operator 容器镜像来修复问题。