prometheus及gpu,k8s

一,物理节点安装配置(简单配置,未涉及报警及grafana图形展示)

1,prometheus 官网下载安装

下载安装
# pwd
/usr/local/src
https://github.com/prometheus/prometheus/releases/download/v2.12.0/prometheus-2.12.0.linux-amd64.tar.gz
# tar xvf prometheus-2.11.1.linux-amd64.tar.gz
# ln -sv /usr/local/src/prometheus-2.11.1.linux-amd64 /usr/local/prometheus
# cd /usr/local/prometheus

服务启动脚本
# vim /etc/systemd/system/prometheus.service
[Unit]
Description=Prometheus Server
Documentation=https://prometheus.io/docs/introduction/overview/
After=network.target
[Service]
Restart=on-failure
WorkingDirectory=/usr/local/prometheus/
ExecStart=/usr/local/prometheus/prometheus --
config.file=/usr/local/prometheus/prometheus.yml
[Install]
WantedBy=multi-user.target

配置所监控的node
cd /usr/local/prometheus
# grep -v "#" prometheus.yml | grep -v "^$"
global:
alerting:
  alertmanagers:
  - static_configs:
    - targets:
rule_files:
scrape_configs:
  - job_name: 'prometheus'
    static_configs:
    - targets: ['localhost:9090']
  - job_name: 'promethues-node'
    static_configs:
    - targets: ['192.168.7.110:9100','192.168.7.111:9100']


修改配置文件后需要重启服务
启动
# systemctl daemon-reload
# systemctl restart prometheus
# systemctl enable prometheus
查看端口是否监听正常

2,节点安装

# pwd
/usr/local/src

https://github.com/prometheus/node_exporter/releases/download/v0.18.1/node_exporter-0.18.1.linux-amd64.tar.gz
# tar xvf node_exporter-0.18.1.linux-amd64.tar.gz
# ln -sv /usr/local/src/node_exporter-0.18.1.linux-amd64 /usr/local/node_exporter
# cd /usr/local/node_exporter


启动脚本
# vim /etc/systemd/system/node-exporter.service
[Unit]
Description=Prometheus Node Exporter
After=network.target
[Service]
ExecStart=/usr/local/node_exporter/node_exporter
[Install]
WantedBy=multi-user.target


启动
# systemctl daemon-reload
# systemctl restart node-exporter
# systemctl enable node-exporter
 
查看端口是否监听正常,关闭防火墙和selinxu

3,监控k8s

参考https://github.com/NVIDIA/gpu-monitoring-tools/tree/master/exporters/prometheus-dcgm

起gpu特定容器做监控

#######################################################

docker 使用GPU

查看docker 使用的runtime

docker   info  |  grep  Runtime
更改默认的runtime 
配置daemon的默认运行时
是否已安装
ls  /usr/bin/nvidia-container-runtime
nvidia-docker 命令是否出现
指定默认的runtime    "default-runtime": "nvidia"  添加加速代理镜像源

vim  /etc/docker/daemon.json 
{
    "default-runtime": "nvidia",
    "runtimes": {
        "nvidia": {
            "path": "/usr/bin/nvidia-container-runtime",
            "runtimeArgs": [],
            "registry-mirrors": ["https://gemfield.mirror.aliyuncs.com"]
        }
    }
}

重启服务
	sudo systemctl restart docker
	
	ldconfig -p 
	 dpkg -S /usr/lib/x86_64-linux-gnu/libcuda.so.1   dpkg -S命令来检查下它属于哪个package

https://gitlab.com/nvidia/cuda/blob/master/dist/ubuntu16.04/10.1/base/Dockerfile

apt-get install pciutils
apt-get install kmod    安装lspci
 apt install dirmngr

https://github.com/NVIDIA/nvidia-docker
 Docker中使用GPU
https://cloud.tencent.com/developer/article/1142345
 
 export DEVICES=$(ls /dev/nvidia* | xargs -I{} echo '--device {}:{}')
docker run -it --rm $DEVICES -v /usr/lib64/nvidia/:/usr/local/nvidia/lib64 tensorflow/tensorflow:latest-gpu bash


#nvidia-docker run -it -p 8888:8888 --name ten tensorflow/tensorflow:0.11.0rc0-gpu  /bin/sh

jupyter_jianhang_v5.1_gpu


进入容器输入nvidia-smi,输入显卡信息,说明安装是正确的。

制作docker 镜像 Anaconda3 + tensorflow-gpu part2 Dockerfile nvidia docker
https://blog.csdn.net/weixin_41270857/article/details/83449964

指定显存大小使用gpu

https://yq.aliyun.com/articles/690623?utm_content=g_1000041607

在k8s上调度GPU

http://longlongloves.life/2018-05-23/%E5%9C%A8k8s%E4%B8%8A%E8%B0%83%E5%BA%A6GPU.html

Kubernetes 多container组成的Pod

https://blog.csdn.net/liumiaocn/article/details/52490444

kubernetes单个pod运行两个容器yaml文件实践
https://blog.csdn.net/zhangxiangui40542/article/details/63273746

Docker 及 nvidia-docker 使用
https://www.cnblogs.com/makefile/p/docker-usage.html



 sudo -u nvidia-docker sh -c 'echo $PATH'  /sbin:/bin:/usr/sbin:/usr/bin

安装 CUDA

安装步骤官网
https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#verify-you-have-cuda-enabled-system
博客
https://blog.csdn.net/weixin_42652125/article/details/81178943
https://www.cnblogs.com/luofeel/p/8654964.html
https://blog.csdn.net/QLULIBIN/article/details/78714596


ubuntu安装cuda驱动实现nvidia-smi命令
https://blog.csdn.net/weixin_42652125/article/details/81178943

显卡监控



显卡信息
lspci | grep -i vga
使用nvidia GPU可以:
lspci | grep -i nvidia
[GeForce GTX 960M] (rev a2)
命令行中输入cat /proc/driver/nvidia/version查看显卡信息

https://us.download.nvidia.cn/XFree86/Linux-x86_64/384.130/NVIDIA-Linux-x86_64-384.130.run  

前边的序号 "00:0f.0"是显卡的代号(这里是用的虚拟机);
查看指定显卡的详细信息用以下指令:
lspci -v -s 00:0f.0
nvidia-smi

表头释义:
Fan:显示风扇转速,数值在0到100%之间,是计算机的期望转速,如果计算机不是通过风扇冷却或者风扇坏了,显示出来就是N/A;
Temp:显卡内部的温度,单位是摄氏度;
Perf:表征性能状态,从P0到P12,P0表示最大性能,P12表示状态最小性能;
Pwr:GPU能耗表示;
Bus-Id:涉及GPU总线的相关信息;
Disp.A:是Display Active的意思,表示GPU的显示是否初始化;
Memory Usage:显存的使用率;
Volatile GPU-Util:浮动的GPU利用率;
Compute M:计算模式;
下边的Processes显示每块GPU上每个进程所使用的显存情况。

如果要周期性的输出显卡的使用情况,可以用watch指令实现:

watch -n 10 nvidia-smi

#nvidia-smi
 nvidia-smi -L     #列出gpu 及id 
 GPU 0: GeForce GTX 960M (UUID: GPU-4d52e430-b8c7-a0b9-7fda-4aa825af5c97)
 
nvidia-smi –i   gpuid   # 指定gpuid  0,1,2,
nvidia-smi –l xxx
动态刷新信息(默认5s刷新一次),按Ctrl+C停止,可指定刷新频率,以秒为单位
nvidia-smi –f xxx
将查询的信息输出到具体的文件中,不在终端显示
nvidia-smi -q   查询所有GPU的当前详细信息
nvidia-smi –q –i xxx
指定具体的GPU或unit信息
nvidia-smi –q –f xxx
将查询的信息输出到具体的文件中,不在终端显示
nvidia-smi –q –x
将查询的信息以xml的形式输出
nvidia-smi -q –d xxx
指定显示GPU卡某些信息,xxx参数可以为MEMORY, UTILIZATION, ECC, TEMPERATURE, POWER,CLOCK, COMPUTE, PIDS, PERFORMANCE, SUPPORTED_CLOCKS, PAGE_RETIREMENT,ACCOUNTING
nvidia-smi –q –l xxx
动态刷新信息,按Ctrl+C停止,可指定刷新频率,以秒为单位
nvidia-smi --query-gpu=gpu_name,gpu_bus_id,vbios_version--format=csv
选择性查询选项,可以指定显示的属性选项
可查看的属性有:timestamp,driver_version,pci.bus,pcie.link.width.current等。(可查看nvidia-smi--help-query–gpu来查看有哪些属性)

