Shell脚本如何配置容器容量规划

wen 实用脚本 2

本文目录导读:

Shell脚本如何配置容器容量规划

  1. 基础资源监控脚本
  2. 容量预测分析脚本
  3. 自动扩缩容脚本
  4. 综合配置示例
  5. 使用建议

为容器容量规划编写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

使用建议

  1. 配置阈值:根据业务需求调整 THRESHOLD_CPUTHRESHOLD_MEM 等参数
  2. 数据持久化:考虑将指标数据存储到 InfluxDB 或 Prometheus
  3. 通知集成:添加 Slack、邮件通知功能
  4. 安全考虑:在生产环境使用时,添加错误处理和回滚机制
  5. 性能优化:对于大规模容器集群,考虑使用 cAdvisor 或 Prometheus 替代 docker stats

这种Shell脚本方案适合中小规模环境,对于更大规模的容器编排(Kubernetes),建议使用HPA/VPA等原生工具。

抱歉,评论功能暂时关闭!