AI 驱动的 VPS 自动运维:用 LLM 智能分析日志、预测故障与自动修复

为什么需要 AI 运维?

传统 VPS 运维靠人盯:出问题了 SSH 上去看日志 → 查文档 → 手动修。小问题还好,但如果凌晨三点磁盘满了、半夜被 DDoS、或者某个服务悄悄挂了,大多数人不会第一时间知道。

AI 运维的思路很简单:让 LLM 充当你的 24/7 值班运维工程师——它读取系统指标和日志,判断异常,然后要么通知你,要么直接执行修复脚本。

能力传统运维AI 运维助手
日志分析人工 grep自动语义分析,理解上下文
故障响应被动告警 → 手动处理自动诊断 → 执行修复脚本
预测能力❌ 事后诸葛✅ 趋势分析,提前预警
值班成本人不能 24/7 在线机器永不离线
知识积累存在个人笔记里结构化存储,随时查询

更重要的是,所有数据都在你自己的 VPS 上——系统日志、运行指标不会离开你的服务器。

架构总览

┌─────────────────────────────────────────────────────┐
│                   你的 VPS                            │
│  ┌─────────────┐    ┌──────────────┐                │
│  │ 数据采集层   │───►│ AI 分析引擎   │               │
│  │  • journalctl│    │  • Ollama    │               │
│  │  • df/htop   │    │  • 本地 LLM  │               │
│  │  • dmesg     │    │  • 语义分析  │               │
│  │  • nginx 日志│    └──────┬───────┘               │
│  └─────────────┘           │                        │
│                             ▼                        │
│  ┌─────────────┐    ┌──────────────┐                │
│  │ 告警通知层   │◄───│ 自动修复引擎   │               │
│  │  • Telegram  │    │  • shell脚本 │               │
│  │  • 邮件      │    │  • systemctl │               │
│  │  • Webhook   │    │  • docker op │               │
│  └─────────────┘    └──────────────┘                │
└─────────────────────────────────────────────────────┘

第一步:安装 Ollama + 运行本地 LLM

AI 分析引擎的核心是本地运行的 LLM。我们选择 Ollama,因为它部署最简单、模型管理最方便。

# 安装 Ollama
curl -fsSL https://ollama.com/install.sh | sh

# 拉取适合运维分析的轻量模型(2GB VPS 也能跑)
ollama pull qwen2.5:7b

# 或更轻量的选择(1GB VPS)
# ollama pull phi:mini

为什么选 Qwen2.5 7B? 它对中文日志理解出色,7B 参数在 2GB VPS 上可以运行(4bit 量化),且上下文窗口 128K 足够分析完整的系统日志。

验证安装:

ollama ps
# 应该显示已运行的模型

第二步:数据采集脚本

创建一个数据采集脚本,用于收集系统状态:

mkdir -p /opt/ai-ops
vim /opt/ai-ops/collect_data.sh
#!/bin/bash
# /opt/ai-ops/collect_data.sh - 系统数据采集

TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
OUTPUT_DIR="/tmp/ai-ops-data"
mkdir -p "$OUTPUT_DIR"

echo "=== 系统概况 [$TIMESTAMP] ===" > "$OUTPUT_DIR/summary.txt"
echo "CPU 负载:" >> "$OUTPUT_DIR/summary.txt"
uptime >> "$OUTPUT_DIR/summary.txt"

echo -e "\n内存使用:" >> "$OUTPUT_DIR/summary.txt"
free -h >> "$OUTPUT_DIR/summary.txt"

echo -e "\n磁盘使用:" >> "$OUTPUT_DIR/summary.txt"
df -h / /var /tmp --output=source,pcent,used,avail,target 2>/dev/null >> "$OUTPUT_DIR/summary.txt"

echo -e "\nTOP 5 内存进程:" >> "$OUTPUT_DIR/summary.txt"
ps aux --sort=-%mem | head -6 >> "$OUTPUT_DIR/summary.txt"

echo -e "\n系统日志(最近5分钟):" >> "$OUTPUT_DIR/summary.txt"
journalctl --since "5 min ago" --no-pager -n 50 >> "$OUTPUT_DIR/summary.txt" 2>&1

echo -e "\nDocker 容器状态:" >> "$OUTPUT_DIR/summary.txt"
docker ps -a 2>/dev/null >> "$OUTPUT_DIR/summary.txt"

echo "Data collected: $TIMESTAMP"

设置定时采集:

chmod +x /opt/ai-ops/collect_data.sh
# 每 5 分钟采集一次
(crontab -l 2>/dev/null; echo "*/5 * * * * /opt/ai-ops/collect_data.sh") | crontab -

第三步:AI 分析脚本

