本文目录导读:

我来为你提供几种实现容器资源超限告警的脚本方案。
基于 Docker 的简单监控脚本
#!/bin/bash
# docker_resource_monitor.sh
# 配置参数
CPU_THRESHOLD=80 # CPU使用率阈值(%)
MEM_THRESHOLD=80 # 内存使用率阈值(%)
DISK_THRESHOLD=80 # 磁盘使用率阈值(%)
INTERVAL=60 # 检测间隔(秒)
LOG_FILE="/var/log/docker_monitor.log"
WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL" # 可选
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}
# 发送告警 (可扩展为微信、钉钉等)
send_alert() {
local message="$1"
log "ALERT: $message"
# 发送到Slack (可选)
if [ ! -z "$WEBHOOK_URL" ]; then
curl -s -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"$message\"}" \
$WEBHOOK_URL > /dev/null 2>&1
fi
# 发送到系统日志
logger -t docker-monitor "ALERT: $message"
}
# 主监控逻辑
monitor_containers() {
while true; do
# 获取所有运行中的容器
containers=$(docker ps --format "{{.Names}}")
for container in $containers; do
# 获取容器资源使用情况
stats=$(docker stats --no-stream --format \
"{{.Name}},{{.CPUPerc}},{{.MemPerc}},{{.MemUsage}},{{.NetIO}},{{.BlockIO}}" \
$container 2>/dev/null)
if [ -z "$stats" ]; then
continue
fi
# 解析数据
IFS=',' read -r name cpu mem mem_usage net_io block_io <<< "$stats"
# 清理数据 (去除%符号)
cpu_value=${cpu%\%}
mem_value=${mem%\%}
# 检查CPU使用率
if (( $(echo "$cpu_value > $CPU_THRESHOLD" | bc -l) )); then
send_alert "Container '$name' CPU usage high: ${cpu} (threshold: ${CPU_THRESHOLD}%)"
fi
# 检查内存使用率
if (( $(echo "$mem_value > $MEM_THRESHOLD" | bc -l) )); then
send_alert "Container '$name' Memory usage high: ${mem} (threshold: ${MEM_THRESHOLD}%)"
fi
done
sleep $INTERVAL
done
}
# 启动监控
monitor_containers
可配置的告警脚本 (支持多种告警方式)
#!/bin/bash
# container_alarm_system.sh
# 配置文件
CONFIG_FILE="/etc/container_monitor/config.conf"
ALERT_SCRIPT="/usr/local/bin/send_alert.sh"
# 默认配置
DEFAULT_CPU_LIMIT=85
DEFAULT_MEM_LIMIT=85
DEFAULT_DISK_LIMIT=85
DEFAULT_INTERVAL=60
# 读取配置
load_config() {
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
else
CPU_LIMIT=$DEFAULT_CPU_LIMIT
MEM_LIMIT=$DEFAULT_MEM_LIMIT
DISK_LIMIT=$DEFAULT_DISK_LIMIT
INTERVAL=$DEFAULT_INTERVAL
fi
}
# 告警发送函数 (支持多种方式)
send_alert() {
local severity=$1
local message=$2
local timestamp=$(date +%s)
# 1. 写入日志
echo "$timestamp|$severity|$message" >> /var/log/container_alerts.log
# 2. 系统日志
logger -t "container-alarm" -p $([[ "$severity" == "CRITICAL" ]] && echo "user.crit" || echo "user.warning") "$message"
# 3. HTTP回调 (支持自定义webhook)
if [ ! -z "$ALARM_WEBHOOK" ]; then
curl -s -X POST -H "Content-Type: application/json" \
-d "{\"severity\":\"$severity\",\"message\":\"$message\",\"timestamp\":$timestamp}" \
"$ALARM_WEBHOOK" > /dev/null 2>&1 &
fi
# 4. 发送邮件 (如果配置了)
if [ ! -z "$ALARM_EMAIL" ]; then
echo "$message" | mail -s "[$severity] Container Resource Alert" "$ALARM_EMAIL" 2>/dev/null &
fi
}
# 检查单个容器
check_container() {
local container_id=$1
local container_name=$2
# 获取详细资源使用情况
local stats=$(docker stats $container_id --no-stream --format \
'{"cpu":"{{.CPUPerc}}","mem":"{{.MemPerc}}","memUsage":"{{.MemUsage}}","netIO":"{{.NetIO}}","blockIO":"{{.BlockIO}}"}' 2>/dev/null)
if [ -z "$stats" ]; then
return 1
fi
local cpu_percent=$(echo "$stats" | jq -r '.cpu' | sed 's/%//')
local mem_percent=$(echo "$stats" | jq -r '.mem' | sed 's/%//')
local mem_usage=$(echo "$stats" | jq -r '.memUsage')
local alerts=""
# CPU告警
if (( $(echo "$cpu_percent > $CPU_LIMIT" | bc -l) )); then
alerts="$alerts\nCPU: ${cpu_percent}% (limit: ${CPU_LIMIT}%)"
fi
# 内存告警
if (( $(echo "$mem_percent > $MEM_LIMIT" | bc -l) )); then
alerts="$alerts\nMemory: ${mem_percent}% - ${mem_usage} (limit: ${MEM_LIMIT}%)"
fi
# 发送告警
if [ ! -z "$alerts" ]; then
local alert_message="Container: $container_name ($container_id)\nAlerts:$alerts"
send_alert "WARNING" "$alert_message"
fi
return 0
}
# 主监控循环
main() {
load_config
while true; do
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
# 获取所有容器
docker ps --format "{{.ID}}|{{.Names}}" | while IFS='|' read -r id name; do
check_container "$id" "$name"
done
# 休眠
sleep $INTERVAL
done
}
# 启动
main
高级监控脚本 (含历史数据和趋势分析)
#!/usr/bin/env python3
# container_advanced_monitor.py
import docker
import json
import time
import logging
import os
from datetime import datetime, timedelta
from collections import defaultdict
import smtplib
from email.mime.text import MIMEText
import requests
class ContainerMonitor:
def __init__(self, config_path='/etc/container_monitor/config.json'):
self.load_config(config_path)
self.client = docker.from_env()
self.setup_logging()
self.history = defaultdict(list)
def load_config(self, config_path):
"""加载配置"""
default_config = {
'cpu_threshold': 80,
'mem_threshold': 80,
'disk_threshold': 80,
'check_interval': 60,
'alert_cooldown': 300, # 告警冷却时间
'history_retention': 3600, # 历史数据保留时间
'email': {
'enabled': False,
'smtp_server': 'smtp.gmail.com',
'smtp_port': 587,
'username': '',
'password': '',
'from_addr': '',
'to_addr': ''
},
'webhook': {
'enabled': False,
'url': '',
'headers': {}
},
'containers': [] # 空列表表示监控所有容器
}
if os.path.exists(config_path):
with open(config_path, 'r') as f:
user_config = json.load(f)
default_config.update(user_config)
self.config = default_config
def setup_logging(self):
"""设置日志"""
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('/var/log/container_monitor.log'),
logging.StreamHandler()
]
)
self.logger = logging.getLogger(__name__)
def get_container_stats(self, container):
"""获取容器资源统计"""
stats = container.stats(stream=False)
name = container.name
# CPU计算
cpu_delta = stats['cpu_stats']['cpu_usage']['total_usage'] - \
stats['precpu_stats']['cpu_usage']['total_usage']
system_delta = stats['cpu_stats']['system_cpu_usage'] - \
stats['precpu_stats']['system_cpu_usage']
cpu_percent = 0.0
if system_delta > 0:
cpu_percent = (cpu_delta / system_delta) * 100.0
# 内存计算
mem_usage = stats['memory_stats']['usage']
mem_limit = stats['memory_stats']['limit']
mem_percent = (mem_usage / mem_limit) * 100.0
# 网络统计
networks = stats['networks']
total_rx = sum(n['rx_bytes'] for n in networks.values())
total_tx = sum(n['tx_bytes'] for n in networks.values())
return {
'name': name,
'cpu_percent': round(cpu_percent, 2),
'mem_percent': round(mem_percent, 2),
'mem_usage': self.format_bytes(mem_usage),
'mem_limit': self.format_bytes(mem_limit),
'network_rx': self.format_bytes(total_rx),
'network_tx': self.format_bytes(total_tx),
'timestamp': datetime.now().isoformat()
}
def format_bytes(self, bytes_value):
"""格式化字节"""
for unit in ['B', 'KB', 'MB', 'GB']:
if bytes_value < 1024.0:
return f"{bytes_value:.2f}{unit}"
bytes_value /= 1024.0
return f"{bytes_value:.2f}TB"
def check_thresholds(self, stats):
"""检查阈值"""
alerts = []
if stats['cpu_percent'] > self.config['cpu_threshold']:
alerts.append({
'type': 'CPU',
'current': stats['cpu_percent'],
'threshold': self.config['cpu_threshold'],
'message': f"CPU usage {stats['cpu_percent']}% exceeds {self.config['cpu_threshold']}%"
})
if stats['mem_percent'] > self.config['mem_threshold']:
alerts.append({
'type': 'Memory',
'current': stats['mem_percent'],
'threshold': self.config['mem_threshold'],
'message': f"Memory usage {stats['mem_percent']}% exceeds {self.config['mem_threshold']}%"
})
return alerts
def send_alert(self, container_name, alerts):
"""发送告警"""
subject = f"[Container Alert] {container_name}"
body = f"Container: {container_name}\nTime: {datetime.now().isoformat()}\n\n"
for alert in alerts:
body += f"- {alert['message']}\n"
# 日志
self.logger.warning(body)
# 邮件告警
if self.config['email']['enabled']:
self.send_email(subject, body)
# Webhook告警
if self.config['webhook']['enabled']:
self.send_webhook(subject, body)
def send_email(self, subject, body):
"""发送邮件"""
try:
msg = MIMEText(body)
msg['Subject'] = subject
msg['From'] = self.config['email']['from_addr']
msg['To'] = self.config['email']['to_addr']
with smtplib.SMTP(
self.config['email']['smtp_server'],
self.config['email']['smtp_port']
) as server:
server.starttls()
server.login(
self.config['email']['username'],
self.config['email']['password']
)
server.send_message(msg)
except Exception as e:
self.logger.error(f"Failed to send email: {e}")
def send_webhook(self, subject, body):
"""发送Webhook"""
try:
payload = {
'subject': subject,
'body': body,
'timestamp': datetime.now().isoformat()
}
requests.post(
self.config['webhook']['url'],
json=payload,
headers=self.config['webhook']['headers'],
timeout=10
)
except Exception as e:
self.logger.error(f"Failed to send webhook: {e}")
def run(self):
"""主运行循环"""
self.logger.info("Container Monitor Started")
last_alert_time = defaultdict(lambda: 0)
while True:
try:
# 获取容器列表
containers = self.client.containers.list()
# 过滤特定容器
if self.config['containers']:
containers = [
c for c in containers
if c.name in self.config['containers']
]
for container in containers:
stats = self.get_container_stats(container)
alerts = self.check_thresholds(stats)
if alerts:
# 检查冷却时间
current_time = time.time()
if current_time - last_alert_time[container.name] > \
self.config['alert_cooldown']:
self.send_alert(container.name, alerts)
last_alert_time[container.name] = current_time
# 保存历史数据
self.history[container.name].append(stats)
# 清理过期数据
cutoff = datetime.now() - timedelta(
seconds=self.config['history_retention']
)
self.history[container.name] = [
h for h in self.history[container.name]
if datetime.fromisoformat(h['timestamp']) > cutoff
]
# 记录正常状态
self.logger.info(
f"Container: {stats['name']} | "
f"CPU: {stats['cpu_percent']}% | "
f"Mem: {stats['mem_percent']}% | "
f"Net: RX={stats['network_rx']} TX={stats['network_tx']}"
)
time.sleep(self.config['check_interval'])
except KeyboardInterrupt:
self.logger.info("Monitor stopped by user")
break
except Exception as e:
self.logger.error(f"Error in monitoring loop: {e}")
time.sleep(10)
if __name__ == "__main__":
monitor = ContainerMonitor()
monitor.run()
配置文件示例 (config.json)
{
"cpu_threshold": 80,
"mem_threshold": 80,
"disk_threshold": 80,
"check_interval": 60,
"alert_cooldown": 300,
"history_retention": 3600,
"email": {
"enabled": true,
"smtp_server": "smtp.gmail.com",
"smtp_port": 587,
"username": "your_email@gmail.com",
"password": "your_app_password",
"from_addr": "your_email@gmail.com",
"to_addr": "admin@example.com"
},
"webhook": {
"enabled": true,
"url": "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK",
"headers": {
"Content-Type": "application/json"
}
},
"containers": ["nginx", "mysql", "redis"]
}
使用方法
基础脚本使用
# 赋予执行权限 chmod +x docker_resource_monitor.sh # 后台运行 nohup ./docker_resource_monitor.sh > /dev/null 2>&1 & # 添加到crontab (每分钟检查) */1 * * * * /path/to/docker_resource_monitor.sh
Python版本使用
# 安装依赖 pip3 install docker requests # 创建配置目录 mkdir -p /etc/container_monitor # 运行监控脚本 python3 container_advanced_monitor.py # 作为服务运行 cat > /etc/systemd/system/container-monitor.service << EOF [Unit] Description=Container Resource Monitor After=docker.service [Service] ExecStart=/usr/bin/python3 /path/to/container_advanced_monitor.py Restart=always User=root [Install] WantedBy=multi-user.target EOF systemctl enable container-monitor systemctl start container-monitor
容器化部署
FROM python:3.9-alpine RUN pip install docker requests COPY container_advanced_monitor.py /app/monitor.py COPY config.json /etc/container_monitor/config.json CMD ["python", "/app/monitor.py"]
这些脚本可以根据你的具体需求进行调整和扩展。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播