zoukankan      html  css  js  c++  java
  • prometheus及gpu,k8s

    prometheus及gpu,k8s

    原文地址:https://www.cnblogs.com/g2thend/p/11515560.html

    ##一,物理节点安装配置(简单配置,未涉及报警及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
    
  • 相关阅读:
    MS SQL入门基础:sql 其它命令
    MS SQL入门基础:数据类型
    MS SQL入门基础:SQL数据库表的修改
    MS SQL入门基础:创建数据库表
    MS SQL入门基础:注释符、运算符与通配符
    MS SQL入门基础:删除数据库
    MS SQL入门基础:字符串函数
    MS SQL入门基础:SQL 流程控制命令
    MS SQL入门基础:关系数据库的范式
    MS SQL入门基础:创建索引
  • 原文地址:https://www.cnblogs.com/zealousness/p/13410936.html
Copyright © 2011-2022 走看看