Kubernetes集群常用监控指标

集群级别

kube-state-metrics和metric-server说明

kube-state-metrics关注于获取k8s各种资源的最新状态,如deployment或者daemonset,之所以没有把kube-state-metrics纳入到metric-server的能力中,是因为他们的关注点本质上是不一样的。

metric-server仅仅是获取、格式化现有数据,写入特定的存储,实质上是一个监控系统。

而kube-state-metrics是将k8s的运行状况在内存中做了个快照,并且获取新的指标,但他没有能力导出这些指标。

我们服务在运行过程中,我们想了解服务运行状态,Pod 有没有重启,伸缩有没有成功,pod的状态是怎么样的等,这时就需要kube-state-metrics,它主要关注deployment,、node 、 pod等内部对象的状态

而metrics-server 主要用于监测node,pod等的CPU,内存,网络等系统指标

1 Node节点数量监控

PromQL语句:

1
kube_node_info{instance="10.42.4.65:8080"}

说明:可以查询到K8S集群对应多少Node节点,可以和实际的节点数比较告警,也可以制作大屏

2 集群节点状态错误

PromQL语句:

1
kube_node_status_condition{condition="Ready",status!="true"}==1

说明:监控集群节点状态是否错误,如何值是1就是有错误可以告警

3 集群节状态是否准备好

PromQL语句:

1
kube_node_status_condition{condition="Ready",status="true"} == 0

说明:监控集群节点状态是否准备好,有点像kubectl get node获取的状态

4 集群节点内存或磁盘资源是否短缺

PromQL语句:

1
kube_node_status_condition{condition=~"OutOfDisk|MemoryPressure|DiskPressure",status!="false"}==1

5 集群中存在失败的PVC监控

PromQL语句:

1
kube_persistentvolumeclaim_status_phase{phase="Failed"}==1

6 集群中存在启动失败的Pod监控

PromQL语句:

1
kube_pod_status_phase{phase=~"Failed|Unknown"}==1

7 最近30分钟内有Pod容器重启监控

PromQL语句:

1
changes(kube_pod_container_status_restarts_total[30m])

8 节点CPU请求总核数(单位cores)

PromQL语句:

1
sum(kube_pod_container_resource_requests_cpu_cores{})

说明:监控容器请求的CPU内核数

9 节点CPU限制总核数

PromQL语句:

1
sum(kube_pod_container_resource_limits_cpu_cores{})

10 节点CPU总量

PromQL语句:

1
sum(kube_node_status_capacity_cpu_cores{}) 

11 节点内存请求值(bytes 1024/1024/1024后为GB)

PromQL语句:

1
sum(kube_pod_container_resource_requests_memory_bytes{})/1024/1024/1024

12 节点内存限制值

PromQL语句:

1
sum(kube_pod_container_resource_limits_memory_bytes{})

13 节点内存总量

PromQL语句:

1
sum(kube_node_status_capacity_memory_bytes{}/1024/1024/1024)

14 节点不可用监控

PromQL语句:

1
sum(kube_node_spec_unschedulable{node=~"$node"})

15 Pod 的生命周期监控

PromQL语句:

1
kube_pod_status_phase{phase=~"Pending|Running"} == 1

说明:kube_pod_status_phase可以统计Pod的数量,phase的值:Running(运行中)Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。官网对Pod 的生命周期说明:
https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-lifecycle/
PromQL语句:

1
sum(kube_pod_status_phase{namespace=~".*", phase="Pending"}==1)

说明:监控悬决的Pods数量;Pod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间
PromQL语句:

1
sum(kube_pod_status_phase{namespace=~".*", phase="Failed"}==1)

说明:监控成功终止的Pods数量;Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非 0 状态退出或者被系统终止
PromQL语句:

1
sum(kube_pod_status_phase{namespace=~".*", phase="Succeeded"}==1)

说明:监控成功终止的Pods数量;Pod 中的所有容器都已成功终止,并且不会再重启
PromQL语句:

1
sum(kube_pod_status_phase{namespace=~".*", phase="Unknown"}==1)

说明:监控未知的Pods数量;因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败

16 监控K8S已运行的容器

PromQL语句:

1
kube_pod_container_status_running{namespace=~".*"}==1

说明:监控正在运行容器数量;可以绘制K8S集群的容器数量

17 监控K8S等待创建的容器

PromQL语句:

1
kube_pod_container_status_waiting{namespace=~".*"}==1

说明:监控K8S等待创建的容器;可以监控容器

18 监控K8S停止的容器

PromQL语句:

1
kube_pod_container_status_terminated{namespace=~".*"}==1

说明:监控K8S停止的容器;可以监控容器

19 监控作业中心成功数

PromQL语句:

1
sum(kube_job_status_succeeded{namespace=~".*"})

说明:监控作业中心成功数;可以监控作业执行的成功数

20 监控每个部署的副本数

PromQL语句:

1
sum(kube_deployment_status_replicas{namespace=~".*"})

