shell-基于k8s/docker管理容器、监控模型训练所消耗的最大CPU与最大内存脚本

文章目录

前言

如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。

而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!!


shell-基于k8s/docker管理容器、监控模型训练所消耗的最大CPU与最大内存脚本

对于k8s管理容器来说,它与Docker管理容器对于 资源隔离机制 与 宿主机内核共享机制是不同的。

1. 基于docker管理容器、监控模型训练所消耗的最大CPU与最大内存

对于docker 容器启动时的状况 如果没有设置内存限制(如 --memory 或 --cpus),那么容器中的 free、top、htop、cat /proc/meminfo 等命令看到的,其实是宿主机的整体资源,而不是容器自己的资源。

设置限制内存的docker启动示例:

bash 复制代码
docker run -d --name jupyter \
  --memory=4g \
  --cpus=2 \
  -p 8888:8888 jupyter/base-notebook
1.1. 使用

启动:

bash 复制代码
./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 文件,存储的是我们监听后持久到本地的指标。

效果:

可以看到运行期间最高占用与最高内存使用是变化的。

停止:

bash 复制代码
./tool.sh stop
1.2. 源码

代码逻辑:

第一步停止守护进程;

第二步停止工作进程;

第三步备份指标历史记录;

第四步删除tool.pid存储守护进程id文件;

脚本源码:

tool.sh:

bash 复制代码
#! /bin/sh

cd `dirname $0` || exit 1

readonly FILE_NAME='tool'
BIN_ROOT=`pwd`
index=${2}

help(){
    echo "${0} <start|stop>"
    exit 1
}

run(){
    interval=$1
    while true; do
        cd $BIN_ROOT
        nohup sh tool_moudel.sh resource_monitor.log  $interval </dev/null >/dev/null 2>&1
        sleep 60                       
   done

}
start(){
  if [ $# -eq 1 ]; then
  
    run ${1} &
    echo $! > $FILE_NAME'.pid'
  else
    echo '缺失参数'
  fi
}


stop(){
  pid_file=${FILE_NAME}'.pid'
  if [ -f "$pid_file" ]; then
    pid=$(cat $pid_file)
    rm $pid_file
    echo "kill -9 $pid"
    kill -9 $pid
    echo "守护进程已停止"
  else
    echo "无法找到守护进程的PID文件"
  fi

  child_pid=$(ps -ef | grep "sh tool_moudel.sh" | grep -v grep | awk '{print $2}')

  echo "子进程id:$child_pid"
  if [ -z "$child_pid" ]; then
    echo "子进程已停止"
    exit 1
  fi

  echo "kill -9 $child_pid"
  kill -9 $child_pid
  if [ -f "resource_monitor.log" ]; then
    mv resource_monitor.log "resource_monitor.log.$(date +%Y%m%d%H%M%S)"
    echo "日志已备份"
  fi
  sleep 5
  child_pid=$(ps -ef | grep "sh tool_moudel.sh" | grep -v grep | awk '{print $2}')
  if [ -z "$child_pid" ]; then
    echo "子进程已停止"
  fi
  
}

case "${1}" in
start)
    start ${2}
    ;;
stop)
    stop
    ;;
*)
    help
    ;;
esac




exit 1

tool_moudel.sh:

bash 复制代码
#!/bin/sh

cd "$(dirname "$0")" || exit 1
BIN_ROOT=$(pwd)

check() {
  if [ $# -lt 2 ]; then
    echo "Usage: $0 <file_name> <interval>"
    exit 1
  fi
}

readonly FILE=$BIN_ROOT"/"$1
readonly interval=$2


init() {
    # 获取 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" ]; then
        echo "运行期间最高占用${CPU_USAGE}核,最高内存使用${MEM_USED}MB,当前容器:${CPU_TOTAL}核,容器运行总内存:${MEM_TOTAL}MB" > "$FILE"
        return
    fi
    # 从文件中读取上次记录的最大 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; do
        cd "$BIN_ROOT"
        init
        sleep "$interval"
   done
}

check "$@"
run
2. 基于k8s管理容器、监控模型训练所消耗的最大CPU与最大内存

说明:k8s的基于yaml做容器资源限制的,这时候,使用top、free之类的命令查询的是宿主机的资源,而不是容器内部本身的资源,因此对于查询最大CPU和最大内存的逻辑需要调整,其余地方保持一致即可。

示例:

bash 复制代码
#!/bin/sh

cd "$(dirname "$0")" || exit 1
BIN_ROOT=$(pwd)

check() {
  if [ $# -lt 2 ]; then
    echo "Usage: $0 <file_name> <interval>"
    exit 1
  fi
}

readonly FILE=$BIN_ROOT"/"$1
readonly interval=$2

init() {
    # 获取 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" ]; then
        echo "运行期间最高占用${CPU_USAGE}核,最高内存使用${MEM_USED}MB,当前容器:${CPU_TOTAL}核,容器运行总内存:${MEM_TOTAL}MB" > "$FILE"
        return
    fi

    # 从文件中读取上次记录的最大 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; do
        cd "$BIN_ROOT"
        init
        sleep "$interval"
   done
}

check "$@"
run

启动脚本无需变化。

相关推荐
海鸥812 小时前
在k8s中部署seaweedfs,上传文件到seaweedfs方法
云原生·容器·kubernetes
半梦半醒*2 小时前
k8s——pod详解2
linux·运维·docker·容器·kubernetes·负载均衡
AAA小肥杨2 小时前
K8s从Docker到Containerd的迁移全流程实践
docker·容器·kubernetes
DARLING Zero two♡2 小时前
云原生基石的试金石:基于 openEuler 部署 Docker 与 Nginx 的全景实录
nginx·docker·云原生
容器魔方4 小时前
KCD 杭州站 x OpenInfra Days China首次联手!华为云云原生团队与您共探Karmada多模板工作负载多集
云原生·容器·云计算
xx.ii5 小时前
k8s:pod-1
云原生·容器·kubernetes
期待のcode5 小时前
Docker容器
java·docker·容器
R-G-B8 小时前
【P7】docker镜像发布和部署
运维·docker·容器·docker镜像·docker镜像发布和部署·镜像发布和部署·docker镜像发布
大象席地抽烟11 小时前
K8S中部署MinIO集群提供块存储服务
kubernetes