当前位置: 首页 > news >正文

k8s容器内资源监控统计脚本

可直接复制以下命令到容器内shell中执行:

cat << "EOF" > /tmp/mem-monitor.sh
#!/bin/bash
DURATION=${1:-60}
INTERVAL=${2:-5}
# 自动检测容器 CPU 核心数
if [ -f /sys/fs/cgroup/cpu/cpu.cfs_quota_us ] && [ -f /sys/fs/cgroup/cpu/cpu.cfs_period_us ]; thenQUOTA=$(cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us)PERIOD=$(cat /sys/fs/cgroup/cpu/cpu.cfs_period_us)if [ "$QUOTA" -gt 0 ]; thenCPU_CORES=$(awk "BEGIN {printf \"%.0f\", $QUOTA/$PERIOD}")elseCPU_CORES=$(nproc 2>/dev/null || echo 1)fi
elseCPU_CORES=$(nproc 2>/dev/null || echo 1)
fi
# 获取容器 CPU 使用时间(纳秒)
get_cpu_usage() {if [ -f /sys/fs/cgroup/cpuacct/cpuacct.usage ]; thencat /sys/fs/cgroup/cpuacct/cpuacct.usageelif [ -f /sys/fs/cgroup/cpu/cpuacct.usage ]; thencat /sys/fs/cgroup/cpu/cpuacct.usageelseecho "0"fi
}
echo "=========================================="
echo "      进程内存 & CPU 监控脚本"
echo "=========================================="
echo "监控时长: ${DURATION}秒 | 采集间隔: ${INTERVAL}秒"
echo "容器 CPU: ${CPU_CORES} 核 (100% = 用满配额)"
echo "开始时间: $(date +"%Y-%m-%d %H:%M:%S")"
echo "=========================================="
echo ""
echo ">>> 请在监控期间触发你的操作 <<<"
echo ""
TMP_FILE="/tmp/mem_monitor_$$.csv"
echo "timestamp,pid,rss_kb,cpu_raw,cmd" > "$TMP_FILE"
if [ -f /sys/fs/cgroup/memory/memory.usage_in_bytes ]; thencontainer_usage=$(cat /sys/fs/cgroup/memory/memory.usage_in_bytes)echo "容器内存基线: $((container_usage/1024/1024))MB"
fi
# 初始化 CPU 基线
PREV_CPU_USAGE=$(get_cpu_usage)
PREV_TIME=$(date +%s%N)
to_mb() {awk "BEGIN {printf \"%.1f\", $1/1024}"
}
# 计算容器总 CPU 占用率
calc_container_cpu() {local current_usage=$1local current_time=$2local usage_diff=$((current_usage - PREV_CPU_USAGE))local time_diff=$((current_time - PREV_TIME))if [ $time_diff -gt 0 ]; then# CPU% = (usage_diff / time_diff) / CPU_CORES * 100awk "BEGIN {printf \"%.1f\", ($usage_diff / $time_diff) / $CPU_CORES * 100}"elseecho "0.0"fi
}
show_snapshot() {local timestamp=$1local label=$2# 计算容器总 CPUlocal current_cpu_usage=$(get_cpu_usage)local current_time=$(date +%s%N)local container_cpu=$(calc_container_cpu $current_cpu_usage $current_time)# 更新基线PREV_CPU_USAGE=$current_cpu_usagePREV_TIME=$current_timeecho "[$timestamp] $label"echo "--------------------------------------------------------------------"if [ -f /sys/fs/cgroup/memory/memory.usage_in_bytes ]; thenlocal usage=$(cat /sys/fs/cgroup/memory/memory.usage_in_bytes)echo "  容器内存: $((usage/1024/1024))MB | 容器总CPU: ${container_cpu}%"elseecho "  容器总CPU: ${container_cpu}%"fiprintf "  %-8s  %10s  %12s  %s\n" "PID" "RSS(MB)" "CPU(实际%)" "命令"printf "  %-8s  %10s  %12s  %s\n" "---" "-------" "----------" "----"ps -eo pid,rss,%cpu,args --sort=-%cpu | grep -iE "java|node" | grep -v "grep" | head -20 | while IFS= read -r line; dopid=$(echo "$line" | awk "{print \$1}")rss=$(echo "$line" | awk "{print \$2}")cpu_raw=$(echo "$line" | awk "{print \$3}")cmd=$(echo "$line" | awk "{for(i=4;i<=NF;i++) printf \"%s \", \$i}" | cut -c1-55)[ "$rss" = "0" ] && continuecpu_real=$(awk "BEGIN {printf \"%.1f\", $cpu_raw/$CPU_CORES}")cpu_mark=""awk "BEGIN {exit ($cpu_real > 80) ? 0 : 1}" && cpu_mark="🔴"awk "BEGIN {exit ($cpu_real > 50 && $cpu_real <= 80) ? 0 : 1}" && cpu_mark="🟡"printf "  %-8s  %10s  %10s%%  %s %s\n" "$pid" "$(to_mb $rss)" "$cpu_real" "$cpu_mark" "$cmd"csv_cmd=$(echo "$cmd" | tr "," ";")echo "$timestamp,$pid,$rss,$cpu_raw,$csv_cmd" >> "$TMP_FILE"doneecho ""
}
START_TIME=$(date +%s)
ITERATION=0
show_snapshot "$(date +"%H:%M:%S")" "开始"
while true; doCURRENT_TIME=$(date +%s)ELAPSED=$((CURRENT_TIME - START_TIME))[ $ELAPSED -ge $DURATION ] && breaksleep $INTERVALITERATION=$((ITERATION + 1))show_snapshot "$(date +"%H:%M:%S")" "第 ${ITERATION} 次采集 (${ELAPSED}s)"
done
echo "=========================================="
echo "              变化分析"
echo "=========================================="
echo ""
declare -A first_rss last_rss max_rss cpu_sum cpu_count
while IFS=, read -r timestamp pid rss cpu_raw cmd; do[ "$pid" = "pid" ] && continue[ -z "${first_rss[$pid]}" ] && first_rss[$pid]=$rsslast_rss[$pid]=$rss[ -z "${max_rss[$pid]}" ] || [ $rss -gt ${max_rss[$pid]} ] && max_rss[$pid]=$rsscpu_sum[$pid]=$(awk "BEGIN {print ${cpu_sum[$pid]:-0} + $cpu_raw}")cpu_count[$pid]=$(( ${cpu_count[$pid]:-0} + 1 ))
done < "$TMP_FILE"
printf "%-8s  %10s  %10s  %10s  %12s  %s\n" "PID" "开始(MB)" "结束(MB)" "最大(MB)" "平均CPU(实际%)" "内存变化"
printf "%-8s  %10s  %10s  %10s  %12s  %s\n" "---" "--------" "--------" "--------" "------------" "--------"
for key in "${!first_rss[@]}"; dostart=${first_rss[$key]}end=${last_rss[$key]}max=${max_rss[$key]}change=$((end - start))avg_cpu_raw=$(awk "BEGIN {printf \"%.1f\", ${cpu_sum[$key]} / ${cpu_count[$key]}}")avg_cpu_real=$(awk "BEGIN {printf \"%.1f\", $avg_cpu_raw / $CPU_CORES}")if [ $change -gt 10240 ]; then marker="🔴 +$(to_mb $change)"elif [ $change -gt 5120 ]; then marker="🟡 +$(to_mb $change)"elif [ $change -lt -5120 ]; then marker="🟢 $(to_mb $change)"else marker="⚪ $(to_mb $change)"fiprintf "%-8s  %10s  %10s  %10s  %12s  %sMB\n" "$key" "$(to_mb $start)" "$(to_mb $end)" "$(to_mb $max)" "${avg_cpu_real}%" "$marker"
done
echo ""
if [ -f /sys/fs/cgroup/memory/memory.usage_in_bytes ]; thencontainer_end=$(cat /sys/fs/cgroup/memory/memory.usage_in_bytes)echo "容器内存变化: $(( (container_end - container_usage) / 1024 / 1024 ))MB"
fi
echo ""
echo "========== 结论 =========="
max_increase=0 max_mem_pid=""
max_cpu=0 max_cpu_pid=""
for key in "${!first_rss[@]}"; doincrease=$((last_rss[$key] - first_rss[$key]))[ $increase -gt $max_increase ] && { max_increase=$increase; max_mem_pid=$key; }avg_raw=$(awk "BEGIN {print ${cpu_sum[$key]} / ${cpu_count[$key]}}")avg_real=$(awk "BEGIN {print $avg_raw / $CPU_CORES}")awk "BEGIN {exit ($avg_real > $max_cpu) ? 0 : 1}" && { max_cpu=$avg_real; max_cpu_pid=$key; }
done
echo "📊 内存增长最多: PID $max_mem_pid (+$(to_mb $max_increase)MB)"
echo "📊 CPU 占用最高: PID $max_cpu_pid (${max_cpu}% 容器配额)"
if [ $max_increase -gt 10240 ]; thenecho ""echo "🔴 PID $max_mem_pid 内存增长较大,可能存在泄漏"
fi
awk "BEGIN {exit ($max_cpu > 80) ? 0 : 1}" && {echo "🔴 PID $max_cpu_pid CPU 占用超过 80%,检查是否有死循环或密集计算"
}
awk "BEGIN {exit ($max_cpu > 100) ? 0 : 1}" && {echo "🔴🔴 PID $max_cpu_pid CPU 已超配额,会被 K8s 限流!"
}
echo "=========================================="
echo "监控完成: $(date +"%Y-%m-%d %H:%M:%S")"
echo "=========================================="
EOF
chmod +x /tmp/mem-monitor.sh && /tmp/mem-monitor.sh 60 5
http://www.zskr.cn/news/1511925.html

