背景
我們知道,如果在Kubernetes中支持GPU設備調度,需要做如下的工作:
-
節點上安裝nvidia驅動
-
節點上安裝nvidia-docker
-
集群部署gpu device plugin,用於為調度到該節點的pod分配GPU設備。
除此之外,如果你需要監控集群GPU資源使用情況,你可能還需要安裝DCCM exporter結合Prometheus輸出GPU資源監控信息。
要安裝和管理這麼多的組件,對於運維人員來說壓力不小。基於此,NVIDIA開源了一款叫NVIDIA GPU Operator的工具,該工具基於Operator Framework實現,用於自動化管理上面我們提到的這些組件。
NVIDIA GPU Operator有以下的組件構成:
-
安裝nvidia driver的組件
-
安裝nvidia container toolkit的組件
-
安裝nvidia devcie plugin的組件
-
安裝nvidia dcgm exporter組件
-
安裝gpu feature discovery組件
本系列文章不打算一上來就開始講NVIDIA GPU Operator,而是先把各個組件的安裝詳細的分析一下,然後手動安裝這些組件,最後再來分析NVIDIA GPU Operator就比較簡單了。
在本篇文章中,我們將介紹NVIDIA GPU Operator安裝NVIDIA DCGM Exporter的原理。
DCGM Exporter簡介
DCGM Exporter是一個用golang編寫的收集節點上GPU信息(比如GPU卡的利用率、卡溫度、顯存使用情況等)的工具,結合Prometheus和Grafana可以提供豐富的儀表大盤。
從1.13開始,kubelet通過/var/lib/kubelet/pod-resources下的Unix套接字來提供pod資源查詢服務,dcgm-exporter可以訪問/var/lib/kubelet/pod-resources/下的套接字服務查詢為每個pod分配的GPU設備,然後將GPU的pod信息附加到收集的度量中。
DCGM Exporter服務在每個節點上都存在一個,當Prometheus使用拉數據這種模式時,每隔一段時間(用戶可設置時間間隔)就訪問該節點GCGM Exporter的服務獲取該節點GPU相關指標,然後存入的Prometheus的數據庫中,grafana每隔一段時間(用戶可設置時間間隔)從Prometheus數據庫中拿取該節點GPU指標,然後在瀏覽器中通過各種儀表盤展示出來。
k8s集群節點安裝DCGM Exporter
接下來演示一下如何在集群中安裝DCGM Exporter。
前提條件
在執行安裝操作前,你需要確認以下的條件是否滿足:
-
k8s集群的版本 > 1.8。
-
集群中的GPU節點已經安裝了GPU驅動,如果沒有安裝驅動,請參考本系列文章《NVIDIA GPU Operator分析一:NVIDIA驅動安裝》。
-
集群中的GPU節點已經安裝NVIDIA Container Toolkit,如果沒有安裝,請參考本系列文章《NVIDIA GPU Operator分析二:NVIDIA Container Toolkit安裝》。
-
集群中的GPU節點已經安裝NVIDIA Device Plugin,如果沒有安裝,請參考本系列文章《NVIDIA GPU Operator分析三:NVIDIA Device Plugin安裝》。
安裝DCGM Exporter
1.下載gpu-operator源碼。
$ git clone -b 1.6.2 https://github.com/NVIDIA/gpu-operator.git
$ cd gpu-operator
$ export GPU_OPERATOR=$(pwd)
2.確認節點已經打了標籤nvidia.com/gpu.present=true。
$ kubectl get nodes -L nvidia.com/gpu.present
NAME STATUS ROLES AGE VERSION GPU.PRESENT
cn-beijing.192.168.8.44 Ready <none> 13d v1.16.9-aliyun.1 true
cn-beijing.192.168.8.45 Ready <none> 13d v1.16.9-aliyun.1 true
cn-beijing.192.168.8.46 Ready <none> 13d v1.16.9-aliyun.1 true
cn-beijing.192.168.9.159 Ready master 13d v1.16.9-aliyun.1
cn-beijing.192.168.9.160 Ready master 13d v1.16.9-aliyun.1
cn-beijing.192.168.9.161 Ready master 13d v1.16.9-aliyun.1
3.修改assets/state-monitoring/0300_rolebinding.yaml,註釋兩個字段,否則無法提交:
-
將userNames這一行和其後面的一行註釋。
#userNames:
#- system:serviceaccount:gpu-operator:nvidia-device-plugin
-
將roleRef.namespace這一行註釋。
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: nvidia-device-plugin
# namespace: gpu-operator-resources
4.修改assets/state-monitoring/0900_daemonset.yaml,補充鏡像名稱。
-
修改initContainers中toolkit-validation的鏡像名稱為nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda10.2
initContainers:
- name: toolkit-validation
image: "nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda10.2"
command: ['sh', '-c']
-
修改containers中nvidia-dcgm-exporter的鏡像名稱為nvcr.io/nvidia/k8s/dcgm-exporter:2.1.4-2.2.0-ubuntu20.04
containers:
- image: "nvcr.io/nvidia/k8s/dcgm-exporter:2.1.4-2.2.0-ubuntu20.04"
name: nvidia-dcgm-exporter
5.部署DCGM Exporter。
$ cd assets/state-monitoring
$ rm -rf *openshift*
$ kubectl apply -f ./
6.查看pod是否處於Running。
$ kubectl get po -n gpu-operator-resources -l app=nvidia-dcgm-exporter
NAME READY STATUS RESTARTS AGE
nvidia-dcgm-exporter-ff6zp 1/1 Running 0 3m31s
nvidia-dcgm-exporter-tk7xk 1/1 Running 0 3m31s
nvidia-dcgm-exporter-zdfg6 1/1 Running 0 3m31s
7.獲取nvidia-dcgm-exporter服務監聽的端口。
$ kubectl get svc -n gpu-operator-resources nvidia-dcgm-exporter -o yaml
apiVersion: v1
kind: Service
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{"prometheus.io/scrape":"true"},"labels":{"app":"nvidia-dcgm-exporter"},"name":"nvidia-dcgm-exporter","namespace":"gpu-operator-resources"},"spec":{"ports":[{"name":"gpu-metrics","port":9400,"protocol":"TCP","targetPort":9400}],"selector":{"app":"nvidia-dcgm-exporter"}}}
prometheus.io/scrape: "true"
creationTimestamp: "2021-03-26T09:39:01Z"
labels:
app: nvidia-dcgm-exporter
name: nvidia-dcgm-exporter
namespace: gpu-operator-resources
resourceVersion: "5634508"
selfLink: /api/v1/namespaces/gpu-operator-resources/services/nvidia-dcgm-exporter
uid: 55b81b2a-32a6-4a97-b75a-ad318a9443fd
spec:
clusterIP: 10.51.129.82
ports:
- name: gpu-metrics
port: 9400
protocol: TCP
targetPort: 9400
selector:
app: nvidia-dcgm-exporter
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
可以看到,服務監聽的端口為9400,端口名稱為gpu-metrics。
配置ServiceMonitor
1.部署ServiceMonitor(需要創建一個文件servicemonitor.yaml),用於Prometheus找到節點上dcgm-exporter服務監聽的端口,然後訪問dcgm-exporter。
$ cat servicemonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: nvidia-dcgm-exporter
labels:
app: nvidia-dcgm-exporter
namespace: gpu-operator-resources
spec:
selector:
matchLabels:
app: nvidia-dcgm-exporter
namespaceSelector:
matchNames:
- gpu-operator-resources
# any: true
endpoints:
- port: gpu-metrics # 此處填寫步驟7獲得的端口名稱,即gpu-metrics
interval: "30s" # 表示prometheus多長時間訪問一次dcgm-exporter獲取gpu指標。
path: /metrics
2.使用kubectl部署:
$ kubectl apply -f servicemonitor.yaml
在grafana中安裝dashboard
1.從https://grafana.com/grafana/dashboards/12239下載dashboard,點擊界面右面的“Download JSON”進行下載,文件名稱為nvidia-dcgm-exporter-dashboard_rev1.json。
2.點擊“+” -> Import導入nvidia-dcgm-exporter-dashboard_rev1.json。
導入時需要選擇數據源(來自哪個集群)。
3.導入後效果如圖。
驗證
當監控大盤安裝完成後,可以通過提交一個任務查看監控是否有效。
1.部署一個tensorflow任務。
cat /tmp/gpu-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-gpu
labels:
test-gpu: "true"
spec:
containers:
- name: training
image: registry.cn-beijing.aliyuncs.com/ai-samples/tensorflow:1.5.0-devel-gpu
command:
- python
- tensorflow-sample-code/tfjob/docker/mnist/main.py
- --max_steps=10000
- --data_dir=tensorflow-sample-code/data
resources:
limits:
nvidia.com/gpu: 1
workingDir: /root
restartPolicy: Never
使用kubectl命令部署。
$ kubectl apply -f /tmp/gpu-test.yaml
2.查看dashboard數據是否變化(注意需要開啟自動刷新界面功能,點擊右上角off,選擇一個刷新頻率,比如15s)。
可以看到有一個GPU的利用率發生了變化。
與Arena Exporter對比
目前,NVIDIA GPU Operator提供的監控儀表盤可參考的指標還是比較簡單的,比如:節點GPU使用率、節點GPU溫度、每張GPU卡已使用的顯存等。儀表盤還存在著如下的一些缺點:
-
無法從應用的角度觀察GPU的使用情況,比如:某個Pod使用了多少GPU顯存、GPU使用率是多少,或者更高級的功能是某個訓練任務使用了多少GPU顯存、GPU使用率是多少。
-
無法查看集群的GPU的整體使用情況,比如:集群總的GPU數、已使用GPU數、集群已使用的GPU顯存等。
-
在當前的監控大盤中,GPU是用GPU Index表示的,所以你可以看到,示例集群中有三個節點,每個節點有一張GPU卡,但是在監控大盤中每塊GPU的標識都是GPU0,無法區分哪張卡是屬於哪個節點。
阿里雲容器服務團隊基於Arena實現的Arena Exporter結合Prometheus以及Grafana能夠從更多的維度展示集群的GPU資源使用情況(詳見:雲原生AI監控):
-
集群儀表盤概覽
-
節點儀表盤概覽
-
訓練任務儀表盤概覽
總結
本篇文章首先簡單介紹了DCGM Exporter,然後演示瞭如何部署dcgm exporter以及結合prometheus和grafana將監控指標通過儀表盤展示出來,最後簡單的對比了DCGM Exporter與Arena Exporter。