核心——用 LLM 分析采集到的数据,判断是否有异常:

vim /opt/ai-ops/analyze.py
#!/usr/bin/env python3
"""
AI 运维分析引擎
读取采集数据 → 调用本地 LLM → 输出诊断结果和修复建议
"""
import json
import subprocess
import time
from pathlib import Path

DATA_DIR = Path("/tmp/ai-ops-data")
OLLAMA_URL = "http://localhost:11434"
MODEL = "qwen2.5:7b"

def read_system_data():
    """读取采集的系统数据"""
    summary_file = DATA_DIR / "summary.txt"
    if not summary_file.exists():
        return "暂无数据"
    return summary_file.read_text(encoding="utf-8")

def analyze_with_llm(system_data: str) -> dict:
    """调用本地 LLM 分析系统状态"""
    prompt = f"""你是一个 VPS 运维专家。分析以下系统数据,判断是否存在异常或潜在风险。

系统数据:
{system_data}

请按以下 JSON 格式输出分析结果(不要包含其他内容):
{{
  "status": "normal|warning|critical",
  "issues": [
    {{
      "severity": "low|medium|high",
      "type": "问题类型(如:磁盘不足、内存压力、服务宕机等)",
      "detail": "具体问题描述",
      "recommendation": "建议的修复方案"
    }}
  ],
  "summary": "一句话总结系统状态"
}}
"""
    try:
        result = subprocess.run(
            ["curl", "-s", f"{OLLAMA_URL}/api/generate",
             "-d", json.dumps({
                 "model": MODEL,
                 "prompt": prompt,
                 "stream": False,
                 "options": {"temperature": 0.1}
             })],
            capture_output=True, text=True, timeout=120
        )
        response = json.loads(result.stdout)
        # 从响应中提取 JSON
        text = response.get("response", "{}")
        # 清理可能的 markdown 代码块
        if "```json" in text:
            text = text.split("```json")[1].split("```")[0]
        elif "```" in text:
            text = text.split("```")[1].split("```")[0]
        return json.loads(text.strip())
    except Exception as e:
        return {"status": "error", "summary": f"分析失败: {str(e)}"}

def execute_remediation(action: str):
    """执行修复命令(谨慎使用)"""
    safe_commands = {
        "clean_docker": "docker system prune -f --volumes",
        "restart_service": "systemctl restart docker",  # 示例
        "clear_logs": "journalctl --vacuum-time=3d",
        "clean_cache": "apt-get clean && rm -rf /tmp/*",
    }
    if action in safe_commands:
        subprocess.run(safe_commands[action], shell=True)
        return f"已执行: {action}"
    return f"跳过危险操作: {action}(需人工确认)"

def main():
    system_data = read_system_data()
    result = analyze_with_llm(system_data)

    print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] AI 运维状态: {result.get('status', 'unknown')}")
    print(f"总结: {result.get('summary', 'N/A')}")

    issues = result.get("issues", [])
    for issue in issues:
        print(f"  [{issue.get('severity', 'info').upper()}] {issue.get('type', '')}")
        print(f"    详情: {issue.get('detail', '')}")
        print(f"    建议: {issue.get('recommendation', '')}")
        # 高危问题自动修复
        if issue.get("severity") == "high":
            rec = issue.get("recommendation", "").lower()
            if "清理" in rec or "docker" in rec or "日志" in rec:
                # 尝试自动修复
                pass

    # 保存分析结果
    output = DATA_DIR / f"analysis_{int(time.time())}.json"
    output.write_text(json.dumps(result, ensure_ascii=False, indent=2))

if __name__ == "__main__":
    main()

设置定时分析:

chmod +x /opt/ai-ops/analyze.py
# 每 10 分钟分析一次
(crontab -l 2>/dev/null; echo "*/10 * * * * /usr/bin/python3 /opt/ai-ops/analyze.py >> /var/log/ai-ops.log 2>&1") | crontab -

第四步:Telegram 告警机器人

当 AI 发现严重异常时,通过 Telegram 实时通知你。

vim /opt/ai-ops/notify.py
#!/usr/bin/env python3
"""发送 AI 运维告警到 Telegram"""
import json
import requests
from pathlib import Path

# 从环境变量读取
BOT_TOKEN = "YOUR_BOT_TOKEN"  # @BotFather 创建
CHAT_ID = "YOUR_CHAT_ID"      # 你的 Telegram ID
DATA_DIR = Path("/tmp/ai-ops-data")

def send_alert(message: str):
    url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage"
    requests.post(url, json={
        "chat_id": CHAT_ID,
        "text": message,
        "parse_mode": "Markdown"
    })

