尽管有 6Gi 限制,但 Prometheus 仍出现 OOMkilled 问题

尽管有 6Gi 限制,但 Prometheus 仍出现 OOMkilled 问题

我对利用 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 占用内存的最可能原因:

  1. 时间序列数量过多。考虑到背景,这是最合理的。在 prometheus 中,与唯一时间序列相比,数据点占用的内存并不多。我现在找不到链接,但据我所知,一个数据点大约占用 4 个字节,而没有任何数据点的时间序列大约占用 1Kb。因此,即使没有任何数据点的时间序列也会占用空间并且可能占用内存。您可以通过比较 prod 和 stage 中的时间序列数量来排除这个原因:count({__name__=~".+"})。如果 prod 中的时间序列明显更多,您必须找出原因,并可能进一步减少数量。
  2. PromQL 查询将太多数据加载到内存中。如果您的查询请求长时间或大量时间序列,也可能是原因,因为 prometheus 会尝试将请求的数据加载到内存中。由于 OOM 不断重现,您可以通过阻止对 prometheus 的所有查询来测试此假设,看看它是否仍然会达到 OOM。可能值得一看 查询日志也。
  3. 节点内存不足。可能只是其他容器消耗了节点上的内存,而 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]

我的实例再次变得稳定。

相关内容