shell-基于k8s/docker管理容器、监控模型训练所消耗的最大CPU与最大内存脚本
文章目录
- 前言
- shell-基于k8s/docker管理容器、监控模型训练所消耗的最大CPU与最大内存脚本
- 1. 基于docker管理容器、监控模型训练所消耗的最大CPU与最大内存
- 1.1. 使用
- 1.2. 源码
- 2. 基于k8s管理容器、监控模型训练所消耗的最大CPU与最大内存
前言
如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。
而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!!
shell-基于k8s/docker管理容器、监控模型训练所消耗的最大CPU与最大内存脚本
对于k8s管理容器来说,它与Docker管理容器对于 资源隔离机制 与 宿主机内核共享机制是不同的。
1. 基于docker管理容器、监控模型训练所消耗的最大CPU与最大内存
对于docker 容器启动时的状况 如果没有设置内存限制(如 --memory 或 --cpus),那么容器中的 free、top、htop、cat /proc/meminfo 等命令看到的,其实是宿主机的整体资源,而不是容器自己的资源。
设置限制内存的docker启动示例:
docker run -d --name jupyter \--memory=4g \--cpus=2 \-p 8888:8888 jupyter/base-notebook
1.1. 使用
启动:
./tool.sh start 1
然后查看进程启动是否成功:
ps -ef | grep tool

脚本:tool.sh
start:第一个参数,代表启动;
1:第二个参数,代表每1秒查询一次;
执行ps -ef | grep tool后可以看到出现两个进程,21732为守护进程,作用是管理启动、停止、守护工作进程、当工作进程宕机时主动拉取。
执行./tool.sh start 1后可以看到,生成两个文件,一个是tool.pid文件,存储的是父进程的pid,一个是resource_monitor.log 文件,存储的是我们监听后持久到本地的指标。
效果:

可以看到运行期间最高占用与最高内存使用是变化的。
停止:
./tool.sh stop