相关文章:

  • Remmina文件互传的‘奇葩’解法:为什么开启音频重定向才能看到共享文件夹?
  • Deepin Boot Maker:三步制作启动盘的终极解决方案
  • 哲学视角:witr如何重塑系统进程因果认知范式
  • WinForms DataGridView实用功能代码集:Excel/Word导出、树形日期、图片嵌入等120+可运行示例
  • PvZ Toolkit深度解析:植物大战僵尸内存修改的终极技术指南
  • 计算机毕业设计之青少年心理健康测评分析与预警的设计与实现
  • 掌握CANN ClipByValue算子:从数据安全到性能优化的完整指南
  • Pixi3D与PixiJS无缝集成:如何将2D游戏升级为3D体验
  • 深入解析NXP 56F8322混合信号处理器:电机控制与数字电源应用实战
  • 分布式系统架构:幂等设计与消息去重的可靠性保障
  • FreeKill开源桌游引擎:构建自定义卡牌游戏的完整指南
  • 腾讯会议语音转写工具推荐
  • 沈阳名表回收 2026 年 6 月,三十年老店,专业鉴定,拒绝恶意压价 - 讯息早知道
  • 从Taq酶到引物设计:手把手教你优化PCR反应体系,避开假阴/阳性那些坑
  • 终极SP 500数据指南:30年历史成分股完整数据库
  • 基于NXP S12ZVM的汽车电机控制:从集成MCU到FOC算法实战
  • 2026:哈尔滨松北区除甲醛公司怎么选?专业机构测评与安心居推荐 - 专注室内空气检测治理
  • 贵州GEO网络推广外包公司哪家好?5家服务商外包能力与适配场景深度对标 - 企业名录优选推荐
  • 安卓虚拟摄像头完全指南:用自定义视频替换真实摄像头
  • 掌握VMware虚拟化:从零开始配置专业级开发环境
  • 别再只懂BFD双向检测了!单臂回声(Echo)在老旧设备组网中的救命用法
  • 2026年3大主流GEO优化服务深度测评:技术架构、服务模式、成本及适配场景对比 - 资讯纵览
  • Python 高手编程系列八十二:我做测试
  • 为什么你的朋友圈回忆需要备份?3个关键原因与解决方案
  • Sub-1 GHz无线MCU KW01深度解析:从架构设计到超低功耗物联网节点实战
  • 如何通过本地化工具提升英雄联盟游戏效率:League Akari 完整指南
  • MPC5567微控制器:汽车电子与工业控制中的实时确定性架构解析
  • 题解:AtCoder AT_awc0089_c A Walk to Cherry Blossom Viewing
  • 2026年新发布安徽保研院校全景透视:机遇、挑战与理性择校指南 - 2026年企业资讯
  • TradingView Charting Library跨框架集成实战:5分钟快速部署专业金融图表