一、为什么要先搭建故障靶场?

在 OpsPilot 项目中,我们的最终目标不是简单做一个问答机器人,而是希望构建一个面向企业业务系统的智能运维 Agent 平台。系统需要能够接收 Prometheus / Alertmanager 产生的告警,结合指标、日志、服务状态和运维知识库进行分析,最后输出根因判断、处置建议,并逐步走向“监控—分析—决策—执行—复盘”的智能运维闭环。

但是在真正接入真实业务系统之前,我们首先需要一个可控、可复现、可反复实验的环境。这个环境既要像真实业务系统一样包含服务、数据库、监控和告警链路,又不能直接影响真实系统的运行。因此,本阶段我主要完成了一个本地故障靶场的搭建工作。

所谓“故障靶场”,可以理解为一个专门用来制造、观察和分析故障的实验环境。它的作用类似于安全领域的网络靶场:我们可以主动构造数据库异常、接口错误率上升、服务不可用、日志风暴等典型故障,然后观察 Prometheus 如何采集指标,Alertmanager 如何触发告警,后续 Agent 又该如何理解这些告警并给出分析结果。

本篇博客主要记录我在 OpsPilot 项目中搭建故障靶场的过程、系统结构、关键理解和阶段性收获。

二、本阶段的工作目标

本阶段工作的核心目标是:先搭建一个可运行的最小运维实验环境,为后续智能分析 Agent 的开发提供真实数据来源。

具体来说,需要完成以下几件事:

1. 使用 Docker Compose 编排多个服务;
2. 搭建一个模拟业务服务 `demo-api`;
3. 搭建数据库服务 `postgres`;
4. 接入 Prometheus 进行指标采集;
5. 接入 Alertmanager 进行告警转发;
6. 编写基础告警规则;
7. 准备典型故障场景和运行脚本;
8. 验证整个靶场能够正常启动和访问。

也就是说,本阶段并不是直接实现大模型 Agent 的完整推理功能,而是先把“告警从哪里来”这个问题解决掉。

对于智能运维系统来说,Agent 的分析能力建立在真实、稳定、结构化的监控数据之上。如果没有可控的 Prometheus 指标、告警规则和故障样本,后续根因分析、RAG 检索、处置建议都没有可靠的输入。

三、靶场系统的整体结构

本次搭建的故障靶场主要由以下几个部分组成:
opspilot-fault-lab
├── demo-api           # 模拟业务服务
├── postgres           # PostgreSQL 数据库
├── prometheus         # 指标采集与告警规则
├── alertmanager       # 告警接收与 webhook 转发
├── scripts            # 启动、测试、辅助脚本
├── runbooks           # 故障处理手册
├── reports            # 事故复盘模板
├── payloads           # 示例 webhook 告警数据
├── docker-compose.yml # 容器编排文件
└── .env.example       # 环境变量示例文件

从逻辑上看,它可以分成四层:

第一层:业务层
demo-api + postgres

第二层:监控层
Prometheus

第三层:告警层
Alertmanager

第四层:后续智能分析层
OpsPilot Agent / Webhook Receiver / RAG / 自动化脚本

目前本阶段主要完成前三层,也就是让业务服务、数据库、Prometheus 和 Alertmanager 能够在本地组成一条基本监控链路。


四、各组件的作用理解

1. demo-api:模拟业务系统

demo-api 是靶场中的模拟业务服务。它的作用不是实现复杂业务逻辑,而是提供一个可以被监控、可以被访问、可以被人为制造异常的服务。

例如,它可以提供健康检查接口、业务请求接口、故障触发接口等。后续我们可以通过访问不同接口来模拟:

  • 接口响应变慢;

  • 接口错误率升高;

  • 数据库连接失败;

  • 日志快速增长;

  • 服务健康状态异常。

对于 Prometheus 来说,demo-api 就是一个被监控对象;对于 OpsPilot 来说,它就是后续智能分析的故障来源。


2. postgres:模拟数据库依赖

真实业务系统通常不会只有一个后端服务,往往还依赖数据库、缓存、消息队列等基础组件。因此靶场中加入了 PostgreSQL 数据库,用来模拟业务服务的外部依赖。

这样做的好处是,后续可以构造更接近真实运维场景的问题,例如:

  • 数据库不可达;

  • 数据库连接池耗尽;

  • SQL 查询失败;

  • 业务服务因为数据库异常而产生连锁错误。

这类问题比单纯的“服务挂了”更有分析价值,因为它涉及服务之间的依赖关系,也更适合后续 Agent 做根因分析。


