node_exporter 主要用于 LINUX 系统监控, 用 Golang 编写,是我们最常用于监控服务器资源的探针。

安装

1、二进制

https://github.com/prometheus/node_exporter/releases/download/v0.14.0/node_exporter-0.14.0.linux-amd64.tar.gz

我们可以直接使用 ./node_exporter -h 查看运行选项,./node_exporter 运行 Node Exporter

2、docker

docker run -d -p 9100:9100 \
  -v "/proc:/host/proc:ro" \
  -v "/sys:/host/sys:ro" \
  -v "/:/rootfs:ro" \
  --net="host" \
  quay.io/prometheus/node-exporter \
    -collector.procfs /host/proc \
    -collector.sysfs /host/sys \
    -collector.filesystem.ignored-mount-points "^/(sys|proc|dev|host|etc)($|/)"

源码原理解析

node探针进程启动的时候,会调用collector的package,就会初始化所有的collect注册到

factories      = make(map[string]func() (Collector, error))
collectorState = make(map[string]*bool)

这个中,根据初始化中传递的参数,确定采集是否开启,处理函数是什么

然后会创建一个结构体

type nodeCollector struct {
    Collectors map[string]Collector
}

将开启采集的数据,创建对应的结构体,其实也是一个实现interface的结构,最后存储在这个结构中

然后将这些collector进行注册,启动监听端口和一些其他设置

然后就是调用client_golang中的describe和collect的重写函数

在collect中启动多协程进行每个类型的处理

调用update函数实现数据赋值与采集

开启默认关闭的采集

我们可以使用 –collectors.enabled 运行参数指定 node_exporter 收集的功能模块, 如果不指定,将使用默认模块。

比如开启ntp采集

./node_exporter --collector.ntp

输出相关指标:

# HELP node_ntp_leap NTPD leap second indicator, 2 bits.
# TYPE node_ntp_leap gauge
node_ntp_leap 3
# HELP node_ntp_offset_seconds ClockOffset between NTP and local clock.
# TYPE node_ntp_offset_seconds gauge
node_ntp_offset_seconds -1.6239e-05
# HELP node_ntp_reference_timestamp_seconds NTPD ReferenceTime, UNIX timestamp.
# TYPE node_ntp_reference_timestamp_seconds gauge
node_ntp_reference_timestamp_seconds 0
# HELP node_ntp_root_delay_seconds NTPD RootDelay.
# TYPE node_ntp_root_delay_seconds gauge
node_ntp_root_delay_seconds 0
# HELP node_ntp_root_dispersion_seconds NTPD RootDispersion.
# TYPE node_ntp_root_dispersion_seconds gauge
node_ntp_root_dispersion_seconds 0.060363769
# HELP node_ntp_rtt_seconds RTT to NTPD.
# TYPE node_ntp_rtt_seconds gauge
node_ntp_rtt_seconds 8.6646e-05
# HELP node_ntp_sanity NTPD sanity according to RFC5905 heuristics and configured limits.
# TYPE node_ntp_sanity gauge
node_ntp_sanity 0
# HELP node_ntp_stratum NTPD stratum.
# TYPE node_ntp_stratum gauge
node_ntp_stratum 0

计算表达式

收集到 node_exporter 的数据后,我们可以使用 PromQL 进行一些业务查询和监控,下面是一些比较常见的查询

CPU 各 mode 占比率

avg by (instance, mode) (irate(node_cpu_seconds_total{instance="xxx"}[5m])) * 100

cpu的使用率

avg(irate(node_cpu_seconds_total{ip="$host"}[1m]))by (mode)

node_cpu_seconds_total采集出来的是cpu使用时间的累加,在linux机器上cpu的使用就是这样记录的,所以可以使用速率的方式来求使用率,GPU貌似不是这样记录的。并不是递增的。因为可能是多核的,所以要使用avg平均出所有核。

pod的cpu使用率

sum(rate(container_cpu_usage_seconds_total{image!="", container_name!="POD"}[5m])) by (pod_name,sn_pod_ip,container_name,namespace) / sum(container_spec_cpu_quota{image!="", container_name!="POD"}/container_spec_cpu_period{image!="", container_name!="POD"}) by (pod_name,sn_pod_ip,container_name,namespace)

机器平均负载

node_load1{instance="xxx"} // 1分钟负载
node_load5{instance="xxx"} // 5分钟负载
node_load15{instance="xxx"} // 15分钟负载

内存使用率

100 - ((node_memory_MemFree{instance="xxx"}+node_memory_Cached{instance="xxx"}+node_memory_Buffers{instance="xxx"})/node_memory_MemTotal) * 100

磁盘使用率

100 - node_filesystem_free{instance="xxx",fstype!~"rootfs|selinuxfs|autofs|rpc_pipefs|tmpfs|udev|none|devpts|sysfs|debugfs|fuse.*"} / node_filesystem_size{instance="xxx",fstype!~"rootfs|selinuxfs|autofs|rpc_pipefs|tmpfs|udev|none|devpts|sysfs|debugfs|fuse.*"} * 100
或者你也可以直接使用 {fstype="xxx"} 来指定想查看的磁盘信息

网络 IO

// 上行带宽
sum by (instance) (irate(node_network_receive_bytes{instance="xxx",device!~"bond.*?|lo"}[5m])/128)

// 下行带宽
sum by (instance) (irate(node_network_transmit_bytes{instance="xxx",device!~"bond.*?|lo"}[5m])/128)

网卡出/入包

// 入包量
sum by (instance) (rate(node_network_receive_bytes{instance="xxx",device!="lo"}[5m]))

// 出包量
sum by (instance) (rate(node_network_transmit_bytes{instance="xxx",device!="lo"}[5m]))