Atlantis
GitHub Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

7. Prometheus无法采集容器metrics

1. 前言

一个普通问题的排查流程,排查过程中摸索了一遍 prometheus-operator 如何处理业务逻辑,这里做下记录。

2. STAR

2.1 Situation

K8s 集群的监控组件采用 prometheus-operator 管理,operator 和相关 CRD 通过 helm 安装,operator 孵化出 alertmanager、prometheus、node-exporter 等组件。

问题出现在一个启用 IPv6 的客户集群,现象是可以查看到节点的监控数据,如节点 CPU、内存、使用率等,但是无法采集到运行在节点上的 Pod 监控数据。

alt text

2.2 Task

定位问题原因,修复数据异常。

2.3 Action

2.3.1 远程排查

最开始不清楚 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&times=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&times=50

2.3.2 确认问题

到底是没有采集到,还是采集到了但查询 prometheus 失败?

  1. 确认 prometheus 的HTTP API文档:https://prometheus.io/docs/prometheus/latest/querying/api/
  2. 登录 prometheus 使用curl模拟查询

结果确认采集到的 metrics 中只有 172.16.1.13 来源的数据,其他节点都没有:

alt text

查看prometheus-operator的Pod存在错误日志:

alt text

通过代码定位到了出错的位置(prometheus-operator-v0.39.0):

alt text

alt text

2.3.3 确认prometheus如何采集容器metrics

  1. Pod 指标由 kubelet 暴露,实际上是从 cadvisor 采集
  2. prometheus-operator 启动参数指定了 kubelet-service,会创建和更新该 service 和 endpoint
  3. 配置 rule 后,prometheus 就会访问 service,采集到 Pod 指标

alt text

2.3.4 异常原因

IPv6 或者双栈环境下,创建 service 后系统会自动补全 IPFamily 字段,而 v0.39.0 版本的 operator 在更新 service 和 endpoint 时没有先同步字段,产生了修改 immutable 字段的行为,导致更新 service 失败,函数直接返回:

alt text

参考社区的修复办法,在更新 service 前先拷贝 immutable 字段(最新版本的 service 对 IPFamily 做了调整来支持双栈):

alt text

2.4 Result

基于 v0.39.0 版本的 prometheus-operator 修复问题,更新到下个版本,故障集群直接替换 prometheus-operator 容器镜像来修复问题。