3. Prometheus:指标采集与告警规则

Prometheus 是整个故障靶场的监控核心。它主要负责两件事:

第一,定期抓取各个服务暴露出来的指标;

第二,根据告警规则判断当前系统是否出现异常。

在靶场中,Prometheus 会周期性访问 demo-api 的指标接口,并保存时间序列数据。后续我们可以通过 PromQL 查询某个指标在一段时间内的变化趋势,比如:

up
rate(http_requests_total[5m])
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))

这些 PromQL 查询结果,后续会成为 OpsPilot Agent 分析故障的重要证据。


4. Alertmanager:告警管理与转发

Prometheus 本身负责判断“是否触发告警”,但告警触发之后如何分组、去重、静默、路由和转发,通常由 Alertmanager 负责。

在本项目中,Alertmanager 的一个重要作用是:把 Prometheus 产生的告警通过 webhook 推送给后续的 OpsPilot 服务。

可以把 Alertmanager 理解为监控系统和智能运维 Agent 之间的桥梁。

Prometheus 发现异常
        ↓
触发告警规则
        ↓
发送给 Alertmanager
        ↓
Alertmanager 通过 webhook 转发
        ↓
OpsPilot 接收告警并进行分析

虽然目前后续 Agent 服务还没有完全接入,但提前把 Alertmanager 和 webhook 配置好,可以让后面的开发直接复用这条告警链路。


五、Docker Compose 在这里解决了什么问题?

一开始我对 Docker Compose 的理解还比较模糊,只知道它和 Docker 有关。经过这次搭建,我对它的理解更清晰了。

如果只用普通 Docker 命令,我们需要分别启动 PostgreSQL、demo-api、Prometheus、Alertmanager 等多个容器,并手动处理它们之间的网络、端口、依赖关系和配置挂载。这对于一个多组件系统来说非常麻烦。

Docker Compose 的作用就是用一个 docker-compose.yml 文件把这些服务统一描述出来:

services:
  postgres:
    image: postgres:16-alpine

  demo-api:
    build: ./demo-api

  prometheus:
    image: prom/prometheus

  alertmanager:
    image: prom/alertmanager

这样我们只需要执行:

docker compose up -d --build

就可以一次性启动整个靶场环境。

这也是它非常适合项目实训的原因:环境可以被代码化、版本化、重复部署。团队成员不需要每个人手动配置一遍复杂环境,只要拿到同一份仓库,就可以用相同的 Compose 文件拉起一致的实验环境。


六、实际启动流程

本项目同时准备了 Windows PowerShell 和 Linux Shell 两种启动方式。

这是因为不同同学的开发环境可能不一样:有的人直接在 Windows 上操作,有的人在 WSL / Linux 环境下操作。PowerShell 命令主要面向 Windows 用户,Shell 命令主要面向 Linux 或 WSL 用户。

1. 进入项目目录

Windows PowerShell:

cd D:\OpsPilot\opspilot-fault-lab

Linux / WSL:

cd /mnt/d/OpsPilot/opspilot-fault-lab

2. 复制环境变量文件

Windows PowerShell:

Copy-Item .env.example .env

Linux / WSL:

cp .env.example .env

.env.example 是示例配置文件,真正运行时一般复制成 .env,再根据本地情况修改端口、数据库密码、webhook 地址等配置。

3. 检查 Compose 配置

docker compose config

这个命令不会真正启动容器,而是检查 docker-compose.yml.env 组合之后的最终配置是否正确。

如果这个命令能正常输出完整配置,说明 Compose 文件语法和变量替换基本没有问题。

4. 启动靶场

docker compose up -d --build

其中:

  • up 表示启动服务;

  • -d 表示后台运行;

  • --build 表示如果有需要构建的镜像,就重新构建。

5. 查看容器状态

docker compose ps

正常情况下,应该能够看到类似这些服务处于运行状态:

demo-api      running
postgres      running
prometheus    running
alertmanager  running

七、端口和服务地址的理解

在搭建过程中,我对“服务地址”这个概念也有了更具体的理解。

所谓服务地址,本质上就是“通过哪个地址访问哪个服务”。

在本地 Docker Compose 环境中,我们常见的访问方式有两种:

1. 宿主机访问容器服务

例如浏览器访问:

http://localhost:18080

表示从当前电脑访问映射到本机 18080 端口的服务。

类似地:

http://localhost:19090

可以访问 Prometheus。

http://localhost:19093

可以访问 Alertmanager。

这里的 localhost 指的是当前电脑本机。


2. 容器之间互相访问

