GPU虚拟化开源项目HAMi中使用prometheus与grafana做监控

背景与说明

​ HAMi,是一个国产的GPU与国产加速卡(支持的GPU与国产加速卡型号与具体特性请查看此项目官网: https://github.com/Project-HAMi/HAMi/ )虚拟化开源项目,实现以kubernetes为基础的容器场景下GPU或加速卡虚拟化。HAMi原名“k8s-vGPU-scheduler”,最初由第四范式公司开源,现已在国内与国际上愈加流行,是管理Kubernetes中异构设备的中间件。它可以管理不同类型的异构设备(如GPU、NPU等),在Pod之间共享异构设备,根据设备的拓扑信息和调度策略做出更好的调度决策。

​ 为了阐述的简明性,本文只提供一种可行的办法,最终实现使用prometheus抓取监控指标并作为数据源、使用grafana来展示监控信息的目的。

​ 本文假定已经部署好Kubernetes集群、HAMi。以下涉及到的相关组件都是在kubernetes集群内安装的,相关组件或软件版本信息如下:

组件或软件名称 版本 备注
kubernetes集群 v1.23.10 AMD64构架服务器环境下
HAMi 根据向开源作者提问,当前HAMi版本发行机制还不够成熟,暂以安装HAMi的scheduler.kubeScheduler.imageTag 参数值为其版本,此值要跟kubernetes版本看齐 项目地址:https://github.com/Project-HAMi/HAMi/
kube-prometheus stack 分支 release-0.11
dcgm-exporter tag 3.2.5-3.1.7

部署与配置kube-prometheus stack

部署kube-prometheus stack

注:kubernetes与kube-prometheus stack的版本兼容矩阵请查看 https://github.com/prometheus-operator/kube-prometheus?tab=readme-ov-file#compatibility ,请根据自己的kubernetes版本选择合适版本的kube-prometheus stack

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#下载kube-prometheus代码仓库(此处使用分支 release-0.11)
git clone -b release-0.11 https://github.com/prometheus-operator/kube-prometheus.git
cd kube-prometheus

#修改下grafana的service类型为NodePort。即在spec下添加type配置项
vi manifests/grafana-service.yaml
...
spec:
type: NodePort
...
#类似的方法修改prometheus与alertmanager service类型为NodePort,它们的配置文件分别是manifests目录下的prometheus-service.yaml与alertmanager-service.yaml

#执行部署
kubectl create -f manifests/setup/
kubectl create -f manifests/.

#创建的所有资源对象都在monitorin命名空间下,使用如下命令查看资源对象的运行状态
kubectl -n monitoring get all
1
2
3
4
5
6
#等monitorin命名空间下所有资源对象处于正常运行状态后,使用如下方式获取grafana、prometheus与alertmanager的svc信息
root@controller01:~/kube-prometheus# kubectl -n monitoring get svc | egrep "NAME|grafana|prometheus-k8s|alertmanager-main"
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
alertmanager-main NodePort 10.233.5.65 <none> 9093:30093/TCP,8080:30401/TCP 19h
grafana NodePort 10.233.56.112 <none> 3000:30300/TCP 19h
prometheus-k8s NodePort 10.233.38.113 <none> 9090:30090/TCP,8080:31273/TCP 19h

​ 此时,假如控制节点的ip是10.0.0.21,则可以分别使用如下url访问grafana、prometheus与alertmanager:http://10.0.0.21:30300 、http://10.0.0.21:30090 、http://10.0.0.21:30093 ,其中访问grafana的默认用户名与密码都是admin

​ 笔者后来在部署好上述 kube-prometheus stack后,发现 自己笔记本电脑访问prometheus的nodeport-service+port时 提示连接超时,但在k8s集群内部访问控制节点+service/prometheus-k8s加port、service/prometheus-k8s的cluster-ip加port、pod/prometheus-k8s-xxx加3000端口都没有问题。此时可以检查 下networkpolicies,如果你知道修改networkpolicies规则请直接修改,否则可以直接删除相关networkpolicies,之后在自己笔记本电脑上访问grafana、prometheus与alertmanager相关界面就正常了。

image-20250110161557368

配置grafana

创建数据源ALL

​ 访问”Configuration“->“Data soutces”页面,创建一个名为"ALL"的数据源,其中HTTP.URL的值保持跟默认创建的数据源“prometheus”中的一样即可为 “http://prometheus-k8s.monitoring.svc:9090” ,然后保存上述数据源“ALL”

导入HAMi默认的dashboard

​ 访问“Dashboards”->“Browse”页面,导入此dashboard: https://grafana.com/grafana/dashboards/22043-hami-vgpu-metrics-dashboard/ ,grafana中将创建一个名为“hami-vgpu-metrics-dashboard”的dashboard,此时此页面中有一些Panel如vGPUCorePercentage还没有数据,请继续看完此文档,执行完"部署dcgm-exporter"与“创建ServiceMonitor”中的步骤之后Panel数据将正常显示。

部署dcgm-exporter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#下载dcgm-exporter代码仓库(未看到与kubernetes的兼容矩阵说明,此处使用tag 3.2.5-3.1.7)
git clone -b 3.2.5-3.1.7 https://github.com/NVIDIA/dcgm-exporter.git
cd dcgm-exporter

#修改 deployment/values.yaml 文件,为其中的serviceMonitor添加relabelings配置,这样dcgm-exporter的监控指标才有node_name与ip属性
#只有这一处serviceMonitor,relabelings内的内容都是添加的,添加后内容如下
root@controller01:~/dcgm-exporter# vi deployment/values.yaml
...
serviceMonitor:
enabled: true
interval: 15s
honorLabels: false
additionalLabels: {}
#monitoring: prometheus
relabelings:
- sourceLabels: [__meta_kubernetes_endpoints_name]
regex: dcgm-exporter
replacement: $1
action: keep
- sourceLabels: [__meta_kubernetes_pod_node_name]
regex: (.*)
targetLabel: node_name
replacement: ${1}
action: replace
- sourceLabels: [__meta_kubernetes_pod_host_ip]
regex: (.*)
targetLabel: ip
replacement: $1
action: replace
...

#使用helm工具在monitoring空间下安装dcgm-exporter
root@controller01:~/dcgm-exporter# helm install dcgm-exporter deployment/ -n monitoring

#查看helm install结果
root@controller01:~/dcgm-exporter# helm list -n monitoring
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
dcgm-exporter monitoring 1 2024-10-02 16:32:35.691073696 +0800 CST deployed dcgm-exporter-3.1.7 3.1.7
#还需确认dcgm-exporter 相关的pod已经处于running状态
root@controller01:~/dcgm-exporter# kubectl -n monitoring get pods | egrep "NAME|dcgm-exporter"
NAME READY STATUS RESTARTS AGE
dcgm-exporter-p4fdp 1/1 Running 0 4h14m

创建ServiceMonitor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#创建文件hami-device-plugin-svc-monitor.yaml
root@controller01:~# touch hami-device-plugin-svc-monitor.yaml
#文件hami-device-plugin-svc-monitor.yaml内容如下
root@controller01:~# cat hami-device-plugin-svc-monitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: hami-device-plugin-svc-monitor
namespace: kube-system
spec:
selector:
matchLabels:
app.kubernetes.io/component: hami-device-plugin
namespaceSelector:
matchNames:
- "kube-system"
endpoints:
- path: /metrics
port: monitorport
interval: "15s"
honorLabels: false
relabelings:
- sourceLabels: [__meta_kubernetes_endpoints_name]
regex: hami-.*
replacement: $1
action: keep
- sourceLabels: [__meta_kubernetes_pod_node_name]
regex: (.*)
targetLabel: node_name
replacement: ${1}
action: replace
- sourceLabels: [__meta_kubernetes_pod_host_ip]
regex: (.*)
targetLabel: ip
replacement: $1
action: replace

#应用此文件
root@controller01:~# kubectl apply -f hami-device-plugin-svc-monitor.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#创建文件hami-scheduler-svc-monitor.yaml
root@controller01:~# touch hami-scheduler-svc-monitor.yaml
#文件hami-scheduler-svc-monitor.yaml内容如下
root@controller01:~# cat hami-scheduler-svc-monitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: hami-scheduler-svc-monitor
namespace: kube-system
spec:
selector:
matchLabels:
app.kubernetes.io/component: hami-scheduler
namespaceSelector:
matchNames:
- "kube-system"
endpoints:
- path: /metrics
port: monitor
interval: "15s"
honorLabels: false
relabelings:
- sourceLabels: [__meta_kubernetes_endpoints_name]
regex: hami-.*
replacement: $1
action: keep
- sourceLabels: [__meta_kubernetes_pod_node_name]
regex: (.*)
targetLabel: node_name
replacement: ${1}
action: replace
- sourceLabels: [__meta_kubernetes_pod_host_ip]
regex: (.*)
targetLabel: ip
replacement: $1
action: replace

#应用此文件
root@controller01:~# kubectl apply -f hami-scheduler-svc-monitor.yaml
1
2
3
4
5
#确认创建的ServiceMonitor
root@controller01:~# kubectl -n kube-system get servicemonitor
NAME AGE
hami-device-plugin-svc-monitor 28h
hami-scheduler-svc-monitor 28h

确认最终监控效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#创建文件gpu-pod.yaml,尝试使用HAMi虚拟出来的NVIDIA vGPU
root@controller01:~# touch gpu-pod.yaml
root@controller01:~# cat gpu-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod-01
spec:
restartPolicy: Never
containers:
- name: cuda-container
image: nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda10.2
resources:
limits:
nvidia.com/vgpu: 2 # 请求2个vGPUs
nvidia.com/gpumem: 3000 # 每个vGPU申请3000m显存 (可选,整数类型)
nvidia.com/gpucores: 10 # 每个vGPU的算力为10%实际显卡的算力 (可选,整数类型)

#应用此文件
root@controller01:~# kubectl apply -f gpu-pod.yaml
root@controller01:~# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
gpu-pod-01 0/1 Completed 0 52s 10.233.81.70 controller01 <none> <none>

​ 此时,应该可以dashboard中看到监控详情。

​ 导入dashboard时少许panel如“GPU Total”的内容可能未被正确解析,将造成其内容不能正常显示,此时请将dashboard文件下载下来,手动编辑对应内容,将数据源“Data source”修改为"ALL",同时将“Metrics browser”修改正确的promQL语句(可以从下载下来的dashboard中查找),其他默认即可。如果不会修改,这里也提供一份在grafana8.5.5中可用的dashboard,阿里云盘分享链接https://www.alipan.com/s/1X8fTqisx6y 提取码: r48s

​ 正常时,内容大概如下

image-20241003215400685

GPU虚拟化开源项目HAMi中使用prometheus与grafana做监控
https://jiangsanyin.github.io/2024/10/07/GPU虚拟化开源项目HAMi中使用prometheus与grafana做监控/
作者
sanyinjiang
发布于
2024年10月7日
许可协议