2.3  设备修改选项
可以手动设置GPU卡设备的状态选项
nvidia-smi –pm 0/1
设置持久模式:0/DISABLED,1/ENABLED
nvidia-smi –e 0/1
切换ECC支持:0/DISABLED, 1/ENABLED
nvidia-smi –p 0/1
重置ECC错误计数:0/VOLATILE, 1/AGGREGATE
nvidia-smi –c
设置计算应用模式:0/DEFAULT,1/EXCLUSIVE_PROCESS,2/PROHIBITED
nvidia-smi –r
GPU复位
nvidia-smi –vm
设置GPU虚拟化模式
nvidia-smi –ac xxx,xxx
设置GPU运行的工作频率。e.g. nvidia-smi –ac2000,800
nvidia-smi –rac
将时钟频率重置为默认值
nvidia-smi –acp 0/1
切换-ac和-rac的权限要求,0/UNRESTRICTED, 1/RESTRICTED
nvidia-smi –pl
指定最大电源管理限制(瓦特)
nvidia-smi –am 0/1
启用或禁用计数模式,0/DISABLED,1/ENABLED
nvidia-smi –caa
清除缓冲区中的所有已记录PID,0/DISABLED,1/ENABLED

nvidia-smi pmon
nvidia-smi pmon –i xxx
用逗号分隔GPU索引,PCI总线ID或UUID
nvidia-smi pmon –d xxx
指定刷新时间(默认为1秒,最大为10秒)
nvidia-smi pmon –c xxx
显示指定数目的统计信息并退出
nvidia-smi pmon –s xxx
指定显示哪些监控指标(默认为u),其中:
u:GPU使用率
m:FB内存使用情况
nvidia-smi pmon –o D/T
指定显示的时间格式D:YYYYMMDD,THH:MM:SS
nvidia-smi pmon –f xxx
将查询的信息输出到具体的文件中,不在终端显示

阿里云GPU监控指标

MetricName 单位 名称
gpu_memory_freespace Byte GPU维度显存空闲量
gpu_memory_totalspace Byte GPU维度显存总量
gpu_memory_usedspace Byte GPU维度显存使用量
gpu_gpu_usedutilization % GPU维度GPU使用率
gpu_encoder_utilization % GPU维度编码器使用率
gpu_decoder_utilization % GPU维度解码器使用率
gpu_gpu_temperature GPU维度GPU温度
gpu_power_readings_power_draw W GPU维度GPU功率
gpu_memory_freeutilization % GPU维度显存空闲率
gpu_memory_useutilization % GPU维度显存使用率

基于阿里云容器服务监控 Kubernetes集群GPU指标
https://www.jianshu.com/p/1c7ddf18e8b2

检测脚本 #未测试
monitor.sh
GPU跨平台通用监控脚本
功能: Useage: monitor.sh fast|mem|gpu|temp|all|[pathToLog sleepTimeNum]
注意: ./monitor.sh fast速度最快

#nvidia-smi pmon -h#!/bin/bash
#. /etc/profile
#. ~/.bash_profile
#. ~/.bashrc
# 判断nvidia-smi命令是否存在
#/usr/bin/nvidia-smi > /dev/nullif 
# if [ $? -eq 0 ];then  
#       echo 'nvidia-smi check pass' `date`
#    else  
#       echo 'nvidia-smi not exists'   
#       exit 1
#  fi

        # 获取GPU Count
  get_gpu_list()
 {
        count=`nvidia-smi -L|wc -l` 
        echo $count
  }
        #获取GPU id对应uuid
get_uuid()
{
    uuid=`nvidia-smi -q -i $1|grep 'UUID'|awk '{print $4}'`   echo $uuid
}
    #获取显存使用率 
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
} 
   #获取内存详细信息
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使用率
 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 温度
 get_temperature()
{  
    temp=`nvidia-smi -q -d Temperature -i $1|grep 'GPU Current'|awk '{print $5}'`  
    echo $temp
}
    #获取Pod_id
get_pod_id()
{
    echo `hostname`
} 
#数据output
    #output $1 $2 $3 $4 $5
    #$1 字段名 $2 pod_id $3 gpu编号 $4 uuid $5 监控值
output(){
    echo $1"{podid=""$2"",gpu=""$3"",uuid=""$4""}" $5
}   
 #输出mem prometheus格式数据
    #dcgm_mem_usage{pod_id="localhost"}
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"}
 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{...}
 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{...}
 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
    }
allinone()
    { 
    mem_prm  
    mem_detail_prm 
    gpu_prm  
    temp_prm
    }
    #快速获取
 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

一,PGME监控

监控物理节点,监控指标较少

Prometheus GPU Metrics Exporter (PGME)
** https://github.com/chhibber/pgme  
#安装
Local Linux Build (Genrates a binary that works on Linuxsystems)

1,go环境配置
go包下载
https://studygolang.com/dl
解压安装
sudo tar -zxvf go1.10.linux-386.tar.gz -C /opt
检测
./opt/go/bin/go version
环境变量
vi /etc/profile
export GOPATH="/root/go"
export GOROOT="/opt/golang/go"
export GOARCH="amd64"
export GOOS=linux
#export GOTOOLS=$GOROOT/pkg/tool
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
source /etc/profile

2,安装编译pgme 
git  clone https://github.com/chhibber/pgme.git
cd pgme
make build
3,运行
#The default port is 9101,前台进程运行
PORT=9101 ./pgme
4,访问
http://localhost:9101/metrics
temperature_gpu{gpu="GeForce GTX 960M[0]"} 38
utilization_gpu{gpu="GeForce GTX 960M[0]"} 0
utilization_memory{gpu="GeForce GTX 960M[0]"} 0
memory_total{gpu="GeForce GTX 960M[0]"} 4044
memory_free{gpu="GeForce GTX 960M[0]"} 4043
memory_used{gpu="GeForce GTX 960M[0]"} 1


5,Prometheus example config
- job_name: "gpu_exporter"
  static_configs:
  - targets: ['localhost:9101']

二,Prometheus 自定义exporter 监控key

当Prometheus的node_exporter中没有我们需要的一些监控项时,就可以如zabbix一样定制一些key,让其支持我们所需要的监控项。node_exporter 可在启动时指定路径,并将该路径下的 *.prom 识别为监控数据文件。
1,获取脚本值
cat /usr/local/node_exporter/key/key_runner 
#! /bin/bash
echo Logical_CPU_core_total  `cat /proc/cpuinfo| grep "processor"| wc -l`
echo logined_users_total     `who | wc -l`;
echo procs_total `ps aux|wc -l`
echo procs_zombie       `ps axo pid=,stat=|grep Z|wc -l`
执行测试
bash  /usr/local/node_exporter/key/key_runner 

设定定时任务
* * * * * bash /usr/local/node_exporter/key/key_runner > /usr/local/node_exporter/key/key.prom

添加启动参数(在node_exporter 可执行目录下)
启动node_exporter,指定新加key值的prom路径
./node_exporter --collector.textfile.directory=/usr/local/node_exporter/key

验证 
curl 127.0.0.1:9100/metrics|grep -E "Logical_CPU_core_total|logined_users_total|procs_total|procs_zombie"

################################################
可使用nvidia-smi 自定义监控项进行监控

三,NVIDIA DCGM exporter for Prometheus (容器)

nvidia-container-runtime
https://github.com/NVIDIA/nvidia-docker


