本文目录导读:

我来详细介绍如何配置容器监控分析的Shell脚本。
基础容器监控脚本
#!/bin/bash
# 容器监控分析脚本
# 功能:监控Docker容器资源使用、健康状态和性能分析
# 配置参数
LOG_DIR="/var/log/container-monitor"
INTERVAL=60 # 采集间隔(秒)
ALERT_CPU=80 # CPU告警阈值(%)
ALERT_MEM=90 # 内存告警阈值(%)
ALERT_DISK=85 # 磁盘告警阈值(%)
# 创建日志目录
mkdir -p "$LOG_DIR"
# 时间戳函数
timestamp() {
date "+%Y-%m-%d %H:%M:%S"
}
# 获取容器列表
get_containers() {
docker ps --format "{{.ID}}:{{.Names}}:{{.Image}}:{{.Status}}"
}
# 监控容器CPU使用率
monitor_cpu() {
local container_id=$1
local container_name=$2
# 使用docker stats获取CPU使用率
local cpu_usage=$(docker stats --no-stream --format "{{.CPUPerc}}" "$container_id" | sed 's/%//')
echo "$cpu_usage"
}
# 监控容器内存使用
monitor_memory() {
local container_id=$1
local container_name=$2
# 获取内存使用率
local mem_stats=$(docker stats --no-stream --format "{{.MemPerc}}" "$container_id" | sed 's/%//')
local mem_usage=$(docker stats --no-stream --format "{{.MemUsage}}" "$container_id")
local mem_limit=$(docker stats --no-stream --format "{{.MemUsage}}" "$container_id")
echo "$mem_stats|$mem_usage"
}
# 监控容器网络IO
monitor_network() {
local container_id=$1
local container_name=$2
# 获取网络IO
local network_io=$(docker stats --no-stream --format "{{.NetIO}}" "$container_id")
echo "$network_io"
}
# 监控容器磁盘IO
monitor_disk() {
local container_id=$1
local container_name=$2
# 获取块IO
local block_io=$(docker stats --no-stream --format "{{.BlockIO}}" "$container_id")
echo "$block_io"
}
# 容器健康检查
health_check() {
local container_id=$1
local container_name=$2
# 检查容器运行状态
local status=$(docker inspect --format '{{.State.Status}}' "$container_id")
# 检查健康检查状态(如果有配置)
local health=""
if docker inspect --format '{{.State.Health.Status}}' "$container_id" 2>/dev/null; then
health=$(docker inspect --format '{{.State.Health.Status}}' "$container_id")
else
health="not_configured"
fi
# 检查重启次数
local restart_count=$(docker inspect --format '{{.RestartCount}}' "$container_id")
echo "$status|$health|$restart_count"
}
高级监控分析脚本
#!/bin/bash
# 高级容器分析功能
# 日志分析函数
analyze_container_logs() {
local container_name=$1
local lines=${2:-100}
echo "=== 容器日志分析: $container_name ==="
# 获取最近N行日志
recent_logs=$(docker logs --tail "$lines" "$container_name" 2>&1)
# 统计错误级别
errors=$(echo "$recent_logs" | grep -ci "error\|exception\|fail")
warnings=$(echo "$recent_logs" | grep -ci "warn\|warning")
info=$(echo "$recent_logs" | grep -ci "info\|debug")
echo "Error count: $errors"
echo "Warning count: $warnings"
echo "Info count: $info"
# 提取错误模式
if [ $errors -gt 0 ]; then
echo "=== 最近错误 ==="
echo "$recent_logs" | grep -i "error\|exception\|fail" | tail -10
fi
}
# 资源趋势分析
analyze_resource_trends() {
local container_name=$1
local duration=${2:-3600} # 默认1小时
echo "=== 资源趋势分析: $container_name ==="
# 创建时间序列数据
local data_file="$LOG_DIR/${container_name}_trend_$(date +%Y%m%d).csv"
# 采集数据点
for ((i=0; i<duration; i+=60)); do
local cpu=$(docker stats --no-stream --format "{{.CPUPerc}}" "$container_name" | sed 's/%//')
local mem=$(docker stats --no-stream --format "{{.MemPerc}}" "$container_name" | sed 's/%//')
echo "$(timestamp),$cpu,$mem" >> "$data_file"
sleep 60
done &
echo "数据采集正在后台运行,文件: $data_file"
}
# 容器间通信分析
analyze_network_connections() {
local container_name=$1
echo "=== 网络连接分析: $container_name ==="
# 获取容器IP
local container_ip=$(docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$container_name")
# 检查网络连接
local connections=$(docker exec "$container_name" ss -tunp 2>/dev/null || docker exec "$container_name" netstat -tunp 2>/dev/null)
echo "Container IP: $container_ip"
echo "Active Connections:"
echo "$connections" | grep -v "Local Address" | head -20
# 检查监听端口
echo "Listening Ports:"
docker port "$container_name" 2>/dev/null
}
# 依赖分析
analyze_dependencies() {
local container_name=$1
echo "=== 依赖分析: $container_name ==="
# 获取容器卷挂载
echo "Volume Mounts:"
docker inspect --format '{{range .Mounts}}{{.Source}} -> {{.Destination}}{{"\n"}}{{end}}' "$container_name"
# 获取网络连接
echo "Network Links:"
docker inspect --format '{{range $net,$v := .NetworkSettings.Networks}}{{$.Name}} -> {{$net}}{{"\n"}}{{end}}' "$container_name"
# 获取环境变量依赖
echo "Environment Dependencies:"
docker inspect --format '{{range .Config.Env}}{{.}}{{"\n"}}{{end}}' "$container_name" | grep -i "host\|url\|endpoint\|connection" | head -10
}
告警与报告生成
#!/bin/bash
# 告警和报告功能
# 告警检查函数
check_alerts() {
local container_name=$1
local cpu_usage=$2
local mem_usage=$3
local alerts=""
# CPU告警
if (( $(echo "$cpu_usage > $ALERT_CPU" | bc -l) )); then
alerts+="CPU使用率过高: ${cpu_usage}% (阈值: ${ALERT_CPU}%) "
fi
# 内存告警
if (( $(echo "$mem_usage > $ALERT_MEM" | bc -l) )); then
alerts+="内存使用率过高: ${mem_usage}% (阈值: ${ALERT_MEM}%) "
fi
if [ -n "$alerts" ]; then
send_alert "$container_name" "$alerts"
fi
}
# 发送告警
send_alert() {
local container=$1
local message=$2
echo "[$(timestamp)] ALERT: $container - $message" >> "$LOG_DIR/alerts.log"
# 可配置的告警方式
# 1. 系统日志
logger "Container Monitor Alert: $container - $message"
# 2. 邮件告警(如果需要)
# echo "$message" | mail -s "Container Alert: $container" admin@example.com
# 3. Webhook(如果需要)
# curl -X POST -H "Content-Type: application/json" \
# -d "{\"container\":\"$container\",\"message\":\"$message\"}" \
# http://your-webhook-url
}
# 生成报告
generate_report() {
local container_name=$1
local report_file="$LOG_DIR/report_${container_name}_$(date +%Y%m%d_%H%M%S).html"
cat > "$report_file" << HTML
<!DOCTYPE html>
<html>
<head>容器监控报告 - $container_name</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.header { background: #4CAF50; color: white; padding: 20px; }
.metric { margin: 20px 0; padding: 10px; border: 1px solid #ddd; }
.warning { background-color: #fff3cd; }
.error { background-color: #f8d7da; }
table { width: 100%; border-collapse: collapse; }
th, td { padding: 8px; text-align: left; border-bottom: 1px solid #ddd; }
</style>
</head>
<body>
<div class="header">
<h1>容器监控报告</h1>
<p>容器: $container_name</p>
<p>时间: $(date)</p>
</div>
<div class="metric">
<h2>当前状态</h2>
<table>
<tr><th>指标</th><th>值</th><th>状态</th></tr>
HTML
# 获取当前状态
local cpu=$(docker stats --no-stream --format "{{.CPUPerc}}" "$container_name")
local mem=$(docker stats --no-stream --format "{{.MemPerc}}" "$container_name")
local status=$(docker inspect --format '{{.State.Status}}' "$container_name")
# 添加到报告
cat >> "$report_file" << HTML
<tr><td>CPU使用率</td><td>$cpu</td><td>$(echo "$cpu > 80" | bc -l) > 0 ? "⚠️" : "✓"</td></tr>
<tr><td>内存使用率</td><td>$mem</td><td>$(echo "$mem > 90" | bc -l) > 0 ? "⚠️" : "✓"</td></tr>
<tr><td>运行状态</td><td>$status</td><td>✓</td></tr>
</table>
</div>
<div class="metric">
<h2>性能历史</h2>
<p>最近30分钟的资源使用趋势</p>
<!-- 这里可以集成图表库 -->
</div>
</body>
</html>
HTML
echo "报告已生成: $report_file"
}
主监控循环
#!/bin/bash
# 主监控循环
main() {
echo "启动容器监控系统..."
echo "日志目录: $LOG_DIR"
echo "采集间隔: ${INTERVAL}秒"
echo "告警阈值 - CPU: ${ALERT_CPU}%, 内存: ${ALERT_MEM}%"
# 初始化日志文件
local log_file="$LOG_DIR/monitor_$(date +%Y%m%d).log"
echo "时间,容器名称,CPU(%),内存(%),网络IO,磁盘IO,状态,健康检查" > "$log_file"
while true; do
local containers=$(get_containers)
while IFS= read -r container; do
if [ -z "$container" ]; then
continue
fi
# 解析容器信息
local container_id=$(echo "$container" | cut -d: -f1)
local container_name=$(echo "$container" | cut -d: -f2)
local container_image=$(echo "$container" | cut -d: -f3)
local container_status=$(echo "$container" | cut -d: -f4)
# 采集指标
local cpu=$(monitor_cpu "$container_id" "$container_name")
local mem_data=$(monitor_memory "$container_id" "$container_name")
local mem_percent=$(echo "$mem_data" | cut -d| -f1)
local net_io=$(monitor_network "$container_id" "$container_name")
local disk_io=$(monitor_disk "$container_id" "$container_name")
local health=$(health_check "$container_id" "$container_name")
# 记录到日志
echo "$(timestamp),$container_name,$cpu,$mem_percent,$net_io,$disk_io,$container_status,$health" >> "$log_file"
# 检查告警
check_alerts "$container_name" "$cpu" "$mem_percent"
# 显示实时状态
printf "%-20s CPU: %5s%% 内存: %5s%% 状态: %-10s\n" \
"$container_name" "$cpu" "$mem_percent" "$container_status"
done <<< "$containers"
sleep "$INTERVAL"
done
}
# 启动监控
main
使用说明
安装配置
#!/bin/bash
# 安装脚本
install_monitor() {
# 1. 创建监控目录
mkdir -p /usr/local/bin/container-monitor
# 2. 复制脚本
chmod +x monitor.sh
cp monitor.sh /usr/local/bin/container-monitor/
# 3. 创建systemd服务
cat > /etc/systemd/system/container-monitor.service << SERVICE
[Unit]
Description=Container Monitor Service
After=docker.service
Requires=docker.service
[Service]
Type=simple
ExecStart=/usr/local/bin/container-monitor/monitor.sh
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
SERVICE
# 4. 创建日志轮转配置
cat > /etc/logrotate.d/container-monitor << LOGROTATE
/var/log/container-monitor/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 0644 root root
}
LOGROTATE
# 5. 启用服务
systemctl daemon-reload
systemctl enable container-monitor
systemctl start container-monitor
echo "安装完成!"
}
配置参数说明
| 参数 | 说明 | 默认值 |
|---|---|---|
| LOG_DIR | 日志存储目录 | /var/log/container-monitor |
| INTERVAL | 采集间隔(秒) | 60 |
| ALERT_CPU | CPU告警阈值(%) | 80 |
| ALERT_MEM | 内存告警阈值(%) | 90 |
| ALERT_DISK | 磁盘告警阈值(%) | 85 |
这个脚本系统提供了完整的容器监控、分析和告警功能,可根据实际需求进行调整和扩展。