zabbix-deepseek

Docker部署zabbix

img

  1. 安装docker
    mkdir ~/docker && mkdir ~/docker/zabbix-docker && cd ~/docker/zabbix-docker

  2. 安装zabbix-server
    ZABBIX_WEB_NGINX_HTTP_PORT=8080
    docker compose -f docker-compose_v3_alpine_mysql_latest.yaml up -d

docker inspect -f '{{range $net,$cfg := .NetworkSettings.Networks}}{{printf "%s → %s\n" $net $cfg.IPAddress}}{{end}}' zabbix-docker-74-zabbix-server-1

zabbix-docker-74_backend → 172.16.239.3
zabbix-docker-74_database → 172.21.0.4
zabbix-docker-74_frontend → 172.16.238.3
zabbix-docker-74_tools_frontend → 172.16.240.2
  1. 配置docker可视化
docker volume create portainer_data  # 创建数据卷
docker run -d -p 9000:9000 -p 8000:8000 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest

• -d:后台运行容器
• -p 9000:9000:映射Web界面端口
• -p 8000:8000:映射Edge Agent通信端口(可选)
• --restart always:容器自动重启
• -v /var/run/docker.sock:/var/run/docker.sock:挂载Docker套接字
• -v portainer_data:/data:持久化存储Portainer数据

获取token
docker ps portainer
setup_token=65c4c591e83e0a16b6476defcf2c4ba9defb9faf907d1133af6f3b1574e8d1c9

  1. 启动zabbix-agent

docker run -dit --name zabbix-agent --network zabbix-docker-74_backend -p 10050:10050 -e ZBX_HOSTNAME="Zabbix server" -e ZBX_SERVER_HOST="172.16.239.2" -e ZBX_SERVER_PORT="10051" zabbix/zabbix-agent:latest

docker inspect -f '{{range $net,$cfg := .NetworkSettings.Networks}}{{printf "%s → %s\n" $net $cfg.IPAddress}}{{end}}' zabbix-agent

  1. 可视化
    192.168.137.11:8080-->zabbix_server
    http://192.168.137.11:9000/-->docker 可视化

设置媒介、触发器与动作

配置脚本

将主机的脚本目录挂在到 Zabbix server 中脚本目录的挂载。

# 确认在镜像中存在如下目录,作为脚本的挂载目录
docker exec -it zabbix-docker-74-zabbix-server-1 /bin/sh
ls -ld /usr/lib/zabbix/alertscripts

# 宿主机
cd ~/docker/zabbix-scripts/
vi deepseek.sh
#!/bin/bash
echo "hello deepseek"

