dev_1.0.0_yuyr_2:重新提交 PR,增加 master/agent 以及系统集成测试 #17
@ -1,39 +1,53 @@
|
|||||||
# Argus Agent Module
|
# Argus Agent 模块
|
||||||
|
|
||||||
Python agent that registers with the Argus master service, persists node information, gathers host metadata, reads module health files, and periodically reports status.
|
Argus Agent 是一个轻量级 Python 进程,负责向 Argus Master 注册节点、汇报健康数据,并维护本地持久化信息。模块现以 PyInstaller 打包为独立可执行文件,便于在普通容器或虚机中直接运行。
|
||||||
|
|
||||||
## Build & Run
|
## 构建可执行文件
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd src/agent
|
cd src/agent
|
||||||
./scripts/build_binary.sh # produces dist/argus-agent
|
./scripts/build_binary.sh # 生成 dist/argus-agent
|
||||||
```
|
```
|
||||||
|
|
||||||
The resulting executable (`dist/argus-agent`) bundles the runtime via PyInstaller. Runtime configuration is now derived from environment variables and the container hostname—no local config file is required.
|
脚本会在本地创建虚拟环境、通过 `pyproject.toml` 安装依赖,并调用 PyInstaller 产出单文件可执行程序。构建过程中生成的 `build/`、`dist/` 会被 `.gitignore` 忽略。
|
||||||
|
|
||||||
Required variables:
|
## 运行时配置
|
||||||
|
|
||||||
- `MASTER_ENDPOINT`:Master 服务的完整地址,若未带协议会自动补全为 `http://`。
|
Agent 不再依赖配置文件;所有参数均由环境变量与主机名推导:
|
||||||
- `REPORT_INTERVAL_SECONDS`:状态上报周期,可选,默认 60。
|
|
||||||
|
|
||||||
Additional overrides:
|
| 变量 | 必填 | 默认值 | 说明 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `MASTER_ENDPOINT` | 是 | N/A | Master 基础地址,可写 `http://host:3000` 或 `host:3000`(自动补全 `http://`)。 |
|
||||||
|
| `REPORT_INTERVAL_SECONDS` | 否 | `60` | 状态上报间隔(秒)。必须为正整数。 |
|
||||||
|
| `AGENT_HOSTNAME` | 否 | `$(hostname)` | 覆盖容器内主机名,便于测试或特殊命名需求。 |
|
||||||
|
|
||||||
- `AGENT_HOSTNAME`:可选,若需要覆盖容器 `hostname`。
|
派生路径:
|
||||||
|
|
||||||
At startup the agent会读取容器主机名(或 `AGENT_HOSTNAME` 覆盖值)并固定以下路径:
|
- 节点信息:`/private/argus/agent/<hostname>/node.json`
|
||||||
|
|
||||||
- 节点状态持久化:`/private/argus/agent/<hostname>/node.json`
|
|
||||||
- 子模块健康目录:`/private/argus/agent/health/<hostname>/`
|
- 子模块健康目录:`/private/argus/agent/health/<hostname>/`
|
||||||
|
|
||||||
健康文件需按 `<模块名前缀>-*.json` 命名,例如 `log-fluentbit.json`,文件内容会以文件名前缀为键写入上报 payload。
|
健康目录中的文件需遵循 `<模块前缀>-*.json` 命名(例如 `log-fluentbit.json`、`metric-node-exporter.json`),文件内容会原样并入上报的 `health` 字段。
|
||||||
|
|
||||||
## Tests
|
## 日志与持久化
|
||||||
|
|
||||||
Docker 端到端测试会启动 master 容器与一个普通 `ubuntu:24.04` 容器,在其中挂载并执行打包后的 agent(通过环境变量注入 `MASTER_ENDPOINT` 与 `REPORT_INTERVAL_SECONDS`):
|
- Agent 会在成功注册、状态上报、异常重试等关键节点输出结构化日志,便于聚合分析。
|
||||||
|
- `node.json` 保存 Master 返回的最新节点对象,用于重启后继续使用既有节点 ID。
|
||||||
|
|
||||||
|
## 端到端测试
|
||||||
|
|
||||||
|
仓库内提供 Docker Compose 测试栈(master + ubuntu 容器):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd src/agent/tests
|
cd src/agent/tests
|
||||||
./scripts/00_e2e_test.sh
|
./scripts/00_e2e_test.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
测试脚本会自动调用 `../scripts/build_binary.sh` 生成可执行文件,并在 `tests/private/` 下准备配置与健康目录,最后通过 `07_down.sh` 清理环境。
|
测试脚本会:
|
||||||
|
|
||||||
|
1. 构建 master 镜像与 agent 可执行文件。
|
||||||
|
2. 以 `ubuntu:24.04` 启动 agent 容器,并通过环境变量注入 `MASTER_ENDPOINT`、`REPORT_INTERVAL_SECONDS`。
|
||||||
|
3. 验证注册、健康上报、nodes.json 生成、统计接口,以及“容器重启 + IP 变化”重注册流程。
|
||||||
|
4. 清理 `tests/private/` 与临时容器网络。
|
||||||
|
|
||||||
|
如需在真实环境部署,只需将 `dist/argus-agent` 连同健康目录挂载到目标主机,并按上表设置环境变量即可。
|
||||||
|
|
||||||
|
@ -1,48 +1,149 @@
|
|||||||
# Argus Master Module
|
# Argus Master 模块
|
||||||
|
|
||||||
A lightweight Flask + SQLite service that manages Argus agent nodes. It exposes node registration, status updates, configuration management, statistics, and generates `nodes.json` for the metric module.
|
Argus Master 是基于 Flask + SQLite 的节点管理服务,负责:
|
||||||
|
|
||||||
## Build & Run
|
- 接收 agent 的注册与重注册请求,分配/校验节点 ID。
|
||||||
|
- 存储节点元数据、配置、健康状态,并根据上报时间计算在线状态。
|
||||||
|
- 输出仅包含在线节点的 `nodes.json`,供其他模块(如 metric)消费。
|
||||||
|
- 提供查询、配置更新、统计等 REST API。
|
||||||
|
|
||||||
|
## 构建与运行
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd src/master
|
cd src/master
|
||||||
./scripts/build_images.sh # builds argus-master:dev
|
./scripts/build_images.sh # 生成 argus-master:dev 镜像
|
||||||
```
|
```
|
||||||
|
|
||||||
Local run via Docker compose (test stack):
|
本仓库提供的端到端测试会使用 `src/master/tests/docker-compose.yml` 启动示例环境:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd src/master/tests
|
cd src/master/tests
|
||||||
./scripts/01_up_master.sh
|
./scripts/01_up_master.sh # 构建镜像并启动容器,监听 http://localhost:31300
|
||||||
```
|
```
|
||||||
|
|
||||||
Service listens on port `3000` (`31300` when using the provided test compose). Key environment variables:
|
服务日志与数据默认写入 `tests/private/argus/master/`(或自定义的挂载目录)。
|
||||||
|
|
||||||
- `DB_PATH` (default `/private/argus/master/db.sqlite3`)
|
## 运行时环境变量
|
||||||
- `METRIC_NODES_JSON_PATH` (default `/private/argus/metric/prometheus/nodes.json`)
|
|
||||||
- `OFFLINE_THRESHOLD_SECONDS`, `ONLINE_THRESHOLD_SECONDS`, `SCHEDULER_INTERVAL_SECONDS`
|
|
||||||
|
|
||||||
## REST API Summary
|
| 变量 | 默认值 | 说明 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `DB_PATH` | `/private/argus/master/db.sqlite3` | SQLite 数据库存放路径。目录会在启动时自动创建。 |
|
||||||
|
| `METRIC_NODES_JSON_PATH` | `/private/argus/metric/prometheus/nodes.json` | `nodes.json` 输出位置,仅包含在线节点。采用原子写入避免部分文件。 |
|
||||||
|
| `OFFLINE_THRESHOLD_SECONDS` | `180` | 若距离最近一次上报时间超过该值,调度器会将节点标记为 `offline`。 |
|
||||||
|
| `ONLINE_THRESHOLD_SECONDS` | `120` | 若最新上报时间距当前不超过该值,则标记为 `online`。范围处于两个阈值之间时保持原状态。 |
|
||||||
|
| `SCHEDULER_INTERVAL_SECONDS` | `30` | 调度器检查节点状态与刷新 `nodes.json` 的周期。 |
|
||||||
|
| `NODE_ID_PREFIX` | `A` | 新节点 ID 的前缀,实际 ID 形如 `A1`、`A2`。 |
|
||||||
|
| `AUTH_MODE` | `disabled` | 预留的认证开关,当前固定为禁用。 |
|
||||||
|
|
||||||
Base path: `/api/v1/master`
|
## REST API 详解
|
||||||
|
|
||||||
- `GET /nodes` — list node summaries
|
基础路径:`/api/v1/master`,全部返回 JSON。
|
||||||
- `GET /nodes/{id}` — node detail
|
|
||||||
- `POST /nodes` — register/re-register
|
|
||||||
- `PUT /nodes/{id}/status` — status report (timestamp + health map)
|
|
||||||
- `PUT /nodes/{id}/config` — update config/labels (partial)
|
|
||||||
- `GET /nodes/statistics` — totals + grouped counts
|
|
||||||
- `GET /healthz`, `GET /readyz` — health checks
|
|
||||||
|
|
||||||
`nodes.json` only contains nodes whose status is `online`.
|
### 1. `GET /nodes`
|
||||||
|
- **用途**:获取所有节点的简要信息。
|
||||||
## Tests
|
- **响应示例**:
|
||||||
|
```json
|
||||||
End-to-end tests are Docker based:
|
[
|
||||||
|
{"id": "A1", "name": "dev-user-inst-pod-0", "status": "online", "type": "agent", "version": "1.1.0"}
|
||||||
```bash
|
]
|
||||||
cd src/master/tests
|
|
||||||
./scripts/00_e2e_test.sh
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Scripts create temporary `private/` and `tmp/` directories under `tests/`; they are cleaned automatically by `06_down.sh`.
|
### 2. `GET /nodes/{id}`
|
||||||
|
- **用途**:获取节点详情(包含配置、健康、持久化时间戳等)。
|
||||||
|
- **错误**:`404` 表示节点不存在。
|
||||||
|
|
||||||
|
### 3. `POST /nodes`
|
||||||
|
- **用途**:注册或重注册节点。
|
||||||
|
- **请求体**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "A1", // 可选,重注册时携带
|
||||||
|
"name": "dev-user-inst-pod-0",
|
||||||
|
"type": "agent",
|
||||||
|
"version": "1.1.0",
|
||||||
|
"meta_data": {
|
||||||
|
"hostname": "dev-user-inst-pod-0",
|
||||||
|
"ip": "10.0.0.10",
|
||||||
|
"env": "dev",
|
||||||
|
"user": "testuser",
|
||||||
|
"instance": "testinst",
|
||||||
|
"cpu_number": 4,
|
||||||
|
"memory_in_bytes": 2147483648,
|
||||||
|
"gpu_number": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **成功返回**:
|
||||||
|
- 新节点:`201 Created`,返回完整节点对象。
|
||||||
|
- 重注册:`200 OK`,返回更新后的节点对象。
|
||||||
|
- **错误情况**:
|
||||||
|
- `404 Not Found`:携带的 ID 在 Master 中不存在。
|
||||||
|
- `500 Internal Server Error`:携带的 ID 与已有名称不匹配。
|
||||||
|
- `400 Bad Request`:请求体缺字段或类型不正确。
|
||||||
|
|
||||||
|
### 4. `PUT /nodes/{id}/status`
|
||||||
|
- **用途**:Agent 上报状态。Master 记录 `last_report`(服务器时间)与 `agent_last_report`(上报内时间),并更新 `health` 字段。
|
||||||
|
- **请求体示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"timestamp": "2025-09-24T03:24:59Z",
|
||||||
|
"health": {
|
||||||
|
"log-fluentbit": {"status": "healthy"},
|
||||||
|
"metric-node-exporter": {"status": "healthy"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **响应**:`200 OK`,返回最新节点对象。`404` 表示节点不存在。
|
||||||
|
|
||||||
|
### 5. `PUT /nodes/{id}/config`
|
||||||
|
- **用途**:局部更新节点配置与标签。
|
||||||
|
- **请求体示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"config": {"log_level": "debug"},
|
||||||
|
"label": ["gpu", "exp001"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **说明**:字段可任选其一;未提供的配置保持原值。更新标签会触发 `nodes.json` 重新生成。
|
||||||
|
- **错误**:`404` 表示节点不存在;`400` 表示请求体不合法。
|
||||||
|
|
||||||
|
### 6. `GET /nodes/statistics`
|
||||||
|
- **用途**:统计节点总数及按状态分布。
|
||||||
|
- **响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"total": 2,
|
||||||
|
"status_statistics": [
|
||||||
|
{"status": "online", "count": 1},
|
||||||
|
{"status": "offline", "count": 1}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7. 健康探针
|
||||||
|
- `GET /healthz`:进程存活检查。
|
||||||
|
- `GET /readyz`:数据库可用性检查(会尝试访问 `DB_PATH`)。
|
||||||
|
|
||||||
|
## 端到端测试场景
|
||||||
|
|
||||||
|
执行 `src/master/tests/scripts/00_e2e_test.sh` 会串联以下用例(脚本 01–10):
|
||||||
|
|
||||||
|
1. **01_up_master**:构建镜像、启动容器、初始化目录与卷。
|
||||||
|
2. **02_verify_ready_and_nodes_json**:轮询 `/readyz`,校验初始 `nodes.json` 为 `[]`。
|
||||||
|
3. **03_register_via_curl**:模拟 agent 注册,保存返回的节点 ID,并确认节点出现在列表接口中。
|
||||||
|
4. **04_reregister_and_error_cases**:覆盖重注册成功、携带未知 ID 的 `404`、ID/名称不匹配触发 `500` 等场景。
|
||||||
|
5. **05_status_report_via_curl**:上报健康信息并验证状态自动从 `initialized`→`online`→`offline`→`online` 的转换。
|
||||||
|
6. **06_config_update_and_nodes_json**:更新配置/标签,检查 `nodes.json` 中的标签同步,并确保离线节点不会出现在文件里。
|
||||||
|
7. **07_stats_single_node**:等待节点掉线,验证统计接口与 `nodes.json` 为空列表。
|
||||||
|
8. **08_multi_node_stats**:注册第二节点,使一在线一离线,校验统计聚合和 `nodes.json` 仅包含在线节点。
|
||||||
|
9. **09_restart_persistence**:重启 master 容器,确认节点数据、统计结果与 `nodes.json` 在持久化目录中保持不变。
|
||||||
|
10. **10_down**:停止并清理容器、网络与临时目录。
|
||||||
|
|
||||||
|
## 相关持久化文件
|
||||||
|
|
||||||
|
- SQLite:默认位于 `DB_PATH`,包含 `nodes` 与 `kv` 两张表。
|
||||||
|
- `nodes.json`:由调度器周期生成,仅保留状态为 `online` 的节点信息。
|
||||||
|
- 测试用例中的 `tests/private/`、`tests/tmp/` 会随脚本自动清理,避免污染后续运行。
|
||||||
|
|
||||||
|
如需在生产环境运行,可将镜像推送到私有仓库,或参考测试 Compose 配置自行部署;只需确保上述环境变量在容器内正确设置即可。
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user