1.2. 源码
代码逻辑:
第一步停止守护进程;
第二步停止工作进程;
第三步备份指标历史记录;
第四步删除tool.pid存储守护进程id文件;
脚本源码:
tool.sh:
#! /bin/shcd `dirname $0` || exit 1readonly FILE_NAME='tool'
BIN_ROOT=`pwd`
index=${2}help(){echo "${0} <start|stop>"exit 1
}run(){interval=$1while true; docd $BIN_ROOTnohup sh tool_moudel.sh resource_monitor.log $interval </dev/null >/dev/null 2>&1sleep 60 done}
start(){if [ $# -eq 1 ]; thenrun ${1} &echo $! > $FILE_NAME'.pid'elseecho '缺失参数'fi
}stop(){pid_file=${FILE_NAME}'.pid'if [ -f "$pid_file" ]; thenpid=$(cat $pid_file)rm $pid_fileecho "kill -9 $pid"kill -9 $pidecho "守护进程已停止"elseecho "无法找到守护进程的PID文件"fichild_pid=$(ps -ef | grep "sh tool_moudel.sh" | grep -v grep | awk '{print $2}')echo "子进程id:$child_pid"if [ -z "$child_pid" ]; thenecho "子进程已停止"exit 1fiecho "kill -9 $child_pid"kill -9 $child_pidif [ -f "resource_monitor.log" ]; thenmv resource_monitor.log "resource_monitor.log.$(date +%Y%m%d%H%M%S)"echo "日志已备份"fisleep 5child_pid=$(ps -ef | grep "sh tool_moudel.sh" | grep -v grep | awk '{print $2}')if [ -z "$child_pid" ]; thenecho "子进程已停止"fi}case "${1}" in
start)start ${2};;
stop)stop;;
*)help;;
esacexit 1
tool_moudel.sh:
#!/bin/shcd "$(dirname "$0")" || exit 1
BIN_ROOT=$(pwd)check() {if [ $# -lt 2 ]; thenecho "Usage: $0 <file_name> <interval>"exit 1fi
}readonly FILE=$BIN_ROOT"/"$1
readonly interval=$2init() {# 获取 CPU 总核数(逻辑核)CPU_TOTAL=$(nproc)# 当前 CPU 使用核数(user + system 时间百分比换算)CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk -v total="$CPU_TOTAL" '{print ($2 + $4) * total / 100}')# 当前内存使用量(MB)MEM_USED=$(free -m | awk '/Mem/ {print $3}')# 当前总内存(MB)MEM_TOTAL=$(free -m | awk '/Mem/ {print $2}')# 如果文件不存在,初始化文件if [ ! -f "$FILE" ]; thenecho "运行期间最高占用${CPU_USAGE}核,最高内存使用${MEM_USED}MB,当前容器:${CPU_TOTAL}核,容器运行总内存:${MEM_TOTAL}MB" > "$FILE"returnfi# 从文件中读取上次记录的最大 CPU 和内存LAST_LINE=$(cat "$FILE")LAST_CPU_USED=$(echo "$LAST_LINE" | grep -oP '最高占用\K[0-9.]+')LAST_MEM_USED=$(echo "$LAST_LINE" | grep -oP '最高内存使用\K[0-9.]+')# 比较并取最大值MAX_CPU_USED=$(echo "$CPU_USAGE $LAST_CPU_USED" | awk '{if($1>$2) print $1; else print $2}')MAX_MEM_USED=$(echo "$MEM_USED $LAST_MEM_USED" | awk '{if($1>$2) print $1; else print $2}')# 覆盖写入最新最大值echo "运行期间最高占用${MAX_CPU_USED}核,最高内存使用${MAX_MEM_USED}MB,当前容器:${CPU_TOTAL}核,容器运行总内存:${MEM_TOTAL}MB" > "$FILE"
}run() {while true; docd "$BIN_ROOT"initsleep "$interval"done
}check "$@"
run
2. 基于k8s管理容器、监控模型训练所消耗的最大CPU与最大内存
说明:k8s的基于yaml做容器资源限制的,这时候,使用top、free之类的命令查询的是宿主机的资源,而不是容器内部本身的资源,因此对于查询最大CPU和最大内存的逻辑需要调整,其余地方保持一致即可。
示例:
#!/bin/shcd "$(dirname "$0")" || exit 1
BIN_ROOT=$(pwd)check() {if [ $# -lt 2 ]; thenecho "Usage: $0 <file_name> <interval>"exit 1fi
}readonly FILE=$BIN_ROOT"/"$1
readonly interval=$2init() {# 获取 CPU 总核数(逻辑核)CPU_QUOTA=$(cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us)CPU_PERIOD=$(cat /sys/fs/cgroup/cpu/cpu.cfs_period_us)CPU_TOTAL=$(awk "BEGIN {print $CPU_QUOTA / $CPU_PERIOD}")# 当前 CPU 使用核数CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print ($2+$4)/100 * '"$CPU_TOTAL"'}')# 当前内存使用量(MB)MEM_USED=$(($(cat /sys/fs/cgroup/memory/memory.usage_in_bytes)/1024/1024))# 当前总内存(MB)MEM_TOTAL=$(($(cat /sys/fs/cgroup/memory/memory.limit_in_bytes) / 1024 / 1024))# 如果文件不存在,初始化文件if [ ! -f "$FILE" ]; thenecho "运行期间最高占用${CPU_USAGE}核,最高内存使用${MEM_USED}MB,当前容器:${CPU_TOTAL}核,容器运行总内存:${MEM_TOTAL}MB" > "$FILE"returnfi# 从文件中读取上次记录的最大 CPU 和内存LAST_LINE=$(cat "$FILE")LAST_CPU_USED=$(echo "$LAST_LINE" | grep -oP '最高占用\K[0-9.]+')LAST_MEM_USED=$(echo "$LAST_LINE" | grep -oP '最高内存使用\K[0-9.]+')# 比较并取最大值MAX_CPU_USED=$(echo "$CPU_USAGE $LAST_CPU_USED" | awk '{if($1>$2) print $1; else print $2}')MAX_MEM_USED=$(echo "$MEM_USED $LAST_MEM_USED" | awk '{if($1>$2) print $1; else print $2}')# 覆盖写入最新最大值echo "运行期间最高占用${MAX_CPU_USED}核,最高内存使用${MAX_MEM_USED}MB,当前容器:${CPU_TOTAL}核,容器运行总内存${MEM_TOTAL}MB" > "$FILE"
}run() {while true; docd "$BIN_ROOT"initsleep "$interval"done
}check "$@"
run
启动脚本无需变化。