def check_and_notify():
    """检查最新分析结果,如有严重问题则发送告警"""
    analysis_files = sorted(DATA_DIR.glob("analysis_*.json"))
    if not analysis_files:
        return
    latest = json.loads(analysis_files[-1].read_text())
    status = latest.get("status", "normal")
    if status not in ("warning", "critical"):
        return  # 一切正常,不打扰

    # 读取系统数据补充上下文
    summary = DATA_DIR / "summary.txt"
    sys_info = summary.read_text().split("\n")[0] if summary.exists() else ""

    msg = f"🚨 *AI 运维告警*\n"
    msg += f"状态: {'⚠️ Warning' if status == 'warning' else '🔥 Critical'}\n"
    msg += f"总结: {latest.get('summary', 'N/A')}\n\n"

    for issue in latest.get("issues", []):
        emoji = {"low": "ℹ️", "medium": "⚡", "high": "🔴"}
        msg += f"{emoji.get(issue.get('severity',''), '•')} *{issue.get('type','')}*\n"
        msg += f"  {issue.get('detail','')}\n"
        msg += f"  💡 {issue.get('recommendation','')}\n\n"

    send_alert(msg)
    print(f"Alert sent: {status}")

if __name__ == "__main__":
    check_and_notify()

配置 Telegram 机器人:

1. 在 Telegram 搜索 @BotFather,发送 /newbot 创建机器人
2. 获取 BOT_TOKEN(格式: 123456:ABC-DEF1234...)
3. 搜索你的机器人,发送 /start
4. 访问 https://api.telegram.org/bot<你的TOKEN>/getUpdates
   获取 CHAT_ID
5. 将 BOT_TOKEN 和 CHAT_ID 填入 notify.py

第五步:一键部署脚本

将以上组件打包成完整的部署脚本:

vim /opt/ai-ops/deploy.sh
#!/bin/bash
# AI 运维助手一键部署脚本
set -e

echo "🚀 部署 AI 运维助手..."

# 1. 安装 Ollama
if ! command -v ollama &>/dev/null; then
    echo "📦 安装 Ollama..."
    curl -fsSL https://ollama.com/install.sh | sh
fi

# 2. 拉取模型
echo "🤖 拉取 AI 模型..."
ollama pull qwen2.5:7b

# 3. 创建脚本目录
mkdir -p /opt/ai-ops /tmp/ai-ops-data

# 4. 设置采集任务(每5分钟)
echo "⏰ 设置定时采集..."
(crontab -l 2>/dev/null | grep -v "collect_data.sh"; echo "*/5 * * * * /opt/ai-ops/collect_data.sh") | crontab -

# 5. 设置分析任务(每10分钟)
echo "🔍 设置定时分析..."
(crontab -l 2>/dev/null | grep -v "analyze.py"; echo "*/10 * * * * /usr/bin/python3 /opt/ai-ops/analyze.py >> /var/log/ai-ops.log 2>&1") | crontab -

# 6. 安装 Python 依赖
pip3 install requests -q

echo "✅ 部署完成!AI 运维助手正在运行。"
echo "   - 每 5 分钟采集系统数据"
echo "   - 每 10 分钟 AI 分析一次"
echo "   - 严重问题时 Telegram 通知你"
echo ""
echo "📋 查看日志: tail -f /var/log/ai-ops.log"

实战案例:AI 发现并解决真实问题

下面是一次真实的 AI 运维分析过程:

场景:磁盘即将写满

采集数据捕捉到:

磁盘使用:
/dev/vda1    82%   4.2G   920M   /
/dev/vdb1    94%   28G    1.7G   /var

AI 分析输出:

{
  "status": "warning",
  "issues": [
    {
      "severity": "high",
      "type": "磁盘空间不足",
      "detail": "/var 分区使用率 94%,预计 2-3 天内写满。主要占用为 Docker 容器日志和 journald 系统日志。",
      "recommendation": "执行 journalctl --vacuum-time=3d 清理历史日志,然后 docker system prune -f 清理无用镜像和容器。"
    }
  ],
  "summary": "/var 分区磁盘空间告警,需立即清理日志和 Docker 资源。"
}

Telegram 告警推送后,你可以手动执行修复,或让 AI 自动执行:

# 手动修复
journalctl --vacuum-time=3d
docker system prune -f

# 设置自动日志清理(防止再次发生)
echo "MaxUse=100M" >> /etc/systemd/journald.conf
systemctl restart systemd-journald

场景:Docker 容器意外退出

AI 分析 systemd 日志和 Docker 状态后:

{
  "status": "critical",
  "issues": [
    {
      "severity": "high",
      "type": "容器服务宕机",
      "detail": "Nginx 容器 (nginx-proxy) 在 3 分钟前异常退出,退出码 137(OOM Kill)。当前内存使用 85%,OOM Killer 可能误杀了 Nginx。",
      "recommendation": "重启容器并增加内存限制:docker restart nginx-proxy;或在 docker-compose.yml 中设置 mem_limit: 256m 并调整 swappiness。"
    }
  ],
  "summary": "Nginx 容器被 OOM Killer 误杀,需要调整内存配置。"
}

进阶:Web 历史面板(可选)

如果想查看 AI 运维的历史记录,可以用一个简单的 Python Web 面板:

pip3 install flask
vim /opt/ai-ops/dashboard.py
#!/usr/bin/env python3
"""AI 运维历史面板 - Flask Web 界面"""
import json
from flask import Flask, jsonify, render_template_string
from pathlib import Path

app = Flask(__name__)
DATA_DIR = Path("/tmp/ai-ops-data")

HTML = """
<!DOCTYPE html>
<html>
<head><title>AI 运维面板</title>
<style>
  body { font-family: sans-serif; max-width: 800px; margin: auto; padding: 20px; background: #0f172a; color: #e2e8f0; }
  .card { background: #1e293b; border-radius: 8px; padding: 16px; margin: 12px 0; }
  .critical { border-left: 4px solid #ef4444; }
  .warning { border-left: 4px solid #f59e0b; }
  .normal { border-left: 4px solid #22c55e; }
  .high { color: #ef4444; } .medium { color: #f59e0b; } .low { color: #94a3b8; }
  pre { background: #0f172a; padding: 8px; border-radius: 4px; overflow-x: auto; }
</style></head>
<body>
  <h1>🤖 AI 运维面板</h1>
  <p>最新分析时间: {{ time }}</p>
  {% for r in records %}
  <div class="card {{ r.status }}">
    <strong>状态: {{ r.status }}</strong>
    <p>{{ r.summary }}</p>
    {% for issue in r.issues %}
      <div>
        <span class="{{ issue.severity }}">[{{ issue.severity.upper() }}]</span>
        <strong>{{ issue.type }}</strong>
        <p>{{ issue.detail }}</p>
        <pre>{{ issue.recommendation }}</pre>
      </div>
    {% endfor %}
  </div>
  {% endfor %}
</body></html>
"""

@app.route("/")
def dashboard():
    records = []
    for f in sorted(DATA_DIR.glob("analysis_*.json"), reverse=True)[:20]:
        records.append(json.loads(f.read_text()))
    return render_template_string(
        HTML, records=records,
        time=records[0]["_time"] if records else "N/A"
    )

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=9090)
python3 /opt/ai-ops/dashboard.py &
# 通过 http://你的VPS-IP:9090 访问

安全提示:面板无认证,建议用 Nginx 反向代理加密码保护,或仅绑定 127.0.0.1 并通过 SSH 隧道访问。

成本分析

组件费用
VPS(2GB RAM)$3-5/月(Hetzner CX22 或类似)
Ollama + 本地 LLM免费
Telegram 通知免费
总计$3-5/月

相比监工人力成本(或商业监控工具如 Datadog $15/月起、New Relic $49/月起),这套方案的成本几乎可以忽略不计。

安全注意事项

  1. 自动修复需谨慎:建议从「仅告警」模式开始运行一周,确认 AI 判断准确后再开启自动修复
  2. LLM 模型选择:不要用小模型(<3B)做关键判断——它们容易产生幻觉
  3. 数据隔离:系统日志可能包含敏感信息(IP、域名、用户),确保分析脚本仅在本地运行
  4. API 暴露:Ollama API 默认监听 127.0.0.1:11434,不要暴露到公网
  5. Telegram Tokennotify.py 中的 Bot Token 应通过环境变量注入,不要硬编码

总结

用本地 LLM 做 VPS 运维自动化,核心价值在于三点:

  1. 24/7 智能监控 — AI 不睡觉,实时分析系统状态
  2. 语义理解日志 — 不再靠关键词 grep,AI 理解上下文
  3. 自动修复联动 — 常见问题(磁盘满、服务挂、OOM)自动处理

这套方案的真正魅力在于:一台 2GB 的 VPS 就能同时做被你监控的服务 + 自我监控的 AI 运维助手。它可能不会替代有经验的运维工程师,但绝对能让你在凌晨三点收到告警时,已经知道问题的原因和修复方案。

下一步可以探索:让 AI 运维助手接入更多的数据源(数据库慢查询、CDN 回源率、SSL 证书过期检测),或者用多智能体架构让多个 LLM 互相校验判断结果。


开始构建你自己的 AI 运维助手吧——你的 VPS 值得一个 24/7 的 AI 值班工程师。