本文目录导读:

为容器容量规划编写Shell脚本的核心目标是自动化收集、分析和预测资源使用情况,从而帮助做出扩缩容决策,以下是一个系统化的Shell脚本配置方案,涵盖从数据采集到决策建议的全流程。
基础资源监控脚本
创建一个基础脚本来收集容器层面的资源使用数据:
#!/bin/bash
# container_capacity_monitor.sh
# 配置参数
LOG_DIR="/var/log/container_capacity"
THRESHOLD_CPU=80 # CPU使用率阈值(%)
THRESHOLD_MEM=85 # 内存使用率阈值(%)
THRESHOLD_DISK=90 # 磁盘使用率阈值(%)
INTERVAL=60 # 采集间隔(秒)
# 创建日志目录
mkdir -p "$LOG_DIR"
# 收集当前容器资源信息
collect_metrics() {
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
local log_file="$LOG_DIR/container_metrics_$(date '+%Y%m%d').log"
echo "[$timestamp] ====== Container Resource Report ======" >> "$log_file"
# 使用docker stats收集所有容器数据
docker stats --no-stream --format \
"table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}" \
>> "$log_file" 2>/dev/null || {
echo "Error: Docker not available or no running containers" >> "$log_file"
return 1
}
# 额外的系统级信息
echo "System Memory: $(free -h | awk '/^Mem:/ {print $3"/"$2}')" >> "$log_file"
echo "Disk Usage: $(df -h /var/lib/docker | awk 'NR==2 {print $5}')" >> "$log_file"
echo "----------------------------------------" >> "$log_file"
}
# 检测资源瓶颈
check_bottlenecks() {
docker stats --no-stream --format \
"{{.Name}}\t{{.CPUPerc}}\t{{.MemPerc}}" | while IFS=$'\t' read -r name cpu mem; do
cpu_val=${cpu%\%}
mem_val=${mem%\%}
if (( $(echo "$cpu_val > $THRESHOLD_CPU" | bc -l) )); then
echo "ALERT: Container $name CPU usage $cpu% exceeds threshold $THRESHOLD_CPU%"
fi
if (( $(echo "$mem_val > $THRESHOLD_MEM" | bc -l) )); then
echo "ALERT: Container $name Memory usage $mem% exceeds threshold $THRESHOLD_MEM%"
fi
done
}
# 主循环
while true; do
collect_metrics
check_bottlenecks >> "$LOG_DIR/alerts.log"
sleep "$INTERVAL"
done
容量预测分析脚本
这个脚本基于历史数据预测未来资源需求:
#!/bin/bash
# capacity_forecast.sh
# 配置
HISTORY_DIR="/var/log/container_capacity"
FORECAST_DAYS=7 # 预测未来天数
SAMPLE_SIZE=1000 # 用于回归的样本数
# 计算线性回归预测
linear_regression_predict() {
local file=$1
local field=$2 # cpu, mem, disk
# 提取最近的数据点
tail -n "$SAMPLE_SIZE" "$file" | awk -v field="$field" '
BEGIN {
sum_x = 0
sum_y = 0
sum_xy = 0
sum_xx = 0
n = 0
}
{
if (field == "cpu") val = $2 + 0
else if (field == "mem") val = $3 + 0
else if (field == "disk") val = $4 + 0
sum_x += n
sum_y += val
sum_xy += n * val
sum_xx += n * n
n++
}
END {
slope = (n * sum_xy - sum_x * sum_y) / (n * sum_xx - sum_x * sum_x)
intercept = (sum_y - slope * sum_x) / n
# 预测未来7天
for (i = n; i <= n + 7; i++) {
printf "Day %d: %.2f\n", i - n + 1, slope * i + intercept
}
}'
}
# 生成容量规划报告
generate_capacity_report() {
local report_file="$HISTORY_DIR/capacity_report_$(date '+%Y%m%d').md"
cat > "$report_file" << 'HEADER'
# Container Capacity Planning Report
## Current Status
HEADER
echo "Generated: $(date)" >> "$report_file"
echo "" >> "$report_file"
# 每个容器的预测
for container in $(docker ps --format "{{.Names}}"); do
echo "### Container: $container" >> "$report_file"
# 获取当前资源限制
local cpu_limit=$(docker inspect "$container" --format '{{.HostConfig.CpuShares}}')
local mem_limit=$(docker inspect "$container" --format '{{.HostConfig.Memory}}')
echo "- CPU Limit: $cpu_limit shares" >> "$report_file"
echo "- Memory Limit: $mem_limit bytes" >> "$report_file"
# 预测CPU使用趋势
echo -e "\n**CPU Usage Forecast (7 days):**" >> "$report_file"
docker stats --no-stream --format "{{.CPUPerc}}" "$container" | \
while read cpu; do
echo "$(date +%s) $cpu" >> "/tmp/cpu_${container}.log"
done
echo '```' >> "$report_file"
linear_regression_predict "/tmp/cpu_${container}.log" "cpu" >> "$report_file"
echo '```' >> "$report_file"
# 建议的容量调整
local current_cpu=$(docker stats --no-stream --format "{{.CPUPerc}}" "$container" | sed 's/%//')
if (( $(echo "$current_cpu > 75.0" | bc -l) )); then
echo -e "\n**Recommendation:** Increase CPU by 20% (current usage $current_cpu%)" >> "$report_file"
fi
done
echo "Report generated: $report_file"
}
# 主执行
generate_capacity_report
自动扩缩容脚本
基于上述监控数据,实现自动调整容器资源:
#!/bin/bash
# auto_scaling.sh
# 配置
MIN_CPU=256 # 最小CPU份额
MAX_CPU=1024 # 最大CPU份额
MIN_MEM="128m" # 最小内存
MAX_MEM="2g" # 最大内存
SCALE_UP_THRESHOLD=80
SCALE_DOWN_THRESHOLD=30
# 调整容器资源
scale_container() {
local container=$1
local resource=$2 # cpu or memory
local action=$3 # up or down
case "$resource" in
cpu)
current=$(docker inspect "$container" --format '{{.HostConfig.CpuShares}}')
if [ "$action" = "up" ]; then
new=$((current * 125 / 100)) # 增加25%
[ "$new" -gt "$MAX_CPU" ] && new=$MAX_CPU
else
new=$((current * 75 / 100)) # 减少25%
[ "$new" -lt "$MIN_CPU" ] && new=$MIN_CPU
fi
docker update --cpu-shares "$new" "$container"
echo "Scaled CPU for $container: $current -> $new"
;;
memory)
current=$(docker inspect "$container" --format '{{.HostConfig.Memory}}')
if [ "$action" = "up" ]; then
# 增加200MB
new=$((current + 209715200))
[ "$new" -gt "$(echo $MAX_MEM | numfmt --from=iec)" ] && new=$(echo $MAX_MEM | numfmt --from=iec)
else
# 减少100MB
new=$((current - 104857600))
[ "$new" -lt "$(echo $MIN_MEM | numfmt --from=iec)" ] && new=$(echo $MIN_MEM | numfmt --from=iec)
fi
docker update --memory "$new" "$container"
echo "Scaled Memory for $container: $current -> $new"
;;
esac
}
# 基于监控数据自动扩缩容
auto_scale_decision() {
docker stats --no-stream --format "{{.Name}}\t{{.CPUPerc}}\t{{.MemPerc}}" | while IFS=$'\t' read -r name cpu mem; do
cpu_val=${cpu%\%}
mem_val=${mem%\%}
# CPU扩容
if (( $(echo "$cpu_val > $SCALE_UP_THRESHOLD" | bc -l) )); then
scale_container "$name" "cpu" "up"
# CPU缩容
elif (( $(echo "$cpu_val < $SCALE_DOWN_THRESHOLD" | bc -l) )); then
scale_container "$name" "cpu" "down"
fi
# 内存扩容
if (( $(echo "$mem_val > $SCALE_UP_THRESHOLD" | bc -l) )); then
scale_container "$name" "memory" "up"
elif (( $(echo "$mem_val < $SCALE_DOWN_THRESHOLD" | bc -l) )); then
scale_container "$name" "memory" "down"
fi
done
}
# 执行扩缩容检查
auto_scale_decision
综合配置示例
创建一个主控脚本整合所有功能:
#!/bin/bash
# capacity_planning_manager.sh
# 配置
CONFIG_DIR="/etc/container_capacity"
SCHEDULE_CRON="*/5 * * * *" # 每5分钟执行一次
# 加载配置
[ -f "$CONFIG_DIR/config.sh" ] && source "$CONFIG_DIR/config.sh"
# 设置定时任务
setup_cron() {
(crontab -l 2>/dev/null; echo "$SCHEDULE_CRON $(pwd)/capacity_planning_manager.sh run") | crontab -
echo "Cron job installed: $SCHEDULE_CRON"
}
# 运行完整的容量规划流程
run_capacity_planning() {
echo "=== Starting Capacity Planning at $(date) ==="
# 1. 收集当前数据
./container_capacity_monitor.sh &
MONITOR_PID=$!
sleep 10 # 等待数据收集
# 2. 分析瓶颈
./capacity_forecast.sh
# 3. 执行扩缩容
./auto_scaling.sh
# 4. 生成报告
./capacity_forecast.sh generate
kill $MONITOR_PID 2>/dev/null
echo "=== Capacity Planning Complete ==="
}
# 主入口
case "${1:-run}" in
setup)
setup_cron
;;
run)
run_capacity_planning
;;
report)
./capacity_forecast.sh generate
;;
*)
echo "Usage: $0 {setup|run|report}"
exit 1
;;
esac
使用建议
- 配置阈值:根据业务需求调整
THRESHOLD_CPU、THRESHOLD_MEM等参数 - 数据持久化:考虑将指标数据存储到 InfluxDB 或 Prometheus
- 通知集成:添加 Slack、邮件通知功能
- 安全考虑:在生产环境使用时,添加错误处理和回滚机制
- 性能优化:对于大规模容器集群,考虑使用 cAdvisor 或 Prometheus 替代 docker stats
这种Shell脚本方案适合中小规模环境,对于更大规模的容器编排(Kubernetes),建议使用HPA/VPA等原生工具。