说明:kube_deployment_status_replicas 表示每个部署的副本数,这值是Status.Replicas;
kube_deployment_spec_replicas表示部署所需的吊舱数。这值是Spec.Replicas资源定义副本数
kube_deployment_status_replicas_available 正在运行副本数
kube_deployment_status_replicas_updated 更新的副本数
kube_deployment_status_replicas_unavailable 不可用的副本数

21 集群磁盘使用率

PromQL语句:

1
(sum (node_filesystem_size_bytes{nodename=~".*"}) - sum (node_filesystem_free_bytes{nodename=~".*"})) / sum (node_filesystem_size_bytes{nodename=~".*"})

说明:监控K8S集群磁盘使用率

22 集群监控磁盘卷可用空间的

PromQL语句:

1
kubelet_volume_stats_available_bytes / kubelet_volume_stats_capacity_bytes * 100 < 10

说明:监控K8S监控磁盘卷可用空间的,小于10就告警

23 集群监控预测磁盘卷7天是否满

PromQL语句:

1
predict_linear(kubelet_volume_stats_available_bytes[1h], 7 * 24 * 3600) < 0

说明:监控K8S集群监控预测磁盘卷7天是否满,小于0就告警

24 集群监控PV使用状态监控

PromQL语句:

1
kube_persistentvolume_status_phase{phase=~"Failed|Pending"} > 0

kube_persistentvolume_status_phase:PV使用状态

说明:监控K8S集群监控PV使用状态,大于0就告警

25 集群监控StatefulSet是否down

PromQL语句:

1
(kube_statefulset_status_replicas_ready / kube_statefulset_status_replicas_current) != 1

说明:监控K8S集群StatefulSet是否down,不于1就告警

26 集群监控HPA动态伸缩异常PromQL语句

1
(sum(kube_hpa_status_condition{condition="ScalingLimited",status="true"}) by (hpa,namespace)) == 1

说明:监控K8S集群HPA动态伸缩异常,等于1就告警

27 集群监控当前5分钟POD重启的次数

PromQL语句:

1
rate(kube_pod_container_status_restarts_total[5m]) * 60 * 5 >2

说明:监控K8S集群监控当前5分钟POD重启的次数,大于2就告警

28 集群监控replicaset副本数状态

PromQL语句:

1
kube_replicaset_spec_replicas != kube_replicaset_status_ready_replicas

说明:监控K8S集群集群监控replicaset副本数状态,不等异常
同理:

1
kube_deployment_spec_replicas != kube_deployment_status_replicas_available
1
kube_statefulset_status_replicas_ready != kube_statefulset_status_replicas
1
kube_deployment_status_observed_generation != kube_deployment_metadata_generation
1
kube_statefulset_status_observed_generation != kube_statefulset_metadata_generation

容器级别

CPU

利用率

  • container_cpu_user_seconds_total —“用户”时间的总数(即不在内核中花费的时间)
  • container_cpu_system_seconds_total —“系统”时间的总数(即在内核中花费的时间)
  • container_cpu_usage_seconds_total—以上总和

所有这些指标都是couter类型,需要对其rate算出使用率

查询展示每个容器正在使用的CPU

1
sum(rate(container_cpu_usage_seconds_total{namespace!~"kube-system"}[5m])) by (pod)

饱和度

如果您定义了CPU的limit 值,计算饱和度将变得容易得多。

当容器超出其CPU限制时,Linux运行时将“限制”该容器并在container_cpu_cfs_throttled_seconds_total指标中记录其被限制的时间

1
sum(rate(container_cpu_cfs_throttled_seconds_total[5m])) by (pod)

内存

cAdvisor中提供的内存指标是从node_exporter公开的43个内存指标的子集。以下是容器内存指标:

指标 含义
container_memory_cache 页面缓存的字节数
container_memory_rss RSS的大小(以字节为单位)
container_memory_swap 容器交换使用量(以字节为单位)
container_memory_usage_bytes 当前内存使用情况(以字节为单位,包括所有内存,无论何时访问)
container_memory_max_usage_bytes 以字节为单位记录的最大内存使用量
container_memory_working_set_bytes 当前工作集(以字节为单位)
container_memory_failcnt 内存使用次数达到限制
container_memory_failures_total 内存分配失败的累积计数

利用率

使用container_memory_usage_bytes来计算内存使用率,但是这个指标还包括了文件系统缓存,是不准确的。更准确的是container_memory_working_set_bytes,是 OOM 所关心的指标

1
sum(container_memory_working_set_bytes{container!~"POD"}) by (pod) / (1024*1024)

在上面的查询中,我们需要排除名称包含“ POD”的容器。这是此容器的父级cgroup,将跟踪pod中所有容器的统计信息。

饱和度

和 CPU 的饱和度计算相似,但是和 CPU 不同,无法直接使用指标,因为 OOM 后 container 会被杀掉,可以使用如下查询

1
sum(container_memory_working_set_bytes) by (pod) / sum(label_join(kube_pod_container_resource_limits_memory_bytes,"container_name", "", "container")) by (pod)

