一、docker使用nvidia GPU
1、nvidia-docker2
安装使用NVIDIA-Docker--使用GPU的Docker容器
https://blog.csdn.net/qq_31747765/article/details/108922204
2、nvidia-container-toolkit
最新版的nvidia-docker就是nvidia-container-toolkit,比nvidia-docker2更加优秀
nvidia-container-toolkit需要主机已安装当前新版的docker 19.03
使用nvidia-container-toolkit的最大优点:
linux主机不需要安装cuda和cudnn,仅安装显卡驱动即可(tensorflow和nvidia-docker官方均强调这一点)
3、实操
设置下载源
yum install https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
curl -s -L https://nvidia.github.io/nvidia-docker/centos7/x86_64/nvidia-docker.repo | sudo tee /etc/yum.repos.d/nvidia-docker.repo
补充:有的网址是自动跳转的。curl使用 -L
参数,curl 就会跳转到新的网址。-s, --silent Silent mode. Don't output anything静默不输出信息
检测显卡驱动和型号
$ sudo yum install nvidia-detect
$ nvidia-detect -v
Probing for supported NVIDIA devices...
[10de:1e04] NVIDIA Corporation TU102 [GeForce RTX 2080 Ti]
This device requires the current 440.64 NVIDIA driver kmod-nvidia
[1af4:1050] Red Hat, Inc. Virtio GPU
Linux查看显卡信息:(ps:若找不到lspci命令,可以安装 yum install pciutils)
lspci | grep -i vga
使用nvidia GPU可以:
lspci | grep -i nvidia
查看显卡驱动
cat /proc/driver/nvidia/version
4、下载对应版本的显卡驱动
NIVID官网:http://www.geforce.cn/drivers
5、查找可安装的nvidia docker
版本
yum search --showduplicates nvidia-docker
下载的时候,在手动搜索驱动程序中,大致勾选自己机器的类型,然后查找到跟步骤3检测到的型号对应的版本进行下载
nvidia-docker配置如下:
$ cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://xxxxxxx"], #替换成自己的harbor仓库地址
"live-restore": true,
"default-shm-size": "128M",
"max-concurrent-downloads": 10,
"oom-score-adjust": -1000,
"debug": false,
"exec-opts": ["native.cgroupdriver=cgroupfs"],
"log-driver": "json-file",
"log-opts": {
"max-size": "20m",
"max-file": "3"
},
"storage-driver": "overlay2",
"default-runtime": "nvidia",
"storage-opts": [
"overlay2.override_kernel_check=true"
],
"runtimes": {
"nvidia": {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs": []
}
}
}
注意:
1、如果您有自定义/etc/docker/daemon.json
,则nvidia-docker2
程序包会覆盖它,可能导致docker 原有的 volume配置会全部丢失。
2、内核问题,centos7内核3.10.0-957.el7.x86_64适配成功过,若是不满足,请升级内核
# 资料 https://unix.stackexchange.com/questions/115289/driver-install-kernel-source-not-found
yum -y install kernel-devel kernel-header
二、nvidia-smi命令
nvidia 的系统管理界面 (nvidia-smi),可以收集各种级别的信息,查看显存使用情况。此外, 可以启用和禁用 GPU 配置选项 (如 ECC 内存功能)。
1、nvidia-smi
第一栏的Fan:N/A是风扇转速,从0到100%之间变动,这个速度是计算机期望的风扇转速,实际情况下如果风扇堵转,可能打不到显示的转速。有的设备不会返回转速,因为它不依赖风扇冷却而是通过其他外设保持低温(比如我们实验室的服务器是常年放在空调房间里的)。
第二栏的Temp:是温度,单位摄氏度。
第三栏的Perf:是性能状态,从P0到P12,P0表示最大性能,P12表示状态最小性能。
第四栏下方的Pwr:是能耗,上方的Persistence-M:是持续模式的状态,持续模式虽然耗能大,但是在新的GPU应用启动时,花费的时间更少,这里显示的是off的状态。
第五栏的Bus-Id是涉及GPU总线的东西,domain:bus:device.function
第六栏的Disp.A是Display Active,表示GPU的显示是否初始化。
第五第六栏下方的Memory Usage是显存使用率。
第七栏是浮动的GPU利用率。
第八栏上方是关于ECC的东西。
第八栏下方Compute M是计算模式。
下面一张表示每个进程占用的显存使用率。
显存占用和GPU占用是两个不一样的东西,显卡是由GPU和显存等组成的,显存和GPU的关系有点类似于内存和CPU的关系。我跑caffe代码的时候显存占得少,GPU占得多,师弟跑TensorFlow代码的时候,显存占得多,GPU占得少。
2. nvidia-smi vgpu
查看当前vGPU的状态信息:
3. nvidia-smi vgpu -p 循环显示虚拟桌面中应用程序对GPU资源的占用情况
4. nvidia-smi -q 查看当前所有GPU的信息,也可以通过参数i指定具体的GPU。
比如nvidia-smi-q -i 0 代表我们查看服务器上第一块GPU的信息。
通过nvidia-smi -q 我们可以获取以下有用的信息:
GPU的SN号、VBIOS、PN号等信息:
GPU的总线、PCI-E总线倍速、风扇转速等信息:
GPU的显存、BAR1、所有资源利用率、ECC模式等信息:
nvidia-smi -q |grep "GPU Link" -A6
NVLink目前更主要的还是大大提升了GPU间通信的带宽。
5、nvidia-smi -L 命令:列出所有可用的 NVIDIA 设备
6、nvidia-smi topo --matrix 命令:查看系统拓扑
7、nvidia-smi topo -mp
三、shell监控GPU脚本
monitor.sh
GPU跨平台通用监控脚本
功能: Useage: monitor.sh fast|mem|gpu|temp|all|[pathToLog sleepTimeNum]
注意: ./monitor.sh fast速度最快
#!/bin/bash
#. /etc/profile
#. ~/.bash_profile
#. ~/.bashrc
# 判断nvidia-smi命令是否存在
/usr/bin/nvidia-smi > /dev/null
if [ $? -eq 0 ]
then
echo 'nvidia-smi check pass' `date`
else
echo 'nvidia-smi not exists'
exit 1
fi
# 获取GPU Count
function get_gpu_list()
{
count=`nvidia-smi -L|wc -l`
echo $count
}
#获取GPU id对应uuid
function get_uuid()
{
uuid=`nvidia-smi -q -i $1|grep 'UUID'|awk '{print $4}'`
echo $uuid
}
#获取显存使用率
function get_memory_usage()
{
usage=`nvidia-smi -q -d MEMORY -i $1|grep -E 'Total|Used'|head -2|awk '{print $3}'|xargs echo|awk '{print $2/$1}'`
echo $usage
}
#获取内存详细信息
function get_memory_detail()
{
detail=`nvidia-smi -q -d MEMORY -i $1|grep -E 'Total|Used|Free'|head -3|awk '{print $3}'|xargs echo`
echo $detail
}
#获取GPU使用率
function get_volatile_gpu()
{
vol=`nvidia-smi -q -d UTILIZATION -i $1 |grep -A 5 "GPU Utilization"|tail -1|awk '{print $3}'`
echo $vol
}
#获取GPU Current 温度
function get_temperature()
{
temp=`nvidia-smi -q -d Temperature -i $1|grep 'GPU Current'|awk '{print $5}'`
echo $temp
}
#获取Pod_id
function get_pod_id()
{
echo `hostname`
}
#数据output
#output $1 $2 $3 $4 $5
#$1 字段名 $2 pod_id $3 gpu编号 $4 uuid $5 监控值
function output()
{
echo $1"{podid=\""$2"\",gpu=\""$3"\",uuid=\""$4"\"}" $5
}
#输出mem prometheus格式数据
#dcgm_mem_usage{pod_id="localhost"}
function mem_prm()
{
for((i=0;i<`get_gpu_list`;i++))
do
name="dcgm_mem_usage"
pod_id=`get_pod_id`
uuid=`get_uuid $i`
value=`get_memory_usage $i`
output $name $pod_id $i $uuid $value
done
}
#输出mem detail prometheus格式数据
#dcgm_mem_detail{pod_id="localhost"}
function mem_detail_prm()
{
for((i=0;i<`get_gpu_list`;i++))
do
pod_id=`get_pod_id`
uuid=`get_uuid $i`
value=`get_memory_detail $i`
output "dcgm_fb_total" $pod_id $i $uuid `echo $value|awk '{print $1}'`
output "dcgm_fb_used" $pod_id $i $uuid `echo $value|awk '{print $2}'`
output "dcgm_fb_free" $pod_id $i $uuid `echo $value|awk '{print $3}'`
done
}
#输出gpu prometheus格式数据
#dcgm_gpu_utilization{...}
function gpu_prm()
{
for((i=0;i<`get_gpu_list`;i++))
do
name="dcgm_gpu_utilization"
pod_id=`get_pod_id`
uuid=`get_uuid $i`
value=`get_volatile_gpu $i`
output $name $pod_id $i $uuid $value
done
}
#输出温度 prometheus格式数据
#dcgm_temp{...}
function temp_prm()
{
for((i=0;i<`get_gpu_list`;i++))
do
name="dcgm_temp"
pod_id=`get_pod_id`
uuid=`get_uuid $i`
value=`get_temperature $i`
output $name $pod_id $i $uuid $value
done
}
function allinone()
{
mem_prm
mem_detail_prm
gpu_prm
temp_prm
}
#快速获取
function fast()
{
nvidia-smi -q > /tmp/1
num=0
count=0
uuid=''
first=0
for i in `cat /tmp/1|grep -E 'Minor Number|UUID|GPU Current Temp|Gpu|Total|Used|Free'|cut -d ':' -f2|awk '{print $1}'`
do
if [ $num -eq 0 ];then
uuid=$i
elif [ $num -eq 1 ];then
count=$i
elif [ $num -eq 2 ];then
if [ $first -lt 13 ];then
echo '# HELP dcgm_fb_total Framebuffer memory total (in MiB).'
echo '# TYPE dcgm_fb_total gauge'
fi
output 'dcgm_fb_total' ${HOSTNAME} $count $uuid $i
elif [ $num -eq 3 ];then
if [ $first -lt 13 ];then
echo '# HELP dcgm_fb_used Framebuffer memory used (in MiB).'
echo '# TYPE dcgm_fb_used gauge'
fi
output 'dcgm_fb_used' ${HOSTNAME} $count $uuid $i
elif [ $num -eq 4 ];then
if [ $first -lt 13 ];then
echo '# HELP dcgm_fb_free Framebuffer memory free (in MiB).'
echo '# TYPE dcgm_fb_free gauge'
fi
output 'dcgm_fb_free' ${HOSTNAME} $count $uuid $i
elif [ $num -eq 8 ];then
if [ $first -lt 13 ];then
echo '# HELP dcgm_gpu_utilization GPU utilization (in %).'
echo '# TYPE dcgm_gpu_utilization gauge'
fi
output 'dcgm_gpu_utilization' ${HOSTNAME} $count $uuid $i
elif [ $num -eq 13 ];then
if [ $first -le 13 ];then
echo '# HELP dcgm_gpu_temp GPU temperature (in C).'
echo '# TYPE dcgm_gpu_temp gauge'
fi
output 'dcgm_gpu_temp' ${HOSTNAME} $count $uuid $i
fi
if [ $num -eq 13 ];then
num=0
else
((num++))
fi
((first++))
done
}
case $1 in
"help")
echo 'Useage: monitor.sh fast|mem|gpu|temp|all|[pathToLog sleepTimeNum]'
;;
"mem")
mem_prm
mem_detail_prm
;;
"gpu")
gpu_prm
;;
"temp")
temp_prm
;;
"fast")
fast
;;
"all")
allinone
;;
"onebyone")
if [ ! -n "$1" ];then
if [ ! -d "/run/prometheus" ];then
mkdir -p /run/prometheus
fi
while true;do allinone > /run/prometheus/`hostname`_dcgm.prom;sleep 15;done
else
if [ ! -n "$2" ];then
while true;do allinone > $1;sleep 15;done
else
while true;do allinone > $1;sleep $2;done
fi
fi
;;
*)
if [ ! -n "$1" ];then
if [ ! -d "/run/prometheus" ];then
mkdir -p /run/prometheus
fi
while true;do fast > /run/prometheus/`hostname`_dcgm.prom;sleep 15;done
else
if [ ! -n "$2" ];then
while true;do fast > $1;sleep 15;done
else
while true;do fast > $1;sleep $2;done
fi
fi
;;
esac
四、docker的存储驱动
https://docs.docker.com/storage/storagedriver/select-storage-driver/ 官网说明
1、docker支持的存储驱动
理想情况下,很少有数据写入到容器的可写层,并且您使用Docker卷来写入数据。但是,某些工作负载要求您能够写入容器的可写层。这是存储驱动程序进入的地方。
Docker支持以下存储驱动程序:
overlay2
是当前所有受支持的Linux发行版的首选存储驱动程序,不需要任何额外的配置。aufs
是在内核3.13上的Ubuntu 14.04上运行的Docker 18.06及更早版本的首选存储驱动程序,而该内核不支持overlay2
。devicemapper
支持,但是direct-lvm
对于生产环境是必需的,因为loopback-lvm
零配置虽然性能很差。devicemapper
是CentOS和RHEL的推荐存储驱动程序,因为它们的内核版本不支持overlay2
。但是,当前版本的CentOS和RHEL现在支持overlay2
,这是推荐的驱动程序。- 如果
btrfs
和zfs
驱动程序是后备文件系统(安装了Docker的主机的文件系统),则使用它们。这些文件系统允许使用高级选项,例如创建“快照”,但需要更多的维护和设置。这些中的每一个都依赖于正确配置的后备文件系统。 - 该
vfs
存储驱动程序用于测试目的,以及无法使用写时复制文件系统的情况。此存储驱动程序的性能很差,通常不建议在生产中使用
2、Supported backing filesystems
3、centos7使用overlay2
centos7中 xfs类型的文件系统,使用 xfs_info / ,ftype=1才支持overlay2,如果是0则不支持
$ xfs_info /
meta-data=/dev/sda3 isize=512 agcount=4, agsize=3080064 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0 spinodes=0
data = bsize=4096 blocks=12320256, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal bsize=4096 blocks=6015, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
centos 系统使用overlay,所以如果是xfs的文件系统,需要重新格式化
系统默认格式化xfs是没有这个参数的,所以需要重新格式化添加参数,才能支持
mkfs.xfs -n ftype=1 /dev/sdxxxx
如果是kickstart 安装的系统,用如下命令:
logvol / --fstype xfs --mkfsoptions='-n ftype=1'
注意:
1、如果用kickstart,iso/initd.img/vmlinuz 必须是同一版本
2、修改驱动之前做好数据备份!!!!!
https://gitlab.com/nvidia
https://github.com/NVIDIA/gpu-operator
https://github.com/zhebrak/nvidia_smi_exporter
https://github.com/mindprince/nvidia_gpu_prometheus_exporter gpu监控
https://www.cnblogs.com/sxgaofeng/p/12036229.html promethus监控gpu并编写自定义grafana可视化页面模板