Prometheus是一个神奇的、开源的监控和警报工具。除了从整个系统(如kubernetes集群,或只是一个单一的实例)收集指标外,还可以使用alertmanager来触发警报。
然而,在设置警报时,我很难找到具体的警报例子,如high cpu usage ,或者kubernetes特有的东西,如pod被重新启动,所以这里是我们想出的一些警报,尽管数值不同,有时方式不同,但可以在生产环境中使用。
一些警报依赖于在目标实例上运行的node-exporter,而其他警报则使用kube-state-metrics和kubernetes。还有一些警报使用http响应状态和http响应时间的自定义指标。
最后,无论具体的数据源是什么,警报的总体概念应该是有效的。
让我们看看一些警报的例子,这些警报在分布式系统(特别是使用kubernetes)中可能是有用的。
基础设施警报
首先,我们来看看一些基本的基础设施警报,关于CPU/内存/磁盘。我们将逐一介绍这些警报,并对每个警报进行简短的解释。
为了表明一个目标(如实例)已经停机,我们只需检查up 。
expr: up == 0
要发出信号,根据过去X小时的趋势,一个磁盘将很快被填满,我们使用predict_linear 函数。如果根据过去24小时的数据,可用的磁盘空间将在未来7天内低于零,则触发该警报。
expr: predict_linear(node_filesystem_avail[24h], 7*24*3600) <= 0
为了发出信号,根据过去x小时的趋势,内存将在某一时间框架内被填满,我们也使用predict_linear 。如果基于过去两小时的内存增加将导致内存在未来一小时内耗尽,该警报将触发。
expr: predict_linear(node_memory_MemAvailable[2h], 1*3600) <= 0
为了发出高内存压力的信号,我们首先计算可用内存的百分比,如果这个百分比低至5%,并且在最后一分钟内的页面故障率很高(>100),我们就会触发警报。
expr: (node_memory_MemAvailable / node_memory_MemTotal * 100) < 5 and rate(node_vmstat_pgmajfault[1m]) > 100
要发出CPU使用率高的信号,我们只需将过去5分钟的平均负载除以该实例上的cpu数量,如果它在一段时间内超过95%,我们就会发出警报。
expr: node_load5/count(node_cpu{mode="idle"}) without (cpu,mode) >= 0.95
针对Kubernetes的警报
下面的警报只针对kubernetes,是基于kube-state-metrics报告的指标。由于这个工具的状态性和kubernetes部分的基于事件的性质,这些警报有时有点难写,有点古怪,但它们仍然可以提供有用的见解。
为了表明一个pod是down (从客户的角度来看),我们首先检查一个pod是否仍在运行,因为我们不希望在部署过程中对pod被轮换掉的情况发出警报。然后,我们使用and 在pod 标签上与目标的up 度量相结合,这些目标确实有一个kubernetes_container_name ,因此是pod。
为了能够在pod 指标上结合起来,我们需要将kubernetes_pod_name 标签替换为pod 。这是一个很好的方法,可以在一个共同的属性上结合不同来源的两个指标。
如果pod是running ,但不是up (即可达),那么我们就会触发一个警报。
expr: kube_pod_container_status_running == 1
and on(pod) label_replace(
up{kubernetes_container_name=~".+"}, "pod", "$1", "kubernetes_pod_name", "(.*)"
) == 0
为了表明一种或多种类型的pod无法到达,我们测试kubernetesdeployment 的现有副本是否小于预期副本的数量。
expr: kube_deployment_status_replicas > kube_deployment_status_replicas_available
为了表明所有类型的pod都无法到达,我们基本上做的和上面一样,但我们测试,实际上没有复制是可用的,这意味着服务无法被到达。
expr: kube_deployment_status_replicas > 0
and kube_deployment_status_replicas_available == 0
为了表明一个pod被重启,我们只检查已经被终止的pod,并计算过去5分钟内的重启率,以便注意到,即使pod是在Prometheus轮询之间重启的,它也发生了。
expr: kube_pod_container_status_last_terminated_reason == 1
and on(container) rate(kube_pod_container_status_restarts_total[5m]) * 300 > 1
为了表明一个pod在启动时可能有问题,我们检查一个pod是否处于waiting 状态,但不是以ContainerCreating ,这只是意味着它正在启动。
expr: kube_pod_container_status_waiting_reason{reason!="ContainerCreating"} == 1
错误率/响应时间警报
下面两个警报是基于一个自定义的计数器,计算http响应状态代码(gateway_status_codes)和http响应时间的摘要(gateway_response_time)。这些值来自哪里并不重要(例如,来自查询ELK堆栈日志),但如果它们以这种方式结构化,就可以用于警报。
为了发出5xx错误增加的信号,我们只需在计数器上使用increase 函数,并在给定的时间内(本例中为1m)将其与一个阈值进行比较。这也可以用4xx 错误来做。在我们的案例中,所有5xx错误都被归类为type 500。
expr: increase(gateway_status_code{type="500"}[1m]) > 50
为了提示响应时间的峰值,我们可以在创建的Prometheus摘要内使用quantile 标签,并与固定值进行定量比较。警报的实际值和限制将在很大程度上取决于系统的实际健康响应时间。
expr: gateway_response_time{quantile="0.5"} > 0.1
or gateway_response_time{quantile="0.9"} > 0.5
or gateway_response_time{quantile="0.99"} > 1.0
可达性警报
为了完成这个列表,这里有一个测试某个网址是否可以到达的方法。
这个警报依赖于Blackbox-Exporter来工作。我不会详细介绍Blackbox-Exporter,但我只想说,你基本上把要检查的URL列表传给它,这些URL被测试,然后你可以查询这些探测是否成功。
因此,为了检查,如果一个URL无法到达,你可以使用下面的方法。
expr: probe_success == 0
结论
我希望这个小型的Prometheus警报例子集对你有用,或者至少能帮助你编写或改进你自己的警报。)