https://github.com/NVIDIA/gpu-monitoring-tools/blob/master/exporters/prometheus-dcgm/README.md

#注意
Prerequisites
NVIDIA Tesla drivers = R384+ (download from NVIDIA Driver Downloads page)
nvidia-docker version > 2.0 (see how to install and it's prerequisites)
Optionally configure docker to set your default runtime to nvidia


1,确定是否为DGCM支持的GPUS
$ docker run --runtime=nvidia --rm --name=nvidia-dcgm-exporter nvidia/dcgm-exporter
$ docker exec nvidia-dcgm-exporter dcgmi discovery -i a -v | grep -c 'GPU ID:'

$ nvidia-smi -L | wc -l
两者输出一至,否则执行脚本失败


2,Bare-metal install
$ cd bare-metal
$ sudo make install
$ sudo systemctl start prometheus-dcgm

或 docker  install 
$ cd docker
$ docker-compose up


3,docker 运行测试 #(已测试)docker 运行环境需要nvidia
$ docker run -d --runtime=nvidia --rm --name=nvidia-dcgm-exporter -v /run/prometheus:/run/prometheus nvidia/dcgm-exporter

# To check the metrics
$ cat /run/prometheus/dcgm.prom

# If you want to add GPU metrics directly to node-exporter container
$ docker run -d --rm --net="host" --pid="host" --volumes-from nvidia-dcgm-exporter:ro quay.io/prometheus/node-exporter --collector.textfile.directory="/run/prometheus"

$ curl localhost:9100/metrics

3,docker 测试结果
# HELP dcgm_dec_utilization Decoder utilization (in %).
# TYPE dcgm_dec_utilization gauge  解码使用率
dcgm_dec_utilization{gpu="0",uuid="GPU-4d52e430-b8c7-a0b9-7fda-4aa825af5c97"} 0


# HELP dcgm_ecc_dbe_volatile_total Total number of double-bit volatile ECC errors.  双位易失性ECC错误的总数
# TYPE dcgm_ecc_dbe_volatile_total counter
dcgm_ecc_dbe_volatile_total{gpu="0",uuid="GPU-4d52e430-b8c7-a0b9-7fda-4aa825af5c97"} 0


# HELP dcgm_ecc_sbe_volatile_total Total number of single-bit volatile ECC errors.   单位易失性ECC错误的总数
# TYPE dcgm_ecc_sbe_volatile_total counter
dcgm_ecc_sbe_volatile_total{gpu="0",uuid="GPU-4d52e430-b8c7-a0b9-7fda-4aa825af5c97"} 0

# HELP dcgm_enc_utilization Encoder utilization (in %).
# TYPE dcgm_enc_utilization gauge   GPU维度编码器使用率
dcgm_enc_utilization{gpu="0",uuid="GPU-4d52e430-b8c7-a0b9-7fda-4aa825af5c97"} 0 

# HELP dcgm_fb_free Framebuffer memory free (in MiB).
# TYPE dcgm_fb_free gauge    帧缓冲区空闲内存
dcgm_fb_free{gpu="0",uuid="GPU-4d52e430-b8c7-a0b9-7fda-4aa825af5c97"} 4043

# HELP dcgm_fb_used Framebuffer memory used (in MiB).
# TYPE dcgm_fb_used gauge   帧缓冲区使用内存
dcgm_fb_used{gpu="0",uuid="GPU-4d52e430-b8c7-a0b9-7fda-4aa825af5c97"} 1


# HELP dcgm_gpu_temp GPU temperature (in C).
# TYPE dcgm_gpu_temp gauge    GPU温度
dcgm_gpu_temp{gpu="0",uuid="GPU-4d52e430-b8c7-a0b9-7fda-4aa825af5c97"} 37  


# HELP dcgm_gpu_utilization GPU utilization (in %).
# TYPE dcgm_gpu_utilization gauge  GPU利用率
dcgm_gpu_utilization{gpu="0",uuid="GPU-4d52e430-b8c7-a0b9-7fda-4aa825af5c97"} 0  


# HELP dcgm_mem_copy_utilization Memory utilization (in %).
# TYPE dcgm_mem_copy_utilization gauge  显存利用率
dcgm_mem_copy_utilization{gpu="0",uuid="GPU-4d52e430-b8c7-a0b9-7fda-4aa825af5c97"} 0


# HELP dcgm_memory_clock Memory clock frequency (in MHz).
# TYPE dcgm_memory_clock gauge    显存时钟频率
dcgm_memory_clock{gpu="0",uuid="GPU-4d52e430-b8c7-a0b9-7fda-4aa825af5c97"} 405  


# HELP dcgm_pcie_replay_counter Total number of PCIe retries.
# TYPE dcgm_pcie_replay_counter counter     PCIe重试总数
dcgm_pcie_replay_counter{gpu="0",uuid="GPU-4d52e430-b8c7-a0b9-7fda-4aa825af5c97"} 0  


# HELP dcgm_pcie_rx_throughput Total number of bytes received through PCIe RX (in KB)
# TYPE dcgm_pcie_rx_throughput counter    通过PCIe RX接收的总字节数
dcgm_pcie_rx_throughput{gpu="0",uuid="GPU-4d52e430-b8c7-a0b9-7fda-4aa825af5c97"} 3 


# HELP dcgm_pcie_tx_throughput Total number of bytes transmitted through PCIe TX (in KB) 
# TYPE dcgm_pcie_tx_throughput counter    通过PCIe RX发送的总字节数
dcgm_pcie_tx_throughput{gpu="0",uuid="GPU-4d52e430-b8c7-a0b9-7fda-4aa825af5c97"} 16  


# HELP dcgm_power_violation Throttling duration due to power constraints (in us).
# TYPE dcgm_power_violation counter   由于功率限制导致的节流持续时间
dcgm_power_violation{gpu="0",uuid="GPU-4d52e430-b8c7-a0b9-7fda-4aa825af5c97"} 0  


# HELP dcgm_sm_clock SM clock frequency (in MHz).
# TYPE dcgm_sm_clock gauge     SM时钟频率
dcgm_sm_clock{gpu="0",uuid="GPU-4d52e430-b8c7-a0b9-7fda-4aa825af5c97"} 135  


# HELP dcgm_sync_boost_violation Throttling duration due to sync-boost constraints (in us).    由于同步 - 增强约束导致的节流持续时间
# TYPE dcgm_sync_boost_violation counter
dcgm_sync_boost_violation{gpu="0",uuid="GPU-4d52e430-b8c7-a0b9-7fda-4aa825af5c97"} 0   


# HELP dcgm_thermal_violation Throttling duration due to thermal constraints (in us).    由于热约束的节流持续时间
# TYPE dcgm_thermal_violation counter
dcgm_thermal_violation{gpu="0",uuid="GPU-4d52e430-b8c7-a0b9-7fda-4aa825af5c97"} 0   


# HELP dcgm_xid_errors Value of the last XID error encountered.
# TYPE dcgm_xid_errors gauge    遇到的最后一个XID错误的值
dcgm_xid_errors{gpu="0",uuid="GPU-4d52e430-b8c7-a0b9-7fda-4aa825af5c97"} 0

四,监控POD gpu metrics

go 编写的服务

If you want to get per pod GPU metrics directly in Prometheus, deploy pod-gpu-metrics-exporter.
https://github.com/NVIDIA/gpu-monitoring-tools/tree/master/exporters/prometheus-dcgm/k8s/pod-gpu-metrics-exporter#pod-gpu-metrics-exporter

#Prerequisites
NVIDIA Tesla drivers = R384+ (download from NVIDIA Driver Downloads page)
nvidia-docker version > 2.0 (see how to install and it's prerequisites)
Set the default runtime to nvidia
Kubernetes version = 1.13
Set KubeletPodResources in /etc/default/kubelet: KUBELET_EXTRA_ARGS=--feature-gates=KubeletPodResources=true

####Deploy on Kubernetes cluster
# Deploy nvidia-k8s-device-plugin

# Deploy GPU Pods

# Create the monitoring namespace
$ kubectl create namespace monitoring

# Add gpu metrics endpoint to prometheus
$ kubectl create -f prometheus/prometheus-configmap.yaml

# Deploy prometheus
$ kubectl create -f prometheus/prometheus-deployment.yaml

$ kubectl create -f pod-gpu-metrics-exporter-daemonset.yaml

# Open in browser: localhost:9090
----------------------------------------------------------------
####Docker Build and Run
$ docker build -t pod-gpu-metrics-exporter .

# Make sure to run dcgm-exporter
$ docker run -d --runtime=nvidia --rm --name=nvidia-dcgm-exporter nvidia/dcgm-exporter

$ docker run -d --privileged --rm -p 9400:9400 -v /var/lib/kubelet/pod-resources:/var/lib/kubelet/pod-resources --volumes-from nvidia-dcgm-exporter:ro nvidia/pod-gpu-metrics-exporter:v1.0.0-alpha

# Check GPU metrics
$ curl -s localhost:9400/gpu/metrics

# Sample output

# HELP dcgm_gpu_temp GPU temperature (in C).
# TYPE dcgm_gpu_temp gauge
dcgm_gpu_temp{container_name="pod1-ctr",gpu="0",pod_name="pod1",pod_namespace="default",uuid="GPU-2b399198-c670-a848-173b-d3400051a200"} 33
dcgm_gpu_temp{container_name="pod1-ctr",gpu="1",pod_name="pod1",pod_namespace="default",uuid="GPU-9567a9e7-341e-bb7e-fcf5-788d8caa50f9"} 34
# HELP dcgm_gpu_utilization GPU utilization (in %).
# TYPE dcgm_gpu_utilization gauge
dcgm_gpu_utilization{container_name="pod1-ctr",gpu="0",pod_name="pod1",pod_namespace="default",uuid="GPU-2b399198-c670-a848-173b-d3400051a200"} 0
dcgm_gpu_utilization{container_name="pod1-ctr",gpu="1",pod_name="pod1",pod_namespace="default",uuid="GPU-9567a9e7-341e-bb7e-fcf5-788d8caa50f9"} 0
# HELP dcgm_low_util_violation Throttling duration due to low utilization (in us).
# TYPE dcgm_low_util_violation counter
dcgm_low_util_violation{container_name="pod1-ctr",gpu="0",pod_name="pod1",pod_namespace="default",uuid="GPU-2b399198-c670-a848-173b-d3400051a200"} 0
dcgm_low_util_violation{container_name="pod1-ctr",gpu="1",pod_name="pod1",pod_namespace="default",uuid="GPU-9567a9e7-341e-bb7e-fcf5-788d8caa50f9"} 0
# HELP dcgm_mem_copy_utilization Memory utilization (in %).
# TYPE dcgm_mem_copy_utilization gauge
dcgm_mem_copy_utilization{container_name="pod1-ctr",gpu="0",pod_name="pod1",pod_namespace="default",uuid="GPU-2b399198-c670-a848-173b-d3400051a200"} 0
dcgm_mem_copy_utilization{container_name="pod1-ctr",gpu="1",pod_name="pod1",pod_namespace="default",uuid="GPU-9567a9e7-341e-bb7e-fcf5-788d8caa50f9"} 0
# HELP dcgm_memory_clock Memory clock frequency (in MHz).
# TYPE dcgm_memory_clock gauge
dcgm_memory_clock{container_name="pod1-ctr",gpu="0",pod_name="pod1",pod_namespace="default",uuid="GPU-2b399198-c670-a848-173b-d3400051a200"} 810
dcgm_memory_clock{container_name="pod1-ctr",gpu="1",pod_name="pod1",pod_namespace="default",uuid="GPU-9567a9e7-341e-bb7e-fcf5-788d8caa50f9"} 810

五,基于阿里云容器服务监控 Kubernetes集群GPU指标

 

六,k8s+promethues

k8s 配置插件使用gpu
https://github.com/NVIDIA/k8s-device-plugin
调度 GPU
https://kubernetes.io/zh/docs/tasks/manage-gpus/scheduling-gpus/

在k8s 上监控gpu

1,创建prometheus server 端

用DaemonSet生成,在每一个节点生成prometheus-server  (访问每一个k8s node 都可以访问到prometheus)
配置文件使用ConfigMap生成

prometheus理论

一,监控项

https://www.gitbook.com/book/songjiayang/prometheus/details (Prometheus 实战) 
https://github.com/1046102779/prometheus (Prometheus 非官方中文手册)
http://www.bubuko.com/infodetail-2004088.html (基于prometheus监控k8s集群)
http://www.cnblogs.com/sfnz/p/6566951.html (安装prometheus+grafana监控mysql redis kubernetes等,非docker安装)
https://github.com/kayrus/prometheus-kubernetes (prometheus-kubernetes)
https://github.com/prometheus/node_exporter (prometheus/node_exporter)
http://dockone.io/article/2579 ( Prometheus在Kubernetes下的监控实践)
https://github.com/prometheus/prometheus/releases (prometheus 下载列表)
https://github.com/prometheus/node_exporter/releases/ (node_exporter下载列表)

前提概念:
1.时间序列是指将同一统计指标的数值按其发生的时间先后顺序排列而成的数列
2.     
=:选择正好相等的字符串标签
!=:选择不相等的字符串标签
=~:选择匹配正则表达式的标签(或子标签)
!~:选择不匹配正则表达式的标签(或子标签)
3.
s:seconds
m:minutes
h:hours
d:days
w:weeks
y:years
       注: [5m]指过去的5分钟内
4.操作符
bool
and
or
unless
on
without : without(label)在结果中移除括号内的标签和值
by : by(label)在结果中只保留括号内的标签和值

1.CPU空闲率
sum(irate(node_cpu{mode="idle", instance="134node"}[1m])) * 100 / count_scalar(node_cpu{mode="user", instance="134node"})

注释:
## instance:指的是label,具体根据实际配置,也可用正则匹配
## mode :      指cpu模式,node-exporter已经抓取出来,可以在node-exporter部署ip:9100这个网址上查看例如:http://172.17.123.134:9100/metrics
## sum()函数: 指将括号内的指标值求和
## irate()函数: 指计算范围向量中时间序列的每秒钟的瞬时(per-second)速度(calculates theper-second instant rate of increase of the time series in the range vector)
## count_scalar()函数 : 指将时间序列向量中的元素个数作为标量返回(returns the number ofelements in a time series vector as a scalar)
2.CPU负载率
node_load1{instance="134node"} / count by(job, instance)(count by(job, instance, cpu)(node_cpu{instance="134node"}))
注释:
## node_load1 : 指1分钟内cpu平均负载,同样cpu_load5指5分钟内cpu平均负载,cpu_load15指15 分钟内cpu平均负载
## count : 指聚合向量中的每个元素(即计数)
## 待添加后续注解
3.可用内存
node_memory_MemAvailable{instance="88node"}
注释:
## node_memory_MemAvailable :Memory information field MemAvailable, node-exporter已经抓取出来,只需查询展示即可;
    注意:该指标针对不同的系统是采集不同的,CentOS6.X 上就采集不到这个指标;CentOS7上可以;
4.空闲文件系统空间
sum(node_filesystem_free{fstype="xfs",instance="88node"})   
sum(node_filesystem_free{fstype="ext4",instance="134node"})
## node_filesystem_free: Filesystem free space in bytes
## fstype 有如下种类:
## aufs :  指联合文件系统,用来把原本分离的两个文件系统联合在一起
## cgroup : Cgroups(控制组)是Linux内核的一个功能,用来限制、统计和分离一个进程组的资源(CPU、内存、磁盘输入输出等)。
## tmpfs : tmpfs是一种虚拟内存文件系统,而不是块设备。
## overlay : 一个 overlay 文件系统包含两个文件系统,一个 upper 文件系统和一个 lower 文件系统,是一种新型的联合文件系统 

### proc、xfs、mqueue等等。
5.swap硬盘交换区:从硬盘到内存或从内存到硬盘,虚拟内存交换
Swap free :
node_memory_SwapFree{instance="134node"}
## node_memory_SwapTotal: Memory information field SwapTotal.
## swap :类似于可以把硬盘当内存用,那么这一部分内存一般就叫做swap
Swap Usage :
node_memory_SwapTotal{instance="134node"} - node_memory_SwapFree{instance="134node"}
## node_memory_SwapFree: Memory information field SwapFree
Swap I/O(in):
rate(node_vmstat_pswpin{instance="88node"}[1m]) * 4096 or irate(node_vmstat_pswpin{instance="88node"}[5m]) * 4096
Swap I/O(out):
rate(node_vmstat_pswpout{instance="88node"}[1m]) * 4096 or irate(node_vmstat_pswpout{instance="88node"}[5m]) * 4096
## vmstat :vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况。
## pswpin/s:每秒从硬盘交换区传送进入内存的次数。
## pswpout/s:每秒从内存传送到硬盘交换区的次数。
## pswpin/s、 pswpout/s描述的是与硬盘交换区相关的交换活动。交换关系到系统的效率。交换区在硬盘上对硬盘的读,写操作比内存读,写慢得多,因此,为了提高系统效率就应该设法减少交换。  
通常的作法就是加大内存,使交换区中进行的交换活动为零,或接近为零。如果swpot/s的值大于 1,预示可能需要增加内存或减少缓冲区(减少缓冲区能够释放一部分自由内存空间)。
Swap free 率(百分百)
(node_memory_SwapFree{instance=~"$server"}  /node_memory_SwapTotal{instance=~"$server"}) * 100
6.CPU使用率
avg without (cpu) (irate(node_cpu{instance="88node", mode!="idle"}[5m]))
## avg : 平均值
7.网路使用情况
上传速率:   irate(node_network_transmit_bytes{device!="lo",instance="88node"}[1m])
下载速率:   irate(node_network_receive_bytes{device!="lo",instance="88node"}[1m])
## eth0: ethernet的简写,一般用于以太网接口。
## wifi0:wifi是无线局域网,因此wifi0一般指无线网络接口。
## ath0: Atheros的简写,一般指Atheros芯片所包含的无线网络接口。
## tunl0:tunl0是隧道接口,封装数据的时候使用
## lo: local的简写,一般指本地环回接口。
8.内存使用率
已用内存:(总内存-空闲内存-缓存=已使用内存)
      node_memory_MemTotal{instance="88node"} -  
      node_memory_MemFree{instance="88node"} - 
      node_memory_Cached{instance="88node"} - 
      node_memory_Buffers{instance="88node"} - 
      node_memory_Slab{instance="88node"}
Buffer缓存:
     node_memory_Buffers{instance="88node"}
Cached缓存:
     node_memory_Cached{instance="88node"}  
     + node_memory_Slab{instance="88node"}
Free空闲内存:
     node_memory_MemFree{instance="88node"}
可用内存占比:
     (node_memory_MemAvailable{instance="88node"} / 
     node_memory_MemTotal{instance="88node"}) * 100
## total:总计物理内存的大小。
## Free:空闲内存有多少。
## Shared:多个进程共享的内存总额。
## Buffers:表示buffers cache的内存数量,一般对块设备的读写才需要缓冲
## Cached:表示page cached的内存数量,一般作文件系统的cached,频繁访问的文件都会被cached。如果cached值较大,就说明cached文件数较多。如果此时IO中的bi比较小,就说明文件系统效率比较好
## Slab:slab分配器不仅可以提供动态内存的管理功能,而且可以作为经常分配并释放的内存的缓存
## MemAvailable: Free + Buffers + Cached - 不可回收的部分。不可回收部分包括:共享内存段 tmpfs,ramfs等
9.磁盘读写(IOPs)
磁盘每秒读取(5分钟内)
sum by (instance) (irate(node_disk_reads_completed{instance="88node"}[5m]))
##node_disk_reads_completed: The total number of reads completed successfully
磁盘每秒写入(5分钟内)
sum by (instance)(irate(node_disk_writes_completed{instance="88node"}[5m]))
##node_disk_writes_completed :The total number of writes completed successfully.
使用I/O的毫秒数(5分钟内)
sum by (instance) (irate(node_disk_io_time_ms{instance="88node"}[5m]))
##node_disk_io_time_ms: Total Milliseconds spent doing I/Os
磁盘每秒读写总数(5分钟内)
sum by (instance) (irate(node_disk_reads_completed{instance="88node"}[5m])) + sum by (instance) (irate(node_disk_writes_completed{instance="88node"}[5m]))
10.I/O Usage
磁盘读取总数(1分钟内)
sum(irate(node_disk_bytes_read{instance="88node"}[1m]))
##node_disk_bytes_read : The total number of bytes read successfully(成功读取的字节数)
磁盘写入总数(1分钟内)
sum(irate(node_disk_bytes_written{instance="88node"}[1m]))
##node_disk_bytes_written :The total number of bytes written successfully(成功写入的字节数)
使用I/O的毫秒数(1分钟内)
sum(irate(node_disk_io_time_ms{instance="88node"}[1m]))
##node_disk_io_time_ms :Total Milliseconds spent doing I/Os.(使用IO的总毫秒数)
11.文件系统空闲空间
最低值:
min(node_filesystem_free{fstype=~"xfs|ext4",instance="88node"} / node_filesystem_size{fstype=~"xfs|ext4",instance="88node"})
最高值:
max(node_filesystem_free{fstype=~"xfs|ext4",instance="88node"} / node_filesystem_size{fstype=~"xfs|ext4",instance="88node"})
## ext4是第四代扩展文件系统(英语:Fourth EXtended filesystem,缩写为ext4)是linlli
linux下的日志文件系统,ext4的文件系统容量达到1EB,而文件容量则达到16TB
## XFS是一个64位文件系统,最大支持8EB减1字节的单个文件系统,实际部署时取决于宿主操作系统的最大块限制。对于一个32位linux系统,文件和文件系统的大小会被限制在16TB。
 

二,基本概念

#数据模型
Prometheus 存储的是时序数据, 即按照相同时序(相同的名字和标签),以时间维度存储连续的数据的集合。

时序索引

时序(time series) 是由名字(Metric),以及一组 key/value 标签定义的,具有相同的名字以及标签属于相同时序。
时序的名字由 ASCII 字符,数字,下划线,以及冒号组成,它必须满足正则表达式 [a-zA-Z_:][a-zA-Z0-9_:]*, 其名字应该具有语义化,一般表示一个可以度量的指标,例如: http_requests_total, 可以表示 http 请求的总数。
时序的标签可以使 Prometheus 的数据更加丰富,能够区分具体不同的实例,例如 http_requests_total{method="POST"} 可以表示所有 http 中的 POST 请求。
标签名称由 ASCII 字符,数字,以及下划线组成, 其中 __ 开头属于 Prometheus 保留,标签的值可以是任何 Unicode 字符,支持中文

时序样本

按照某个时序以时间维度采集的数据,称之为样本,其值包含:
一个 float64 值
一个毫秒级的 unix 时间戳

格式
Prometheus 时序格式与 OpenTSDB 相似:
<metric name>{<label name>=<label value>, ...}
其中包含时序名字以及时序的标签。


#时序 4 种类型
Prometheus 时序数据分为 Counter, Gauge, Histogram, Summary 四种类型
Counter
Counter 表示收集的数据是按照某个趋势(增加/减少)一直变化的,我们往往用它记录服务请求总量、错误总数等。

例如 Prometheus server 中 http_requests_total, 表示 Prometheus 处理的 http 请求总数,我们可以使用 delta, 很容易得到任意区间数据的增量,这个会在 PromQL 一节中细讲。

Gauge
Gauge 表示搜集的数据是一个瞬时的值,与时间没有关系,可以任意变高变低,往往可以用来记录内存使用率、磁盘使用率等。

例如 Prometheus server 中 go_goroutines, 表示 Prometheus 当前 goroutines 的数量。

Histogram
Histogram 由 <basename>_bucket{le="<upper inclusive bound>"},<basename>_bucket{le="+Inf"}, <basename>_sum,<basename>_count 组成,主要用于表示一段时间范围内对数据进行采样(通常是请求持续时间或响应大小),并能够对其指定区间以及总数进行统计,通常它采集的数据展示为直方图。

例如 Prometheus server 中 prometheus_local_storage_series_chunks_persisted, 表示 Prometheus 中每个时序需要存储的 chunks 数量,我们可以用它计算待持久化的数据的分位数。

Summary
Summ
ary 和 Histogram 类似,由 <basename>{quantile="<φ>"},<basename>_sum,<basename>_count 组成,主要用于表示一段时间内数据采样结果(通常是请求持续时间或响应大小),它直接存储了 quantile 数据,而不是根据统计区间计算出来的。

例如 Prometheus server 中 prometheus_target_interval_length_seconds。

Histogram vs Summary
都包含 <basename>_sum,<basename>_count
Histogram 需要通过 <basename>_bucket 计算 quantile, 而 Summary 直接存储了 quantile 的值。

#作业与实例
Prometheus 中,将任意一个独立的数据源(target)称之为实例(instance)。包含相同类型的实例的集合称之为作业(job)。 如下是一个含有四个重复实例的作业:
- job: api-server
    - instance 1: 1.2.3.4:5670
    - instance 2: 1.2.3.4:5671
    - instance 3: 5.6.7.8:5670
    - instance 4: 5.6.7.8:5671
    
  自生成标签和时序  
  Prometheus 在采集数据的同时,会自动在时序的基础上添加标签,作为数据源(target)的标识,以便区分
  job: The configured job name that the target belongs to.
instance: The <host>:<port> part of the target's URL that was scraped.

如果其中任一标签已经在此前采集的数据中存在,那么将会根据 honor_labels 设置选项来决定新标签。详见官网解释: scrape configuration documentation

对每一个实例而言,Prometheus 按照以下时序来存储所采集的数据样本:

up{job="<job-name>", instance="<instance-id>"}: 1 表示该实例正常工作
up{job="<job-name>", instance="<instance-id>"}: 0 表示该实例故障

scrape_duration_seconds{job="<job-name>", instance="<instance-id>"} 表示拉取数据的时间间隔

scrape_samples_post_metric_relabeling{job="<job-name>", instance="<instance-id>"} 表示采用重定义标签(relabeling)操作后仍然剩余的样本数

scrape_samples_scraped{job="<job-name>", instance="<instance-id>"}  表示从该数据源获取的样本数

其中 up 时序可以有效应用于监控该实例是否正常工作。

PromQL 基本使用
https://songjiayang.gitbooks.io/prometheus/content/promql/summary.html

PromQL 查询结果主要有 3 种类型:
瞬时数据 (Instant vector): 包含一组时序,每个时序只有一个点,例如:http_requests_total
区间数据 (Range vector): 包含一组时序,每个时序有多个点,例如:http_requests_total[5m]
纯量数据 (Scalar): 纯量只有一个数字,没有时序,例如:count(http_requests_total)



数据可视化

Prometheus 自带的 Web 界面比较简单,因为它的目的是为了及时查询数据,方便 PromeQL 调试
它并不是像常见的 Admin Dashboard,在一个页面尽可能展示多的数据,如果你有这方面的需求,不妨试试 Grafana。

Grafana 是一套开源的分析监视平台,支持 Graphite, InfluxDB, OpenTSDB, Prometheus, Elasticsearch, CloudWatch 等数据源,其 UI 非常漂亮且高度定制化



配置文件

Prometheus 启动的时候,可以加载运行参数 -config.file 指定配置文件,默认为 prometheus.yml。
在配置文件中我们可以指定 global, alerting, rule_files, scrape_configs, remote_write, remote_read 等属性
#全局配置
global 属于全局的默认配置,它主要包含 4 个属性,
scrape_interval: 拉取 targets 的默认时间间隔。
scrape_timeout: 拉取一个 target 的超时时间。
evaluation_interval: 执行 rules 的时间间隔。
external_labels: 额外的属性,会添加到拉取的数据并存到数据库中

global:
  scrape_interval:     15s # By default, scrape targets every 15 seconds.
  evaluation_interval: 15s # By default, scrape targets every 15 seconds.
  scrape_timeout: 10s # is set to the global default (10s).

  # Attach these labels to any time series or alerts when communicating with
  # external systems (federation, remote storage, Alertmanager).
  external_labels:
    monitor: 'codelab-monitor'
    
#告警配置    
通常我们可以使用运行参数 -alertmanager.xxx 来配置 Alertmanager, 但是这样不够灵活,没有办法做到动态更新加载,以及动态定义告警属性。
所以 alerting 配置主要用来解决这个问题,它能够更好的管理 Alertmanager, 主要包含 2 个参数:
alert_relabel_configs: 动态修改 alert 属性的规则配置。
alertmanagers: 用于动态发现 Alertmanager 的配置
#规则配置
rule_files 主要用于配置 rules 文件,它支持多个文件以及文件目录
rule_files:
  - "rules/node.rules"
  - "rules2/*.rules"
#数据拉取配置
scrape_configs 主要用于配置拉取数据节点,每一个拉取配置主要包含以下参数:
job_name:任务名称
honor_labels: 用于解决拉取数据标签有冲突,当设置为 true, 以拉取数据为准,否则以服务配置为准
params:数据拉取访问时带的请求参数
scrape_interval: 拉取时间间隔
scrape_timeout: 拉取超时时间
metrics_path: 拉取节点的 metric 路径
scheme: 拉取数据访问协议
sample_limit: 存储的数据标签个数限制,如果超过限制,该数据将被忽略,不入存储;默认值为0,表示没有限制
relabel_configs: 拉取数据重置标签配置
metric_relabel_configs:metric 重置标签配置

ServiceDiscoveryConfig 主要用于 target 发现,大体分为两类,静态配置和动态发现。
#远程可写存储
remote_write 主要用于可写远程存储配置,主要包含以下参数:
url: 访问地址
remote_timeout: 请求超时时间
write_relabel_configs: 标签重置配置, 拉取到的数据,经过重置处理后,发送给远程存储
#远程可读存储
remote_read 主要用于可读远程存储配置,主要包含以下参数:
url: 访问地址
remote_timeout: 请求超时时间
#服务发现
在 Prometheus 的配置中,一个最重要的概念就是数据源 target,而数据源的配置主要分为静态配置和动态发现, 大致为以下几类:
static_configs: 静态服务发现
dns_sd_configs: DNS 服务发现
file_sd_configs: 文件服务发现
consul_sd_configs: Consul 服务发现
serverset_sd_configs: Serverset 服务发现
nerve_sd_configs: Nerve 服务发现
marathon_sd_configs: Marathon 服务发现
kubernetes_sd_configs: Kubernetes 服务发现
gce_sd_configs: GCE 服务发现
ec2_sd_configs: EC2 服务发现
openstack_sd_configs: OpenStack 服务发现
azure_sd_configs: Azure 服务发现
triton_sd_configs: Triton 服务发现
它们具体使用以及配置模板,请参考服务发现配置模板。
它们中最重要的,也是使用最广泛的应该是 static_configs, 其实那些动态类型都可以看成是某些通用业务使用静态服务封装的结果。

##配置样例
global:
  scrape_interval:     15s # By default, scrape targets every 15 seconds.
  evaluation_interval: 15s # By default, scrape targets every 15 seconds.

rule_files:
  - "rules/node.rules"

scrape_configs:
  - job_name: 'prometheus'
    scrape_interval: 5s
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node'
    scrape_interval: 8s
    static_configs:
      - targets: ['127.0.0.1:9100', '127.0.0.12:9100']

  - job_name: 'mysqld'
    static_configs:
      - targets: ['127.0.0.1:9104']
  - job_name: 'memcached'
    static_configs:
      - targets: ['127.0.0.1:9150']

export

Exporter
在 Prometheus 中负责数据汇报的程序统一叫做 Exporter, 而不同的 Exporter 负责不同的业务。 它们具有统一命名格式,即 xx_exporter, 例如负责主机信息收集的 node_exporter。
#文本格式
Exporter 本质上就是将收集的数据,转化为对应的文本格式,并提供 http 请求。
Exporter 收集的数据转化的文本内容以行 (
) 为单位,空行将被忽略, 文本内容最后一行为空行。
#注释
文本内容,如果以 # 开头通常表示注释。
以 # HELP 开头表示 metric 帮助说明。
以 # TYPE 开头表示定义 metric 类型,包含 counter, gauge, histogram, summary, 和 untyped 类型。
其他表示一般注释,供阅读使用,将被 Prometheus 忽略
#采样数据
内容如果不以 # 开头,表示采样数据。它通常紧挨着类型定义行,满足以下格式:

metric_name [
  "{" label_name "=" `"` label_value `"` { "," label_name "=" `"` label_value `"` } [ "," ] "}"
] value [ timestamp ]

需要特别注意的是,假设采样数据 metric 叫做 x, 如果 x 是 histogram 或 summary 类型必需满足以下条件:
采样数据的总和应表示为 x_sum。
采样数据的总量应表示为 x_count。
summary 类型的采样数据的 quantile 应表示为 x{quantile="y"}。
histogram 类型的采样分区统计数据将表示为 x_bucket{le="y"}。
histogram 类型的采样必须包含 x_bucket{le="+Inf"}, 它的值等于 x_count 的值。
summary 和 historam 中 quantile 和 le 必需按从小到大顺序排列。

Node Exporter

默认开启的功能

名称 说明 系统
arp /proc/net/arp 中收集 ARP 统计信息 Linux
conntrack /proc/sys/net/netfilter/ 中收集 conntrack 统计信息 Linux
cpu 收集 cpu 统计信息 Darwin, Dragonfly, FreeBSD, Linux
diskstats /proc/diskstats 中收集磁盘 I/O 统计信息 Linux
edac 错误检测与纠正统计信息 Linux
entropy 可用内核熵信息 Linux
exec execution 统计信息 Dragonfly, FreeBSD
filefd /proc/sys/fs/file-nr 中收集文件描述符统计信息 Linux
filesystem 文件系统统计信息,例如磁盘已使用空间 Darwin, Dragonfly, FreeBSD, Linux, OpenBSD
hwmon /sys/class/hwmon/ 中收集监控器或传感器数据信息 Linux
infiniband 从 InfiniBand 配置中收集网络统计信息 Linux
loadavg 收集系统负载信息 Darwin, Dragonfly, FreeBSD, Linux, NetBSD, OpenBSD, Solaris
mdadm /proc/mdstat 中获取设备统计信息 Linux
meminfo 内存统计信息 Darwin, Dragonfly, FreeBSD, Linux
netdev 网口流量统计信息,单位 bytes Darwin, Dragonfly, FreeBSD, Linux, OpenBSD
netstat /proc/net/netstat 收集网络统计数据,等同于 netstat -s Linux
sockstat /proc/net/sockstat 中收集 socket 统计信息 Linux
stat /proc/stat 中收集各种统计信息,包含系统启动时间,forks, 中断等 Linux
textfile 通过 --collector.textfile.directory 参数指定本地文本收集路径,收集文本信息 any
time 系统当前时间 any
uname 通过 uname 系统调用, 获取系统信息 any
vmstat /proc/vmstat 中收集统计信息 Linux
wifi 收集 wifi 设备相关统计数据 Linux
xfs 收集 xfs 运行时统计信息 Linux (kernel 4.4+)
zfs 收集 zfs 性能统计信息 Linux

默认关闭的功能

名称 说明 系统
bonding 收集系统配置以及激活的绑定网卡数量 Linux
buddyinfo /proc/buddyinfo 中收集内存碎片统计信息 Linux
devstat 收集设备统计信息 Dragonfly, FreeBSD
drbd 收集远程镜像块设备(DRBD)统计信息 Linux
interrupts 收集更具体的中断统计信息 Linux,OpenBSD
ipvs /proc/net/ip_vs 中收集 IPVS 状态信息,从 /proc/net/ip_vs_stats 获取统计信息 Linux
ksmd /sys/kernel/mm/ksm 中获取内核和系统统计信息 Linux
logind logind 中收集会话统计信息 Linux
meminfo_numa /proc/meminfo_numa 中收集内存统计信息 Linux
mountstats /proc/self/mountstat 中收集文件系统统计信息,包括 NFS 客户端统计信息 Linux
nfs /proc/net/rpc/nfs 中收集 NFS 统计信息,等同于 nfsstat -c Linux
qdisc 收集队列推定统计信息 Linux
runit 收集 runit 状态信息 any
supervisord 收集 supervisord 状态信息 any
systemd systemd 中收集设备系统状态信息 Linux
tcpstat /proc/net/tcp/proc/net/tcp6 收集 TCP 连接状态信息 Linux

docker 安装

docker run -d -p 9100:9100 
  -v "/proc:/host/proc:ro" 
  -v "/sys:/host/sys:ro" 
  -v "/:/rootfs:ro" 
  --net="host" 
  quay.io/prometheus/node-exporter 
    -collector.procfs /host/proc 
    -collector.sysfs /host/sys 
    -collector.filesystem.ignored-mount-points "^/(sys|proc|dev|host|etc)($|/)"
    
     docker run -d -p 9100:9100 --net="host" prom/node-exporter
 容器如何监控外部的资源 ????
 

k8s部署

根据

https://github.com/NVIDIA/gpu-monitoring-tools/blob/master/exporters/prometheus-dcgm/k8s/node-exporter/gpu-only-node-exporter-daemonset.yaml

一,部署promethues server

可以通过ConfigMap配置prometheus的配置文件,生成的配置文件由prometheus使用,后期有新节点可以修改配置文件重新应用生效

apiVersion: v1
kind: ConfigMap
metadata:
  creationTimestamp: null
  name: prometheus-config
  namespace: monitoring
data:
  prometheus.yaml: |
    global:
      scrape_interval: 15s
    scrape_configs:
    - job_name: prometheus
      scrape_interval: 5s
      static_configs:
      - targets:
        - localhost:9090
    - job_name: gpu_metrics
      scrape_interval: 1s
      metrics_path: /gpu/metrics
      scheme: http
      static_configs:
      - targets:
        - localhost:9400
-------------------------------------------
可以添加新的job_name  或   在某一个job下添加targets 

二,

节点daemonset

# Node exporter collecting only GPU metrics from dcgm-exporter.
# Except textfile collector, all other collectors that are enabled by default are disabled.
# Refer: https://github.com/prometheus/node_exporter/tree/release-0.16
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: dcgm-exporter
spec:
  template:
    metadata:
      labels:
        app: dcgm-exporter
      name: dcgm-exporter
    spec:
      nodeSelector:
        hardware-type: NVIDIAGPU
      containers:
      - image: quay.io/prometheus/node-exporter:v0.16.0
        name: node-exporter
        args:
        - "--web.listen-address=0.0.0.0:9101"
        - "--path.procfs=/host/proc"
        - "--path.sysfs=/host/sys"
        - "--collector.textfile.directory=/run/prometheus"
        - "--no-collector.arp"
        - "--no-collector.bcache"
        - "--no-collector.bonding"
        - "--no-collector.conntrack"
        - "--no-collector.cpu"
        - "--no-collector.diskstats"
        - "--no-collector.edac"
        - "--no-collector.entropy"
        - "--no-collector.filefd"
        - "--no-collector.filesystem"
        - "--no-collector.hwmon"
        - "--no-collector.infiniband"
        - "--no-collector.ipvs"
        - "--no-collector.loadavg"
        - "--no-collector.mdadm"
        - "--no-collector.meminfo"
        - "--no-collector.netdev"
        - "--no-collector.netstat"
        - "--no-collector.nfs"
        - "--no-collector.nfsd"
        - "--no-collector.sockstat"
        - "--no-collector.stat"
        - "--no-collector.time"
        - "--no-collector.timex"
        - "--no-collector.uname"
        - "--no-collector.vmstat"
        - "--no-collector.wifi"
        - "--no-collector.xfs"
        - "--no-collector.zfs"
        ports:
        - name: metrics
          containerPort: 9101
          hostPort: 9101
        resources:
          requests:
            memory: 30Mi
            cpu: 100m
          limits:
            memory: 50Mi
            cpu: 200m
        volumeMounts:
        - name: proc
          readOnly:  true
          mountPath: /host/proc
        - name: sys
          readOnly: true
          mountPath: /host/sys
        - name: collector-textfiles
          readOnly: true
          mountPath: /run/prometheus
      - image: nvidia/dcgm-exporter:1.4.6
        name: nvidia-dcgm-exporter
        securityContext:
          runAsNonRoot: false
          runAsUser: 0
        volumeMounts:
        - name: collector-textfiles
          mountPath: /run/prometheus

      hostNetwork: true
      hostPID: true

      volumes:
      - name: proc
        hostPath:
          path: /proc
      - name: sys
        hostPath:
          path: /sys
      - name: collector-textfiles
        emptyDir:
          medium: Memory
          
暴露的指标可访问
Pod 滚动更新一:修改 CI 流程
这种办法异常简单,只需要我们写一个简单的 CI 脚本:给 ConfigMap 算一个 Hash 值,然后作为一个环境变量或 Annotation 加入到 Deployment 的 Pod 模板当中。

举个例子,我们写这样的一个 Deployment yaml 然后在 CI 脚本中,计算 Hash 值替换进去:

...
spec:
  template:
    metadata:
      annotations:
        com.aylei.configmap/hash: ${CONFIGMAP_HASH}
...
这时,假如 ConfigMap 变化了,那 Deployment 中的 Pod 模板自然也会发生变化,k8s 自己就会帮助我们做滚动更新了。另外,如何 ConfigMap 不大,直接把 ConfigMap 转化为 JSON 放到 Pod 模板中都可以,这样做还有一个额外的好处,那就是在排查故障时,我们一眼就能看到这个 Pod 现在关联的 ConfigMap 内容是什么。

或者
----------------------------------------------------------------------------
当前最佳方案是使用 Deployment 编排 Pods,并将 ConfigMap 视为只读资源。当我们需要更新 ConfigMap 时,我们重新创建一个新的 ConfigMap,并将我们的 Deployment 配置指向新的 ConfigMap,然后滚动更新。如果我们新的配置是有问题,则需要执行 Deployment 回滚操作。虽然不能直接编辑 ConfigMap 那么快,但更安全。

新增 ConfigMap 编辑 Deployment 使用最新配置,并执行更新操作

kubectl apply -f prometheus.deploy.yml


# HELP dcgm_dec_utilization Decoder utilization (in %).
# TYPE dcgm_dec_utilization gauge
dcgm_dec_utilization{gpu="0",uuid="GPU-a53b4ec8-50eb-abc9-ce5a-4fdf12db1187"} 0
# HELP dcgm_ecc_dbe_volatile_total Total number of double-bit volatile ECC errors.
# TYPE dcgm_ecc_dbe_volatile_total counter
dcgm_ecc_dbe_volatile_total{gpu="0",uuid="GPU-a53b4ec8-50eb-abc9-ce5a-4fdf12db1187"} 0
# HELP dcgm_ecc_sbe_volatile_total Total number of single-bit volatile ECC errors.
# TYPE dcgm_ecc_sbe_volatile_total counter
dcgm_ecc_sbe_volatile_total{gpu="0",uuid="GPU-a53b4ec8-50eb-abc9-ce5a-4fdf12db1187"} 0
# HELP dcgm_enc_utilization Encoder utilization (in %).
# TYPE dcgm_enc_utilization gauge
dcgm_enc_utilization{gpu="0",uuid="GPU-a53b4ec8-50eb-abc9-ce5a-4fdf12db1187"} 0
# HELP dcgm_fb_free Framebuffer memory free (in MiB).
# TYPE dcgm_fb_free gauge
dcgm_fb_free{gpu="0",uuid="GPU-a53b4ec8-50eb-abc9-ce5a-4fdf12db1187"} 3825
# HELP dcgm_fb_used Framebuffer memory used (in MiB).
# TYPE dcgm_fb_used gauge
dcgm_fb_used{gpu="0",uuid="GPU-a53b4ec8-50eb-abc9-ce5a-4fdf12db1187"} 219
# HELP dcgm_gpu_temp GPU temperature (in C).
# TYPE dcgm_gpu_temp gauge
dcgm_gpu_temp{gpu="0",uuid="GPU-a53b4ec8-50eb-abc9-ce5a-4fdf12db1187"} 39
# HELP dcgm_gpu_utilization GPU utilization (in %).
# TYPE dcgm_gpu_utilization gauge
dcgm_gpu_utilization{gpu="0",uuid="GPU-a53b4ec8-50eb-abc9-ce5a-4fdf12db1187"} 4
# HELP dcgm_mem_copy_utilization Memory utilization (in %).
# TYPE dcgm_mem_copy_utilization gauge
dcgm_mem_copy_utilization{gpu="0",uuid="GPU-a53b4ec8-50eb-abc9-ce5a-4fdf12db1187"} 2
# HELP dcgm_memory_clock Memory clock frequency (in MHz).
# TYPE dcgm_memory_clock gauge
dcgm_memory_clock{gpu="0",uuid="GPU-a53b4ec8-50eb-abc9-ce5a-4fdf12db1187"} 405
# HELP dcgm_pcie_replay_counter Total number of PCIe retries.
# TYPE dcgm_pcie_replay_counter counter
dcgm_pcie_replay_counter{gpu="0",uuid="GPU-a53b4ec8-50eb-abc9-ce5a-4fdf12db1187"} 0
# HELP dcgm_pcie_rx_throughput Total number of bytes received through PCIe RX (in KB)
# TYPE dcgm_pcie_rx_throughput counter
dcgm_pcie_rx_throughput{gpu="0",uuid="GPU-a53b4ec8-50eb-abc9-ce5a-4fdf12db1187"} 1
# HELP dcgm_pcie_tx_throughput Total number of bytes transmitted through PCIe TX (in KB)
# TYPE dcgm_pcie_tx_throughput counter
dcgm_pcie_tx_throughput{gpu="0",uuid="GPU-a53b4ec8-50eb-abc9-ce5a-4fdf12db1187"} 13
# HELP dcgm_power_violation Throttling duration due to power constraints (in us).
# TYPE dcgm_power_violation counter
dcgm_power_violation{gpu="0",uuid="GPU-a53b4ec8-50eb-abc9-ce5a-4fdf12db1187"} 0
# HELP dcgm_sm_clock SM clock frequency (in MHz).
# TYPE dcgm_sm_clock gauge
dcgm_sm_clock{gpu="0",uuid="GPU-a53b4ec8-50eb-abc9-ce5a-4fdf12db1187"} 135
# HELP dcgm_sync_boost_violation Throttling duration due to sync-boost constraints (in us).
# TYPE dcgm_sync_boost_violation counter
dcgm_sync_boost_violation{gpu="0",uuid="GPU-a53b4ec8-50eb-abc9-ce5a-4fdf12db1187"} 0
# HELP dcgm_thermal_violation Throttling duration due to thermal constraints (in us).
# TYPE dcgm_thermal_violation counter
dcgm_thermal_violation{gpu="0",uuid="GPU-a53b4ec8-50eb-abc9-ce5a-4fdf12db1187"} 0
# HELP dcgm_xid_errors Value of the last XID error encountered.
# TYPE dcgm_xid_errors gauge
dcgm_xid_errors{gpu="0",uuid="GPU-a53b4ec8-50eb-abc9-ce5a-4fdf12db1187"} 0
原文地址:https://www.cnblogs.com/g2thend/p/11515560.html