磁盘

利用率

在处理磁盘I / O时,我们首先通过查找和读写来跟踪所有磁盘利用率。

cAdvisor有以下指标:

  • container_fs_io_time_seconds_total
  • container_fs_io_time_weighted_seconds_total

最基本的磁盘I / O利用率是读/写的字节数:

1
sum(rate(container_fs_writes_bytes_total[5m])) by (pod,device) > 0

1
sum(rate(container_fs_reads_bytes_total[5m])) by (pod,device) > 0

![image-20210603200527062](/Users/mervinwang/Library/Application Support/typora-user-images/image-20210603200527062.png)

网络

利用率

容器的网络利用率,可以选择以字节为单位还是以数据包为单位。网络的指标有些不同,因为所有网络请求都在Pod级别上进行,而不是在容器上进行

下面查询将按pod名称显示每个pod的网络利用率:

1
sum(rate(container_network_receive_bytes_total[5m])) by (pod)

1
sum(rate(container_network_transmit_bytes_total[5m])) by (pod)

节点级别

node-exporter可以检查节点的核心指标,从利用率,饱和度和错误的角度来看CPU,内存,磁盘和网络的监控指标

四个黄金信号

  • Latency — 延迟
  • Traffic — 流量
  • Errors — 错误数
  • Saturation — 饱和度

要定义应用程序的饱和度,我们经常需要考虑应用程序使用的基础资源的饱和度。这些资源我们可以使用USE方法对其进行监控

USE 方法

Brendan Gregg在解释系统资源时如何考虑利用率、饱和度、错误方面做得非常出色。

他给出以下定义:

  • Resource:所有服务器功能组件(CPU,磁盘,总线等)
  • Utilization:资源忙于服务工作的平均时间
  • Saturation:需要排队无法提供服务的时间
  • Errors:错误事件的计数

他建议(但没有规定)确切地表示在Unix系统的上下文中哪些度量表示利用率,饱和度和错误。本文的其余部分,我将USE方法应用于Kubernetes节点中的资源。

尽管USE方法针对的是资源,具有严格限制的实际物理资源,但是对于在这些资源上运行的软件而言,这是不完整的描述。这就是RED方法的用武之地。

RED 方法

Tom Wilkie解释RED方法为:

  • Rate:每秒的请求数。
  • Errors:失败的那些请求的数量。
  • Duration:这些请求所花费的时间。

从表面上看,RED方法似乎与USE方法和四个黄金信号非常相似。什么时候使用USE vs RED?

USE 方法用于资源,RED 方法用于服务

CPU

利用率

现在,我们有两种方法可以帮助您选择要注意的指标。这东西是资源还是应用程序?
集群中的节点具有资源。您的节点在Kubernetes群集中提供的最重要资源是CPU,内存,网络和磁盘。
让我们将USE方法应用于所有这些方法。

node_exporter指标node_cpu_seconds_total会跟踪所有CPU mode 在每个内核上花费的所有CPU时间。这些mode是:user, system, nice, idle, iowait, guest, guest_nice, steal, soft_irq and irq

要计算Kubernetes集群中主机的cpu利用率,我们希望对所有mode进行累加, idle, iowait, guest, and guest_nice除外。PromQL看起来像这样:

1
sum(rate(node_cpu_seconds_total{mode!="idle",mode!="iowait",mode!~"^(?:guest.*)$"}[5m])) by (instance)

关于此查询的一些注意事项:

  • 在PromQL中,当同一标签上有多个修饰符时,它们将被AND在一起。
  • 所有的node_cpu系列均表示为CPU秒,并且是counter,因此我们需要使用rate()来计算每秒的时间。最终结果显示了每个节点使用的CPU数。
  • 最终结果显示了每个节点使用的CPU数。

关于此查询的一些注意事项:

  • 在PromQL中,当同一标签上有多个修饰符时,它们将被AND在一起。
  • 所有的node_cpu_seconds_total系列均表示为CPU秒,并且是counter,因此我们需要使用rate来计算每秒的时间。最终结果显示了每个节点使用的CPU数。
  • 最终结果显示了每个节点使用的CPU数。

饱和度

CPU 提供的饱和度,是Unix的平均负载。平均负载是正在运行的进程数加上正在等待运行的进程数

node_load1,node_load5和node_load15分别代表1、5和15分钟的平均负载。该指标是一个gauge,已经为您进行了平均。

node_exporter 不会直接公开节点CPU的数量,但是可以通过以下promql获取

1
count(node_cpu_seconds_total{mode="system"}) by (instance)

现在可以通过以百分比表示的节点上的CPU数量来规范化node_load1指标

1
sum(node_load1) by (instance) / count(node_cpu_seconds_total{mode="system"}) by (instance) * 100

内存

使用率

可用内存除以节点上可用的总内存,即可得到可用内存的百分比,然后从1中减去以得出节点内存利用率的度量

1
1 - sum(node_memory_MemAvailable_bytes) by (instance) / sum(node_memory_MemTotal_bytes) by (instance)