容器之间访问时,一般不使用 localhost,而是使用 Compose 中定义的服务名。

例如 Prometheus 要抓取 demo-api 的指标,通常可以写:

targets:
  - "demo-api:8080"

这里的 demo-api 不是随便写的,而是 Docker Compose 中的服务名。Compose 会自动创建一个内部网络,让同一个 Compose 项目里的容器可以通过服务名互相访问。

这个地方非常容易混淆:

  • 在宿主机浏览器里访问,用 localhost:端口

  • 在容器内部访问另一个容器,用 服务名:容器内部端口

例如:

宿主机访问 demo-api:
http://localhost:18080

Prometheus 容器访问 demo-api:
http://demo-api:8080

这两个地址看起来不一样,但实际指向的是同一个服务,只是访问者不同。


八、webhook 地址为什么需要特别注意?

在 Alertmanager 配置中,有一个很关键的配置项:webhook 地址。

它表示 Alertmanager 触发告警后,要把告警数据发到哪里。

例如:

webhook_configs:
  - url: "http://host.docker.internal:8080/api/alerts/alertmanager"

这里的意思是:Alertmanager 容器内触发告警后,把告警 POST 到宿主机上的某个 OpsPilot 接口。

我一开始有一个疑问:既然 .env 里面已经写了 webhook 地址,为什么还要改 alertmanager.yml?是不是多此一举?

后来理解到,.env 文件对 Docker Compose 本身是有用的,但是 Alertmanager 的配置文件不一定会自动读取 .env 里的变量。也就是说,如果 alertmanager.yml 里面写死了 webhook 地址,而没有通过模板或启动参数显式注入环境变量,那么 .env 里的地址并不会自动生效。

因此现阶段更稳妥的做法是:

  1. .env 里保留项目级配置,方便统一管理;

  2. alertmanager.yml 里也要确认实际生效的 webhook 地址;

  3. 修改 Alertmanager 配置后,需要重启 Alertmanager 容器。

重启命令可以是:

docker compose restart alertmanager

这个问题让我意识到:配置文件是否使用环境变量,不是“看起来写了变量就一定生效”,而要看具体程序是否支持变量替换,以及 Compose 是否把变量传进去了。


九、目前已经完成的靶场能力

经过本阶段搭建,当前靶场已经具备了以下基础能力:

1. 多服务容器化启动

通过 Docker Compose 可以统一启动:

  • 模拟业务服务;

  • PostgreSQL 数据库;

  • Prometheus;

  • Alertmanager。

这说明基础运行环境已经具备可复现能力。


2. Prometheus 监控链路初步建立

Prometheus 可以作为监控中心,后续持续抓取业务服务指标,并根据告警规则判断异常。

这一步为后续 PromQL 查询工具和 Agent 指标分析模块提供了基础。


3. Alertmanager 告警转发链路准备完成

Alertmanager 已经作为告警管理组件接入系统,并预留 webhook 转发能力。

后续只要 OpsPilot 后端实现对应的 webhook 接收接口,就可以接收真实告警 payload。


4. 故障剧本目录初步建立

项目中准备了 runbookspayloadsreports 等目录,用来保存:

  • 故障处理手册;

  • 示例告警数据;

  • 事故复盘模板;

  • 后续自动化执行脚本。

这对后续 RAG 知识库和事故复盘功能很重要。


十、我对故障靶场价值的理解

在没有搭建这个靶场之前,我对智能运维 Agent 的理解更多停留在“让大模型分析告警”这个抽象层面。但真正开始搭建环境后,我发现智能运维不是简单把告警文本丢给大模型,而是要先解决一系列工程问题。

1. Agent 需要稳定的数据入口

如果没有 Prometheus 和 Alertmanager,Agent 就没有标准化的告警输入。

告警从哪里来、格式是什么、包含哪些标签、如何标识服务、如何知道触发时间,这些都需要监控系统提供。


2. 根因分析需要上下文

一个告警本身往往只能说明“某个指标超过阈值”,但不能直接说明为什么出问题。

例如:

接口错误率升高

它可能由很多原因导致:

  • 数据库连接失败;

  • 下游服务不可用;

  • 最近版本发布引入 bug;

  • 请求量突然升高;

  • 资源耗尽。

所以后续 Agent 不能只看单条告警,而要结合 PromQL 查询结果、日志、服务状态和知识库内容进行综合分析。


3. 故障场景必须可重复

如果每次故障都是偶然出现的,就很难调试 Agent 的分析流程。

