我对利用 prometheus 设置的耐心已经到了极限kube-prometheus 堆栈44.3.0(最新为 45)。
我有两个环境,staging 和 prod。在 staging 中,我的 prometheus 运行顺利。在 prod 中,它大约每 4 分钟就会崩溃一次,并出现 OOMKilled 错误。
我已经尝试过的事情:
- 将抓取间隔从 30 秒增加至 300 秒
- 确定重要的指标,并在提取之前将其删除 [稍后详细介绍]
- 启用 web.enable-admin-api,以查询 tsdb 并清理墓碑
- 删除了 prometheusrules,因为我注意到它们往往会缩短 pod 的使用寿命,直到下一次崩溃
- 考虑到我正在使用的节点,将资源(限制和请求)提升到最大可用范围(当前内存限制为 6Gi;暂存工作在 1Gi 内存以下)
- 减少了要抓取的目标数量(例如,记录 etcd 指标)
比较 TSDB 在暂存区和生产区的状态 当产品启动时,它不会显示更高的数字 - 直到它崩溃:
通过查看 TSDB 统计数据,我注意到我曾经有 kube_replicasets 指标蜂拥而至 prometheus。集群中的另一个组件由于错误而创建了大量副本集,从而增加了指标。我从摄取中完全停用了这些指标:
...
metricRelabelings:
- regex: '(kube_replicaset_status_observed_generation|kube_replicaset_status_replicas|kube_replicaset_labels|kube_replicaset_created|kube_replicaset_annotations|kube_replicaset_status_ready_replicas|kube_replicaset_spec_replicas|kube_replicaset_owner|kube_replicaset_status_fully_labeled_replicas|kube_replicaset_metadata_generation)'
action: drop
sourceLabels: [__name__]
我已验证这些副本集指标不再存在于 prod prometheus 中。
总结:
我的 K8S 环境中的 Prometheus 不断出现 OOMkilled 现象,导致该工具几乎无法使用。我需要了解如何查找和隔离问题的原因。目前唯一合理的罪魁祸首似乎仍然是 kube-state-metrics(待办事项 - 我需要禁用它以验证这个想法)。
我已经查看过的相关问题:
答案1
以下是 Prometheus 占用内存的最可能原因:
- 时间序列数量过多。考虑到背景,这是最合理的。在 prometheus 中,与唯一时间序列相比,数据点占用的内存并不多。我现在找不到链接,但据我所知,一个数据点大约占用 4 个字节,而没有任何数据点的时间序列大约占用 1Kb。因此,即使没有任何数据点的时间序列也会占用空间并且可能占用内存。您可以通过比较 prod 和 stage 中的时间序列数量来排除这个原因:
count({__name__=~".+"})
。如果 prod 中的时间序列明显更多,您必须找出原因,并可能进一步减少数量。 - PromQL 查询将太多数据加载到内存中。如果您的查询请求长时间或大量时间序列,也可能是原因,因为 prometheus 会尝试将请求的数据加载到内存中。由于 OOM 不断重现,您可以通过阻止对 prometheus 的所有查询来测试此假设,看看它是否仍然会达到 OOM。可能值得一看 查询日志也。
- 节点内存不足。可能只是其他容器消耗了节点上的内存,而 prometheus 被杀死,因为它的内存较低服务质量。只需确保 prometheus 符合保证的 QoS 即可。
答案2
导致我出现问题的原因是 keycloak 命名空间中的 keycloak 部署出现故障。旧的 keycloak 设置创建了大量副本集(约 36000 个),这导致 Prom 中与副本集相关的查询基数很高。
问题不在于暂存,因为暂存没有完全反映该配置。
我已经尝试对 kube-state-metrics 进行以下重新标记,在提取之前删除查询:
- regex: '(kube_replicaset_status_observed_generation|kube_replicaset_status_replicas|kube_replicaset_labels|kube_replicaset_created|kube_replicaset_annotations|kube_replicaset_status_ready_replicas|kube_replicaset_spec_replicas|kube_replicaset_owner|kube_replicaset_status_fully_labeled_replicas|kube_replicaset_metadata_generation)'
action: drop
sourceLabels: [__name__]
但事实证明它过于保守。添加后:
- regex: 'keycloak'
action: drop
sourceLabels: [namespace]
我的实例再次变得稳定。