配置Prometheus抓取k8s集群外的监测数据

K8s集群内的Prometheus抓取监测数据是通过servicemonitor这个crd来完成的。每个servicemonitor对应Prometheus中的一个target。每个servicemonitor对应一个或多个service,负责获取这些service上指定端口暴露的监测数据,并向Prometheus上报。

service是k8s集群内的资源。如果想让service对应集群外的应用,则必须手动创建endpoint。

下面以运行在集群外的某个机器上的gpu-exporter为例。

一、手动创建endpoint

gpu-exporter占用宿主机的9445端口,因此创建endpoint如下:

apiVersion: v1
kind: Endpoints
metadata:
  name: gpu-data
subsets:
- addresses:
  - ip: [宿主机ip]
  ports:
  - port: 9445
    name: gpu

注意,为了后面创建servicemonitor时使用,这里给port起一个名字。

二、创建service与endpoint绑定

创建与endpoint名字相同的service,则二者会自动绑定。

apiVersion: v1
kind: Service
metadata:
  name: gpu-data
  labels:
    app: gpu-data
spec:
  ports:
  - port: 9445
    targetPort: 9445
    name: gpu

注意,service的name字段必须与endpoint相同,并且下面port的name也需要相同。另外,需要为这个service配置一个label,以便后面servicemonitor进行筛选。

创建后,执行kubectl describe,看看service的endpoint字段是否已经显示为[宿主机ip]:9445。执行curl [service的ip]:9445,看看有没有监测数据的返回值。

三、创建servicemonitor

创建与service同名的servicemonitor:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  labels:
    app: prometheus
    prometheus: prometheus
  name: gpu-data
spec:
  endpoints:
  - interval: 10s
    path: /
    targetPort: 9445
    port: gpu
  jobLabel: k8s-app
  namespaceSelector:
    matchNames:
    - default
  selector:
    matchLabels:
      app: gpu-data

servicemonitor的label需要查看Prometheus中对应的servicemonitor字段:

kubectl get prometheus -n kube-system prometheus-operator-prometheus -o yaml 

查看serviceMonitorSelector.matchExpressions字段中对应的key、value对,选出一对填写在metadata.labels中即可。

下面的spec.endpoint中,port填写前面service和endpoint中定义的port名字,path这里是/,因为gpu-exporter直接暴露在ip:9445/下。很多情况下会填写/metrics。

后面selector需要填写之前service定义的label。

创建后,查看Prometheus的页面,查找target,看看是否出现了default/gpu-data这一个target。

四、判断数据是否已经为Prometheus接受

可以直接通过http api判断:

curl [prometheus的pod或serviceip]:9090/api/v1/query?query=nvidia_gpu_memory_used_bytes

看看有无监测数据输出。

五、配置告警项

更进一步的,在Prometheus接收到监测数据后,可以配置相关的告警项,使GPU的告警数据可以被AlertManager接收到。

配置告警项通过创建Prometheusrule资源来实现。这里创建了GPU显存利用率超过90%告警的指标:

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  labels:
    app: prometheus-rules
    cato: node
    release: prometheus-operator
  name: gpu.alert
  namespace: kube-system
spec:
  groups:
  - name: gpu.alert.rules
    rules:
    - alert: GPUMemUsageHigh
      annotations:
        description: 'instance: {{ $labels.instance }}, value: {{ $value }}'
        summary: GPU Memory Usage > 0.9 for 2m
      expr: nvidia_gpu_memory_used_bytes / 24032378880 > 0.9
      for: 2m
      labels:
        severity: warning

其中,metadata.labels应该与prometheus的ruleSelector.matchLabels字段完全一致。通过以下命令查看ruleSelector.matchLabels字段,将其完全复制到prometheusrule中的metadata.labels字段中:

kubectl get prometheus -n kube-system -o yaml | grep ruleSelector -A 10

另外,gpu-exporter没有显存利用率指标,只有显存利用量,因此需要用nvidia_gpu_memory_used_bytes除以GPU卡的总显存量,以获取显存利用率指标。

创建prometheusrule后,查看prometheus的portal页面的targets栏,看看新创建的告警项是否已存在。

原文地址:https://www.cnblogs.com/00986014w/p/12655031.html