Shell脚本如何配置容器监控通知

wen 实用脚本 1

本文目录导读:

Shell脚本如何配置容器监控通知

  1. 基础容器监控脚本
  2. 通知方式配置
  3. 资源监控通知
  4. 日志监控通知
  5. 完整监控脚本
  6. 配置文件示例
  7. 部署和使用
  8. 使用建议

我来详细介绍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&timestamp=$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

使用建议

  1. 安全配置:敏感信息使用环境变量或密钥管理服务
  2. 错误处理:添加重试机制和降级策略
  3. 性能优化:控制检查频率,避免资源消耗
  4. 日志管理:实现日志轮转和清理机制
  5. 告警聚合:避免重复告警,实现告警抑制
  6. 监控覆盖:包括健康检查、重启策略、端口监听等

这个配置可以根据你的实际需求进行调整和扩展。

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