PromQL 查询以查找上周使用的 CPU 和内存

Ste*_*eve 1 kubernetes prometheus promql

我正在尝试编写一个 Prometheus 查询,它可以告诉我每个命名空间在一个时间范围内(例如一周)使用了多少 CPU(以及另一个用于内存和网络的百分比)。

我尝试使用的指标是container_spec_cpu_sharescontainer_memory_working_set_bytes但我无法弄清楚随着时间的推移如何对它们求和。无论我尝试返回 0 还是错误。

任何有关如何为此编写查询的帮助将不胜感激。

Daw*_*ruk 7

要检查每个命名空间使用的内存百分比,您需要一个类似于以下的查询:

sum( container_memory_working_set_bytes{container="", namespace=~".+"} )|
by (namespace) / ignoring (namespace) group_left 
sum( machine_memory_bytes{}) * 100 
Run Code Online (Sandbox Code Playgroud)

上面的查询应该产生一个类似于这个的图:

格拉法纳图像

免责声明!:

  • 上面的屏幕截图来自 Grafana,以获得更好的可见性。
  • 此查询不确认可用 RAM 的更改(节点更改、节点自动缩放等)。

要在 PromQL 中获取一段时间内的指标,您需要使用其他功能,例如:

  • avg_over_time(EXP[time]).

要回到过去并从特定时间点计算资源,您需要使用:

  • offset TIME

使用上面的指针查询应该结合到:

avg_over_time( sum(container_memory_working_set_bytes{container="", namespace=~".+"} offset 45m) by (namespace)[120m:])  / ignoring (namespace) group_left 
sum( machine_memory_bytes{}) 
Run Code Online (Sandbox Code Playgroud)

以上查询将计算每个命名空间使用的平均内存百分比,并将其除以集群中从 120 分钟到当前时间的所有内存。它也将从当前时间提前 45 分钟开始。

例子:

  • 运行查询时间:20:00
  • avg_over_time(EXPR[2h:])
  • offset 45 min

上面的示例将从 17:15 开始,并将查询运行到 19:15。您可以修改它以包括整周:)。

如果要按命名空间计算 CPU 使用率,可以将此指标替换为以下指标:

  • container_cpu_usage_seconds_total{}-rate()使用此指标时请检查功能(计数器)
  • machine_cpu_cores{}

您还可以查看此网络指标:

  • container_network_receive_bytes_total-rate()使用此指标时请检查功能(计数器)
  • container_network_transmit_bytes_total-rate()使用此指标时请检查功能(计数器)

我在下面包含了更多解释,包括示例(内存)、测试方法和使用查询的剖析。


让我们假设:

  • Kubernetes 集群1.18.6(Kubespray) 总共有 12GB 内存:
    • 具有2GB内存的主节点
    • 具有8GB内存的worker-one 节点
    • 具有2GB内存的worker-2 节点
  • Prometheus 和 Grafana 安装:Github.com:Coreos:Kube-prometheus
  • kruk带有单个ubuntupod 的命名空间设置为使用以下命令生成人工负载:
    • $ stress-ng --vm 1 --vm-bytes <AMOUNT_OF_RAM_USED> --vm-method all -t 60m -v

人工负载产生stress-ng两次:

  • 60 分钟 - 使用了1GB内存
  • 60 分钟 - 使用了2GB内存

命名空间kruk在此时间跨度内使用的内存百分比:

  • 1GB,约占集群所有内存的 8.5% (12GB)
  • 2GB,约占集群所有内存的 17.5% (12GB)

从 Prometheus 查询kruk命名空间的负载看起来像这样:

kruk 命名空间内存使用

查询人工负载产生的时间时,计算 usingavg_over_time(EXPR[time:]) / memory in the cluster显示使用率在 13% ( (17.5+8.5)/2)左右。这应该表明查询是正确的:

平均使用量


至于使用的查询:

avg_over_time( sum( container_memory_working_set_bytes{container="", namespace="kruk"} offset 1380m )
by (namespace)[120m:]) / ignoring (namespace) group_left 
sum( machine_memory_bytes{}) * 100 
Run Code Online (Sandbox Code Playgroud)

上面的查询与开头的查询非常相似,但我做了一些更改以仅显示kruk名称空间。

我将查询解释分为两部分(股息/除数)。

股利

container_memory_working_set_bytes{container="", namespace="kruk"}
Run Code Online (Sandbox Code Playgroud)

该指标将输出 namespace 中的内存使用记录kruk。如果您要查询所有名称空间,请查看附加说明:

  • namespace=~".+"<- 仅当命名空间键内的值包含 1 个或多个字符时,此正则表达式才会匹配。这是为了避免带有聚合指标的空命名空间结果。
  • container=""<- 部分用于过滤指标。如果您在没有它的情况下进行查询,您将获得每个容器/pod 的多个内存使用指标,如下所示。container=""仅当容器值为空时才匹配(下面引文中的最后一行)。
sum( container_memory_working_set_bytes{container="", namespace=~".+"} )|
by (namespace) / ignoring (namespace) group_left 
sum( machine_memory_bytes{}) * 100 
Run Code Online (Sandbox Code Playgroud)

您可以在此处阅读有关暂停容器的更多信息:

sum( container_memory_working_set_bytes{container="", namespace="kruk"} offset 1380m )
by (namespace)
Run Code Online (Sandbox Code Playgroud)

此查询将按各自的命名空间对结果求和。offset 1380m用于在过去进行测试时回到过去。

avg_over_time( sum( container_memory_working_set_bytes{container="", namespace="kruk"} offset 1380m )
by (namespace)[120m:])
Run Code Online (Sandbox Code Playgroud)

此查询将从比当前时间早 1380m 开始的指定时间(120m 到现在)跨命名空间的内存度量计算平均值。

您可以avg_over_time()在此处阅读更多信息:

除数

sum( machine_memory_bytes{})
Run Code Online (Sandbox Code Playgroud)

该指标将对集群中每个节点的可用内存求和。

EXPR / ignoring (namespace) group_left 
sum( machine_memory_bytes{}) * 100 
Run Code Online (Sandbox Code Playgroud)

专注于:

  • / ignoring (namespace) group_left<- 此表达式将允许您将除数(集群中的所有内存)中的每个“记录”(每个命名空间及其跨时间的平均内存)除以除数。您可以在此处阅读更多相关信息:Prometheus.io:矢量匹配
  • * 100 是不言自明的,并将结果乘以 100 以看起来更像百分比。

其他资源: