使用node-exporter监控k8s集群内主机资源

简介

prometheus监控服务器CPU、内存、磁盘、I/O等信息,可以使用node-exporter,在虚机或物理机环境中,监控主机的步骤是,在每台主机上安装node-exporter,然后在prometheus的抓取任务中配置每一台主机的地址,每次添加主机,都需要重复去做这个操作,而在k8s环境中,我们可以通过DaemonSet类型创建node-exporter,基于Prometheus在k8s内的node类型的服务发现,可以对新扩容的主机自动部署node-exporter并纳入监控。

操作

首先了解一下DaemonSet

DaemonSet确保全部(或者一些)Node上运行一个Pod的副本。当有Node加入集群时,也会为他们新增一个Pod。当有Node从集群
移除时,这些Pod也会被回收。

简单来说,默认配置下,daemonset会在集群中每一台节点上都运行一个pod,但不包括master节点,如果想在master节点上也运行pod的话,需要在启动参数中配置tolerations

然后是在k8s环境下安装node-exporter需要注意的问题,我们查看node-exporter官方文档

The node_exporter is designed to monitor the host system. It's not recommended to deploy it as a Docker container because it 
requires access to the host system. Be aware that any non-root mount points you want to monitor will need to be bind-mounted into 
the container. If you start container for host monitoring, specify path.rootfs argument. This argument must match path in bind-mount 
of host root. The node_exporter will use path.rootfs as prefix to access host filesystem.

该node_exporter设计用于监控主机系统。不建议将其部署为Docker容器,因为它需要访问主机系统。请注意,您要监视的所有非根
安装点都需要绑定安装到容器中。如果启动用于主机监视的容器,请指定path.rootfs参数。此参数必须与主机根的bind-mount中的路
径匹配。node_exporter将 path.rootfs用作访问主机文件系统的前缀。

大致意思就是如果要在容器环境中部署node-exporter,需要将主机的根节点绑定到容器环境,不然在查询磁盘等参数时,数据是不准确的

部署

了解了这些内容后,我们就可以部署node-exporter了,直接放出 node-exporter.yaml

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: monitoring
  labels:
    app: node-exporter
spec:
  template:
    metadata:
      labels:
        app: node-exporter
    spec:
      hostPID: true
      hostIPC: true
      hostNetwork: true
      containers:
      - name: node-exporter
        image: quay.io/prometheus/node-exporter
        ports:
        - containerPort: 9100
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
          limits:
            cpu: 2000m
            memory: 2Gi        
        securityContext:
          privileged: true
        args:
        - --path.procfs
        - /host/proc
        - --path.sysfs
        - /host/sys
        - --path.rootfs
        - /host/root
        - --collector.filesystem.ignored-mount-points
        - '"^/(sys|proc|dev|host|etc)($|/)"'
        - "--collector.processes"
        volumeMounts:
        - name: dev
          mountPath: /host/dev
        - name: proc
          mountPath: /host/proc
        - name: sys
          mountPath: /host/sys
        - name: rootfs
          mountPath: /host/root
      tolerations:
      - key: "node-role.kubernetes.io/master"
        operator: "Exists"
        effect: "NoSchedule"
      volumes:
        - name: proc
          hostPath:
            path: /proc
        - name: dev
          hostPath:
            path: /dev
        - name: sys
          hostPath:
            path: /sys
        - name: rootfs
          hostPath:
            path: /
#部署
kubectl apply -f node-exporter.yaml

查看pod列表会发现,所有的k8s集群节点上都已经部署上相应的pod了

数据抓取

node-exporter部署完成后,就可以通过prometheus来抓取主机数据了,因为是每一台机器上都部署了node-exporter,所以与cAdvisor相同,我们可以通过node服务发现方式去发现每一台主机并抓取数据

- job_name: 'kubernetes-node-exporter'
  kubernetes_sd_configs:
  - role: node
  relabel_configs:
  - source_labels: [__address__]
    regex: '(.*):10250'
    replacement: '${1}:9100'
    target_label: __address__
    action: replace
  - source_labels: [__meta_kubernetes_node_name]
    action: replace
    target_label: node      
  - action: labelmap
    regex: __meta_kubernetes_node_label_(.+)
  - source_labels: [__meta_kubernetes_node_address_InternalIP]
    action: replace
    target_label: ip

将以上配置添加到configmap prometheus-config中,详见“k8s环境下搭建prometheus”一文,更新configmap和pod

## 更新configmap
kubectl create configmap prometheus-config --from-file=prometheus.yaml -n monitoring -o yaml --dry-run | kubectl replace -f -

## 更新pod
kubectl apply -f prometheus-deploy.yaml

## 热更新配置
curl -XPOST http://localhost:30090/-/reload

页面查看prometheus,就可以看到相应的metrics

常用查询


100 - sum by(ip,instance, mountpoint) (node_filesystem_avail_bytes / node_filesystem_size_bytes)

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

(((node_memory_MemTotal_bytes - node_memory_MemFree_bytes - node_memory_Cached_bytes) / (node_memory_MemTotal_bytes) * 100))

欢迎关注我的个人微信公众号,一个菜鸟程序猿的技术分享和奔溃日常

一个菜鸟程序猿的技术技术分享和奔溃日常

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