chmod 755 zabbix-scripts
chmod +x zabbix-scripts/*.sh

修改 docker-compose_v3_alpine_mysql_latest.yaml 文件

  volumes:
   - /etc/timezone:/etc/timezone:ro
   - ~/docker/zabbix-scripts:/usr/lib/zabbix/alertscripts  # 加入这一行

vi deepseek.sh

# 先停止并移除当前运行的容器(不会删除数据卷和镜像)
docker compose -f docker-compose_v3_alpine_mysql_latest.yaml down

# 重新创建并启动容器(会应用新的volumes配置)
docker compose -f docker-compose_v3_alpine_mysql_latest.yaml up -d
#!/bin/bash

# 获取当前脚本所在目录的绝对路径
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)

# 获取当前时间(格式:年-月-日 时:分:秒)
CURRENT_TIME=$(date "+%Y-%m-%d %H:%M:%S")

# 在脚本同目录创建test.txt并写入内容(包含时间戳)
echo "[$CURRENT_TIME] hello deepseek" >> "$SCRIPT_DIR/test.txt"

媒介、用户、触发器、动作

img
img
img

创建媒介:Alerts>>Media types>>
用户关联媒介:Users>>[Admin]>>Media>>
动作:Alerts>>Actions>>Trigger actions

DeepSeek诊断zabbix

配置Python环境

docker exec -it -u root zabbix-docker-74-zabbix-server-1 /bin/sh # 进入Docker容器

apk update
apk add --no-cache python3 py3-pip
python3 --version 
pip3 --version

安装 venv 为我们的代码创建虚拟环境

1. 安装虚拟环境工具(Alpine 中需手动安装)
apk add --no-cache python3-venv

2. 创建虚拟环境(路径可自定义,例如 /var/lib/zabbix/venv)
python3 -m venv /var/lib/zabbix/venv

3. 激活虚拟环境
source /var/lib/zabbix/venv/bin/activate

4. 在虚拟环境中安装 openai(此时 pip 指向虚拟环境,无权限问题)
pip install openai

5. 验证安装(激活状态下)
python -c "import openai; print('安装成功')"  # 无报错即成功

6. 退出虚拟环境(后续调用脚本时需先激活)
deactivate

配置DeepSeek API

.env配置DeepSeekAPI # 在DeepSeek.sh的相同路径下创建

DEEPSEEK_API_KEY=sk-*******

通过python-dotenv 读取 .env 文件中的环境变量(DEEPSEEK_API_KEY)

source /var/lib/zabbix/venv/bin/activate
pip install python-dotenv
apk add curl
curl -v https://api.deepseek.com

DeepSeek 生成告警报表

import os
import sys
import datetime
from openai import OpenAI
from dotenv import load_dotenv  # 新增:导入dotenv库

load_dotenv()  # 默认读取当前目录的.env文件,若路径不同可指定:load_dotenv("/path/to/.env")

def generate_alert_report():
    # 定义错误日志文件路径(与脚本同目录)
    script_dir = os.path.dirname(os.path.abspath(__file__))  # 获取当前脚本所在目录(绝对路径)
    error_log = os.path.join(script_dir, "error.log")  # 错误日志放在脚本目录
    
    # 接收从Shell脚本传递的参数
    if len(sys.argv) != 7:
        error_msg = "错误:参数数量不正确,需要6个参数(cpu_util, host_name, item_key, host_ip, event_time, trigger_name)"
        with open(error_log, "a", encoding="utf-8") as f:
            f.write(f"[{datetime.datetime.now()}] {error_msg}\n")
        return error_msg
    
    # 解析参数
    cpu_util = sys.argv[1]       # CPU利用率值
    host_name = sys.argv[2]      # 主机名称
    item_key = sys.argv[3]       # 监控项键值
    host_ip = sys.argv[4]        # 主机IP
    event_time = sys.argv[5]     # 告警时间
    trigger_name = sys.argv[6]   # 触发器名称

    try:
        # 检查API密钥是否存在
        if not os.environ.get("DEEPSEEK_API_KEY"):
            error_msg = "错误:未设置DEEPSEEK_API_KEY环境变量"
            with open(error_log, "a", encoding="utf-8") as f:
                f.write(f"[{datetime.datetime.now()}] {error_msg}\n")
            return error_msg

        # 初始化OpenAI客户端(DeepSeek兼容OpenAI SDK)
        client = OpenAI(
            api_key=os.environ.get("DEEPSEEK_API_KEY"),
            base_url="https://api.deepseek.com/v1"
        )

        # 构建系统提示词(定义AI的角色和报告要求)
        system_prompt = """
        你是一名资深运维工程师,擅长分析服务器性能告警并生成专业报告。
        请根据提供的CPU告警信息,生成一份结构化的告警分析报告,包含以下内容:
        1. 告警基本信息(主机、IP、时间、触发条件)
        2. 可能的原因分析(基于CPU利用率和监控项)
        3. 建议的处理步骤(分点说明,清晰具体)
        4. 预防措施(如何避免类似问题再次发生)
        
        报告风格要专业、简洁,重点突出,便于运维人员快速理解和处理。
        """

        # 构建用户提示词(传递具体参数)
        user_prompt = f"""
        服务器告警信息如下:
        - 主机名称:{host_name}
        - 主机IP:{host_ip}
        - 告警时间:{event_time}
        - 触发条件:{trigger_name}
        - 当前CPU利用率:{cpu_util}%
        - 监控项键值:{item_key}
        
        请基于以上信息生成告警分析报告。
        """

        # 调用DeepSeek模型
        response = client.chat.completions.create(
            model="deepseek-chat",
            messages=[
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": user_prompt}
            ],
            stream=False,
            max_tokens=1000
        )

        # 获取模型返回的报告内容
        report_content = response.choices[0].message.content

        # 生成报告文件名(包含主机名和时间戳)
        timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
        clean_host_name = host_name.replace(" ", "_")  # 处理主机名中的空格
        report_filename = os.path.join(script_dir, f"alert_report_{clean_host_name}_{timestamp}.txt")  # 关键:用script_dir指定路径
        
        # 将报告写入文件
        with open(report_filename, "w", encoding="utf-8") as f:
            f.write(f"=== 服务器CPU告警分析报告 ===\n")
            f.write(f"生成时间:{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n")
            f.write(report_content)
        
        return f"告警报告生成成功:{report_filename}"

    except Exception as e:
        # 捕获所有异常并写入错误日志
        error_msg = f"生成报告失败:{str(e)}"
        with open(error_log, "a", encoding="utf-8") as f:
            f.write(f"[{datetime.datetime.now()}] {error_msg}\n")
        return error_msg

if __name__ == "__main__":
    result = generate_alert_report()
    print(result)  # 输出结果给Shell脚本

deepseek.sh 脚本调用 deepseek.py

#!/bin/bash

# 获取脚本目录和日志文件
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
LOG_FILE="$SCRIPT_DIR/cpu_multi_params_log.log"

# 接收多个参数(按Zabbix配置的顺序对应)
cpu_util="$1"       # 参数1:CPU利用率值
host_name="$2"      # 参数2:主机名称
item_key="$3"       # 参数3:监控项键值
host_ip="$4"        # 参数4:主机IP
event_time="$5"     # 参数5:告警时间
trigger_name="$6"   # 参数6:触发器名称

# 记录所有参数到日志
{
   echo "========================================="
   echo "日志生成时间: $(date "+%Y-%m-%d %H:%M:%S")"
   echo "1. CPU利用率值: $cpu_util"  
   echo "2. 主机名称: $host_name"
   echo "3. 监控项键值: $item_key"
   echo "4. 主机IP地址: $host_ip"
   echo "5. 告警触发时间: $event_time"
   echo "6. 触发器名称: $trigger_name"
   echo ""
} >> "$LOG_FILE"

# 简单验证(确保核心参数不为空)
if [ -z "$cpu_util" ] || [ -z "$host_name" ]; then
   echo "[$(date "+%Y-%m-%d %H:%M:%S")] 错误:核心参数缺失(CPU值或主机名)" >> "$LOG_FILE"
   exit 1
fi

echo "[$(date "+%Y-%m-%d %H:%M:%S")] 多参数接收成功" >> "$LOG_FILE"

# 调用deepseek.py并传递6个参数
PY_SCRIPT="$SCRIPT_DIR/deepseek.py"
if [ -f "$PY_SCRIPT" ]; then
   echo "[$(date "+%Y-%m-%d %H:%M:%S")] 开始调用Python脚本生成报告" >> "$LOG_FILE"
   # 执行Python脚本并捕获输出结果
   python_result=$(
       source /var/lib/zabbix/venv/bin/activate && \  # 激活虚拟环境
       python3 "$PY_SCRIPT" "$cpu_util" "$host_name" "$item_key" "$host_ip" "$event_time" "$trigger_name" 2>&1
   )
   # 将Python脚本的执行结果写入日志
   echo "[$(date "+%Y-%m-%d %H:%M:%S")] Python脚本执行结果: $python_result" >> "$LOG_FILE"
else
   echo "[$(date "+%Y-%m-%d %H:%M:%S")] 错误:未找到Python脚本 $PY_SCRIPT" >> "$LOG_FILE"
   exit 1
fi

设置媒介(传入参数)
img

实测结果

img
img

posted @ 2026-08-18 17:15  WiseHYH  阅读(17)  评论(0)    收藏  举报