前提:適用於通過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欄,看看新創建的告警項是否已存在。