目录
cpu 利用率高告警指标
我们先从告警指标说起,关于 Kubernetes 集群中的告警指标,开源项目 awesome-prometheus-alerts 提供了一些方案,真的是非常的 awesome。
对于 cpu 资源利用率高,该项目给出的告警规则为 docker-containers:
- alert: ContainerHighCpuUtilization
expr: (sum(rate(container_cpu_usage_seconds_total{container!=""}[5m])) by (pod, container) /
sum(container_spec_cpu_quota{container!=""}/container_spec_cpu_period{container!=""}) by (pod, container) * 100) > 80
for: 2m
labels:
severity: warning
annotations:
summary: Container High CPU utilization (instance )
description: "Container CPU utilization is above 80%\n VALUE = \n LABELS = "
那上面的表达式具体是怎么计算的呢?本文章一步一步分析一下。
1.计算容器使用核数
容器的 cpu 利用率计算表达式为 使用量/限制量*100
,我们首先需要计算出容器实际使用了多少核数。从上面表达式中,可以看出使用了 container_cpu_usage_seconds_total
这个监控指标,这个监控指标说的是容器自启动以来使用的 cpu 秒数
,来源是容器的 cgroup 统计。如果容器使用了多个 cpu,则累加起来。因为是 counter 类型,所以这个指标是一直增加的,不会下降,大概是下面这个样子。
然后是计算容器使用核数,这个是通过 rate 函数进行的,这里需要理解一下,是如何从 cpu 使用时间转换成使用核数的,也就是 rate 函数的工作过程。rate 求的是一个斜率,结果是 每秒 的使用量。具体计算过程是 container_cpu_usage_seconds_total
这个指标:(当前值 - 5分钟之前的值)/ (5 * 60)
,所以下面表达式的含义:在过去的 5 分钟内,容器每秒使用的 cpu 秒数。首先一个事实是,对于一个 cpu,每一秒我们最多能使用一秒。因此,如果容器每秒使用的 cpu 秒数大于 1,比如说是 2.5s
,则表示容器在这一秒使用了 2.5 个 cpu 核。
rate(container_cpu_usage_seconds_total{container!=""}[5m])
因此上面指标就是容器使用的核数。理解之后,外面这一层 sum 就是按照 pod、container 分组求和。
sum(rate(container_cpu_usage_seconds_total{container!=""}[5m])) by (pod, container)
2.计算容器的 cpu limit
计算容器使用的 cpu limit,涉及到两个指标:container_spec_cpu_quota
以及 container_spec_cpu_period
其实就是 cgroup 中的 quota 以及 period。直接相除就能得到容器的 limit。注意表达式 container_spec_cpu_quota{container!=""}/container_spec_cpu_period{container!=""}
在进行除法计算时,会自动进行 label join,只有标签相同的才会相除。然后再根据 pod、container 分组求和。
sum(container_spec_cpu_quota{container!=""}/container_spec_cpu_period{container!=""}) by (pod, container)
关于容器使用的 cpu limit,其实还有一个指标 kube_pod_container_resource_limits
,这个是来自资源的 yaml 配置,并且包含了 cpu 以及 memory,需要通过 resource="cpu"
来查看 cpu 的限制,相对来说使用 quota 更精确一点。
3.计算使用率
最后就是计算使用量的表达式了,同样只有 pod、container 相同的才会进行计算。
sum(rate(container_cpu_usage_seconds_total{container!=""}[5m])) by (pod, container) /
sum(container_spec_cpu_quota{container!=""}/container_spec_cpu_period{container!=""}) by (pod, container)