靶场的意义就在于:我们可以反复制造相同类型的故障,观察系统是否每次都能稳定地产生告警、稳定地进入分析流程、稳定地输出合理结果。

这对于后续做系统测试和答辩演示都非常关键。


十一、遇到的问题和收获

1. Docker 环境问题

在搭建过程中,Docker 环境本身并不是天然可用的,需要先完成 Docker Engine 和 Docker Compose 的安装,并解决镜像拉取问题。

这让我认识到,项目开发中“环境搭建”本身就是工程工作的一部分。尤其是涉及容器、网络、镜像仓库时,很多问题不是代码逻辑错误,而是运行环境、网络访问或配置细节导致的。


2. Windows 和 Linux 命令差异

项目文档中同时提供 PowerShell 和 Shell 命令,刚开始看起来像是重复,但实际上是为了兼容不同开发环境。

例如复制文件:

Windows PowerShell:

Copy-Item .env.example .env

Linux Shell:

cp .env.example .env

它们做的是同一件事,只是运行环境不同。

这让我意识到,项目文档面向团队协作时,不能只考虑自己当前使用的系统,也要考虑其他成员的开发环境。


3. 配置文件不是越多越好,关键是要知道谁真正生效

.envdocker-compose.ymlprometheus.ymlalertmanager.yml 都是配置文件,但它们作用的对象不同。

简单理解:

.env
主要给 Docker Compose 提供变量

docker-compose.yml
定义有哪些服务、端口、挂载、依赖关系

prometheus.yml
定义 Prometheus 抓取谁、怎么抓取

alertmanager.yml
定义 Alertmanager 如何处理和转发告警

所以排查问题时,不能只看一个配置文件,而要知道当前问题属于哪一层。


十二、下一步计划

本阶段完成的是故障靶场的基础搭建。接下来需要继续推进以下工作:

1. 完成典型故障触发脚本

例如:

  • 模拟数据库断连;

  • 模拟接口错误率上升;

  • 模拟服务响应变慢;

  • 模拟日志快速增长。

这样后续就可以通过脚本一键触发故障。


2. 验证 Prometheus 告警规则

需要观察不同故障是否能触发对应告警,并检查告警标签、严重等级、描述信息是否合理。


3. 打通 Alertmanager 到 OpsPilot 后端的 webhook

后端需要实现告警接收接口,例如:

POST /api/alerts/alertmanager

接收到 Alertmanager 的告警 payload 后,系统要能够解析:

  • 告警名称;

  • 告警级别;

  • 触发服务;

  • 指标名称;

  • 当前值;

  • 阈值;

  • 开始时间;

  • 标签信息。


4. 开发 PromQL 查询工具

后续 Agent 不能只接收告警,还要能主动查询相关指标。例如告警提示接口错误率升高,Agent 应该继续查询:

  • 过去 5 分钟请求量;

  • 过去 5 分钟错误率;

  • P95 响应时间;

  • 服务是否存活;

  • 数据库连接是否正常。


5. 接入 Agent 分析流程

最终目标是让系统完成如下流程:

触发故障
    ↓
Prometheus 采集异常指标
    ↓
Prometheus 触发告警
    ↓
Alertmanager 转发告警
    ↓
OpsPilot 接收告警
    ↓
Agent 查询指标、日志、知识库
    ↓
生成根因分析和处置建议
    ↓
记录处置过程并生成复盘报告

十三、阶段总结

本阶段我主要完成了 OpsPilot 故障靶场的搭建和理解工作。通过 Docker Compose,我把模拟业务服务、数据库、Prometheus 和 Alertmanager 组织成了一个可以统一启动、统一测试、方便后续扩展的本地实验环境。

这项工作看起来偏基础,但它是整个智能运维 Agent 平台的前提。因为只有先有真实可观测的业务系统、可触发的故障场景、可查询的监控指标和可转发的告警数据,后续的大模型分析、RAG 检索、根因判断、自动化处置才有实际意义。

通过这次搭建,我对以下几个问题有了更清晰的认识:

  • Docker Compose 适合编排多服务实验环境;

  • Prometheus 负责采集指标和触发告警;

  • Alertmanager 负责告警管理和 webhook 转发;

  • 服务地址要区分宿主机访问和容器内部访问;

  • .env 不一定会自动影响所有配置文件;

  • 故障靶场是智能运维系统从“想法”走向“可验证工程系统”的关键一步。

后续我会在这个靶场基础上继续完成故障触发、告警规则验证、webhook 接入和 Agent 分析流程开发,逐步把 OpsPilot 从基础监控链路推进到真正的智能运维闭环。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