本文目录导读:

我来详细介绍Shell脚本配置容器监控通知的多种方法。
基础容器监控脚本
#!/bin/bash
# 容器监控配置
CONTAINERS=("nginx" "mysql" "redis") # 监控的容器名称
NOTIFY_EMAIL="admin@example.com"
NOTIFY_WEBHOOK="https://hooks.example.com/alert"
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# 监控函数
check_container_status() {
local container_name=$1
# 检查容器是否存在
if ! docker ps -a --format '{{.Names}}' | grep -q "^${container_name}$"; then
echo "容器 $container_name 不存在"
return 1
fi
# 检查容器运行状态
local status=$(docker inspect --format='{{.State.Status}}' "$container_name" 2>/dev/null)
case $status in
"running")
echo -e "${GREEN}容器 $container_name 运行正常${NC}"
return 0
;;
"exited")
echo -e "${RED}容器 $container_name 已停止${NC}"
return 1
;;
"restarting")
echo -e "${YELLOW}容器 $container_name 正在重启${NC}"
return 2
;;
*)
echo -e "${RED}容器 $container_name 状态异常: $status${NC}"
return 3
;;
esac
}
# 监控主循环
monitor_containers() {
for container in "${CONTAINERS[@]}"; do
check_container_status "$container"
local result=$?
if [ $result -ne 0 ]; then
# 发送告警通知
send_alert "$container" $result
fi
done
}
通知方式配置
邮件通知
#!/bin/bash
# 邮件通知配置
EMAIL_CONFIG() {
# 使用mailx或sendmail
SMTP_SERVER="smtp.example.com"
SMTP_PORT="587"
EMAIL_USER="monitor@example.com"
EMAIL_PASS="your_password"
# 创建邮件配置文件
cat > /tmp/msmtprc << EOF
account default
host $SMTP_SERVER
port $SMTP_PORT
from $EMAIL_USER
auth on
user $EMAIL_USER
password $EMAIL_PASS
tls on
tls_starttls on
EOF
}
send_email_alert() {
local container=$1
local status=$2
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
local hostname=$(hostname)
# 构建邮件内容
local subject="[容器告警] $container 状态异常"
local body="容器监控告警
时间: $timestamp
主机: $hostname
容器: $container
状态: $status
请及时检查处理"
# 发送邮件
echo "$body" | mailx -s "$subject" -r "$EMAIL_USER" "$NOTIFY_EMAIL"
echo "已发送邮件通知到 $NOTIFY_EMAIL"
}
Webhook通知
#!/bin/bash
# Webhook通知配置
send_webhook_alert() {
local container=$1
local status=$2
local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
# 构建JSON载荷
local payload=$(cat <<EOF
{
"alert_type": "container_monitor",
"severity": "critical",
"timestamp": "$timestamp",
"host": "$(hostname)",
"container": "$container",
"status": "$status",
"message": "Container $container status changed to $status",
"details": {
"container_id": "$(docker inspect -f '{{.ID}}' $container 2>/dev/null)",
"image": "$(docker inspect -f '{{.Config.Image}}' $container 2>/dev/null)",
"cpu_limit": "$(docker inspect -f '{{.HostConfig.CpuShares}}' $container 2>/dev/null)",
"memory_limit": "$(docker inspect -f '{{.HostConfig.Memory}}' $container 2>/dev/null)"
}
}
EOF
)
# 发送Webhook请求
response=$(curl -s -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your_token" \
-d "$payload" \
"$NOTIFY_WEBHOOK" 2>&1)
if [ $? -eq 0 ]; then
echo "Webhook通知发送成功"
else
echo "Webhook通知发送失败: $response"
fi
}
钉钉机器人群通知
#!/bin/bash
# 钉钉机器人配置
DINGTALK_WEBHOOK="https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN"
DINGTALK_SECRET="your_secret" # 如果开启了加签
# 钉钉签名计算
calc_dingtalk_sign() {
local timestamp=$(date +%s%3N)
local sign_base="$timestamp\n$DINGTALK_SECRET"
echo -ne "$sign_base" | openssl dgst -sha256 -hmac "$DINGTALK_SECRET" | base64
echo "$timestamp"
}
send_dingtalk_alert() {
local container=$1
local status=$2
# 获取签名和时间戳
local sign_result=$(calc_dingtalk_sign)
local timestamp=$(echo "$sign_result" | tail -1)
local sign=$(echo "$sign_result" | head -1)
# 构建消息内容
local message=$(cat <<EOF
{
"msgtype": "markdown",
"markdown": {
"title": "容器监控告警",
"text": "### 🚨 容器监控告警\n\n**容器名称**: $container\n**状态**: $status\n**时间**: $(date '+%Y-%m-%d %H:%M:%S')\n**主机**: $(hostname)\n\n> 请及时检查处理"
},
"at": {
"isAtAll": false
}
}
EOF
)
# 发送钉钉消息
local url="$DINGTALK_WEBHOOK×tamp=$timestamp&sign=$sign"
curl -s -X POST \
-H "Content-Type: application/json" \
-d "$message" \
"$url"
}
资源监控通知
#!/bin/bash
# 资源阈值配置
CPU_THRESHOLD=80 # CPU使用率阈值%
MEM_THRESHOLD=80 # 内存使用率阈值%
DISK_THRESHOLD=85 # 磁盘使用率阈值%
# 监控容器资源使用
check_container_resources() {
local container=$1
# 获取CPU使用率
local cpu_usage=$(docker stats --no-stream --format "{{.CPUPerc}}" "$container" | sed 's/%//')
cpu_usage=${cpu_usage:-0}
# 获取内存使用率
local mem_usage=$(docker stats --no-stream --format "{{.MemPerc}}" "$container" | sed 's/%//')
mem_usage=${mem_usage:-0}
# 检查磁盘使用
local disk_usage=$(docker system df --format "{{.Type}} {{.Size}}" | grep "Containers" | awk '{print $2}' | sed 's/GB//')
local alerts=""
# CPU告警
if (( $(echo "$cpu_usage > $CPU_THRESHOLD" | bc -l) )); then
alerts+="CPU使用率过高: ${cpu_usage}% (阈值: ${CPU_THRESHOLD}%) "
fi
# 内存告警
if (( $(echo "$mem_usage > $MEM_THRESHOLD" | bc -l) )); then
alerts+="内存使用率过高: ${mem_usage}% (阈值: ${MEM_THRESHOLD}%) "
fi
if [ -n "$alerts" ]; then
send_resource_alert "$container" "$alerts"
fi
}
send_resource_alert() {
local container=$1
local alerts=$2
local message="容器 $container 资源告警: $alerts"
echo "🔔 $message"
# 发送各种通知
send_email_alert "$container" "resource_warning" "$message"
send_webhook_alert "$container" "resource_warning" "$message"
}
日志监控通知
#!/bin/bash
# 日志监控配置
ERROR_PATTERNS=("ERROR" "FATAL" "CRASH" "OOM")
LOG_LINES=50 # 检查最后N行日志
# 监控容器日志
monitor_container_logs() {
local container=$1
local log_file="/var/log/docker/${container}.log"
# 获取最近的日志
local recent_logs=$(docker logs --tail $LOG_LINES "$container" 2>&1)
# 检查错误模式
for pattern in "${ERROR_PATTERNS[@]}"; do
if echo "$recent_logs" | grep -qi "$pattern"; then
log_alert "$container" "$pattern" "$recent_logs"
break
fi
done
}
log_alert() {
local container=$1
local pattern=$2
local logs=$3
local message=$(cat <<EOF
容器日志告警
容器: $container
匹配模式: $pattern
时间: $(date)
最近日志:
$logs
建议检查应用状态和错误日志
EOF
)
send_email_alert "$container" "log_alert" "$message"
send_webhook_alert "$container" "log_alert" "$message"
}
完整监控脚本
#!/bin/bash
# ===========================================
# 容器监控通知脚本
# 版本: 1.0
# 作者: DevOps Team
# ===========================================
# 配置区域
CONFIG_FILE="/etc/container-monitor/config.conf"
LOG_FILE="/var/log/container-monitor.log"
# 加载配置
load_config() {
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
else
echo "配置文件不存在,使用默认配置"
setup_default_config
fi
}
# 默认配置
setup_default_config() {
CONTAINERS=("nginx" "mysql" "redis")
NOTIFY_EMAIL="admin@example.com"
NOTIFY_WEBHOOK=""
NOTIFY_DINGTALK=""
CHECK_INTERVAL=60
ENABLE_RESOURCE_MONITORING=true
ENABLE_LOG_MONITORING=true
}
# 日志函数
log_message() {
local level=$1
local message=$2
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE"
}
# 主监控循环
main_monitoring_loop() {
log_message "INFO" "开始容器监控..."
while true; do
log_message "INFO" "执行监控检查..."
for container in "${CONTAINERS[@]}"; do
# 检查状态
check_container_status "$container"
local status=$?
# 如果状态异常,发送告警
if [ $status -ne 0 ]; then
send_combined_alert "$container" "status_alert" $status
fi
# 检查资源使用
if [ "$ENABLE_RESOURCE_MONITORING" = true ]; then
check_container_resources "$container"
fi
# 检查日志
if [ "$ENABLE_LOG_MONITORING" = true ]; then
monitor_container_logs "$container"
fi
done
# 等待下一次检查
sleep "$CHECK_INTERVAL"
done
}
# 组合通知发送
send_combined_alert() {
local container=$1
local alert_type=$2
local alert_data=$3
log_message "WARN" "发送告警: $container - $alert_type"
# 发送邮件
send_email_alert "$container" "$alert_type" "$alert_data"
# 发送Webhook
if [ -n "$NOTIFY_WEBHOOK" ]; then
send_webhook_alert "$container" "$alert_type" "$alert_data"
fi
# 发送钉钉
if [ -n "$NOTIFY_DINGTALK" ]; then
send_dingtalk_alert "$container" "$alert_type" "$alert_data"
fi
}
# 信号处理
cleanup() {
log_message "INFO" "收到停止信号,安全退出..."
exit 0
}
trap cleanup SIGINT SIGTERM
# 主程序
main() {
echo "========================================"
echo "容器监控通知系统"
echo "========================================"
# 检查依赖
command -v docker >/dev/null 2>&1 || { echo "需要安装Docker"; exit 1; }
command -v curl >/dev/null 2>&1 || { echo "需要安装curl"; exit 1; }
# 加载配置
load_config
# 启动监控
main_monitoring_loop
}
# 启动
main
配置文件示例
# /etc/container-monitor/config.conf
# 监控容器列表
CONTAINERS=(
"nginx"
"mysql"
"redis"
"postgresql"
)
# 通知配置
NOTIFY_EMAIL="admin@example.com"
NOTIFY_WEBHOOK="https://hooks.example.com/webhook"
NOTIFY_DINGTALK="https://oapi.dingtalk.com/robot/send?access_token=your_token"
# 邮件配置
SMTP_SERVER="smtp.gmail.com"
SMTP_PORT=587
EMAIL_USER="monitor@gmail.com"
EMAIL_PASS="your_app_password"
# 监控间隔(秒)
CHECK_INTERVAL=60
# 资源阈值
CPU_THRESHOLD=80
MEM_THRESHOLD=85
DISK_THRESHOLD=90
# 功能开关
ENABLE_RESOURCE_MONITORING=true
ENABLE_LOG_MONITORING=true
ENABLE_HEALTH_CHECK=false
部署和使用
# 1. 创建配置目录 sudo mkdir -p /etc/container-monitor sudo mkdir -p /var/log/container-monitor # 2. 创建配置文件 sudo cp config.conf /etc/container-monitor/ # 3. 设置执行权限 chmod +x container-monitor.sh # 4. 创建systemd服务 cat > /etc/systemd/system/container-monitor.service << EOF [Unit] Description=Container Monitoring Service After=docker.service Requires=docker.service [Service] ExecStart=/path/to/container-monitor.sh Restart=always RestartSec=10 User=root [Install] WantedBy=multi-user.target EOF # 5. 启动服务 sudo systemctl daemon-reload sudo systemctl enable container-monitor.service sudo systemctl start container-monitor.service # 6. 查看日志 sudo journalctl -u container-monitor.service -f
使用建议
- 安全配置:敏感信息使用环境变量或密钥管理服务
- 错误处理:添加重试机制和降级策略
- 性能优化:控制检查频率,避免资源消耗
- 日志管理:实现日志轮转和清理机制
- 告警聚合:避免重复告警,实现告警抑制
- 监控覆盖:包括健康检查、重启策略、端口监听等
这个配置可以根据你的实际需求进行调整和扩展。