配置Prometheus抓取k8s集群外的监测数据
前提:适用于通过prometheus operator在k8s集群中部署的prometheus。
K8s集群内的Prometheus抓取监测数据是通过servicemonitor这个crd来完成的。每个servicemonitor对应Prometheus中的一个target。每个servicemonitor对应一个或多个service,负责获取这些service上指定端口暴露的监测数据,并向Prometheus上报。
service是k8s集群内的资源。如果想让service对应集群外的应用,则必须手动创建endpoint。
下面以运行在集群外的某个机器上的gpu-exporter为例。地址为:https://github.com/mindprince/nvidia_gpu_prometheus_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栏,看看新创建的告警项是否已存在。