Files
aiops/CLAUDE.md
T
attacker 69df073d42 chore: 隐藏.hermes目录、删除docker-compose.embed.yml、优化CLAUDE.md和README.md
- .gitignore 新增 .hermes/ 目录,git rm --cached 已追踪的 plan 文件
- 删除 docker-compose.embed.yml(embed 部署统一走 K8s 或独立二进制)
- Makefile 移除 docker-embed 目标
- CLAUDE.md 全面重写:三种部署方式详解、技术栈修正(Go1.24+MySQL/Redis)、架构完善、新增工具懒加载/凭证v2/远程执行/流水线/PTY终端等章节
- README.md 重写:三种部署快速开始、项目结构对齐实际目录、核心功能更新
2026-06-22 17:19:54 +00:00

342 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md — AIOps
本文档为 Claude Code / Hermes 等 AI 编程助手提供在代码库中工作的指导说明。
> 作者:Logan.Li
> 语言:中文(代码注释和文档主要使用中文,注释署名 `// Logan.Li`)
## 项目概述
**AIOps** 是一个企业级智能运维平台,聚焦三大核心能力:
1. **资产管理** — 服务器管理、云资源(云账号/域名/账单)、K8s 集群
2. **监控告警** — Agent 采集指标、告警引擎(资源阈值/离线检测)、告警中心、链路追踪、监控大屏
3. **自动化运维 / AIOps** — 流水线 CI/CD、定时任务/脚本库、远程执行(Go-native SSH)、资源申请审批、AI 智能运维(智能助手/告警分析/容量预测)
### 核心特性
- **Agent 双通道** — 指标采集通道(10s 上报 `/proc`)+ 远程任务通道(5s 轮询执行命令)
- **LDAP 集成** — 配置管理、用户导入、OU 管理、LDAP 用户 CRUD
- **资源申请审批** — 云服务器申请、应用部署申请,动态表单
- **5 套主题** — CSS 变量驱动,暗色/亮色/紫色/绿色/玫红一键切换
- **WebShell** — WebSocket 终端,在线 SSH 操作服务器
- **凭证系统 v2** — 7 种统一凭证类型(SSH/Docker/TLS/AKSK/DB/API/Generic),加密存储
- **CI/CD 流水线** — GitLab CI 风格可视化,阶段色块进度条,实时日志,文件浏览器
- **Kubectl 终端** — WebSocket + PTY 交互式 K8s 终端,懒加载 kubectl 二进制
## 技术栈
| 层 | 技术 | 端口 |
|---|---|---|
| 后端 | Go 1.24 + Gin + GORM + MySQL 8.0 + Redis 7 + JWT + Zap | 8080 |
| 前端 | React 19 + TypeScript + Vite + Tailwind + shadcn/ui + Zustand + TanStack Query | 5173 |
| Agent | Go 1.24 (CGO_ENABLED=0 静态二进制, amd64+arm64) | — |
## 三种部署方式
项目通过统一入口 `./run.sh` 支持三种部署方式,适配不同场景:
### 方式一:独立二进制(`./run.sh build` / `./run.sh binary`)
前端通过 `go:embed` 嵌入后端二进制,生成单一可执行文件。零外部依赖,直接运行。
```bash
./run.sh build # 编译独立二进制 → backend/aiops
./run.sh binary # 编译 + 直接启动
./run.sh build agent # 交叉编译 Agent (amd64+arm64)
```
**二进制用法:**
```bash
./backend/aiops # 默认启动 (SQLite, 端口 8080)
./backend/aiops --port 9090 # 自定义端口
./backend/aiops --db-driver mysql --db-host 10.10.10.75 ... # MySQL 模式(需 --redis-driver redis)
./backend/aiops --config config.yaml # 使用配置文件
```
> ⚠️ MySQL 模式必须显式传 `--redis-driver redis`,否则默认 redka(CGO 依赖)在 `CGO_ENABLED=0` 下静默失败。
### 方式二:Kubernetes(`./run.sh k8s deploy`)
在 K8s 集群 `devops` 命名空间部署,单容器 embed 模式,NodePort 30080 暴露。
```bash
./run.sh k8s deploy # 构建 Dockerfile.embed 镜像 + 全量部署 (MySQL+Redis+App)
./run.sh k8s upgrade # 重新构建 + 滚动更新(不停机)
./run.sh k8s status # 查看 pods/svc/pvc/ingress
./run.sh k8s logs # 应用日志 (follow)
./run.sh k8s exec # 进入容器 Shell
./run.sh k8s mysql # MySQL CLI
./run.sh k8s redis # Redis CLI
./run.sh k8s scale 3 # 扩缩容
./run.sh k8s port-forward # 端口转发 localhost:8080 → svc/aiops
./run.sh k8s delete # 清理资源(保留 PVC)
```
**K8s 部署文件** (`deploy/k8s/`): namespace.yaml / secret.yaml / configmap.yaml / mysql.yaml / redis.yaml / deployment.yaml / ingress.yaml
> ⚠️ 健康检查用 `/version`(无 DB 依赖),不用 `/health`(启动早期可能不响应)。
### 方式三:Docker Compose(`./run.sh docker up`)
传统 4 容器部署:`aiops-mysql` + `aiops-redis` + `aiops-backend` + `aiops-frontend` (nginx)。
```bash
./run.sh docker up # 构建 + 启动全部容器
./run.sh docker down # 停止 + 移除容器
./run.sh docker build # 仅构建镜像
./run.sh docker restart # 重启容器
./run.sh docker logs # 实时日志
./run.sh docker ps # 容器状态
./run.sh docker clean # 清理构建缓存
```
**容器清单:**
| 容器 | 镜像 | 端口 | 说明 |
|------|------|------|------|
| `aiops-mysql` | `mysql:8.0` | 3306 | 数据库 |
| `aiops-redis` | `redis:7-alpine` | 6379 | 缓存 |
| `aiops-backend` | `backend/Dockerfile` (3-stage) | 8080 | Go API |
| `aiops-frontend` | `frontend/Dockerfile` (nginx:alpine) | 80 | React SPA |
### 本地开发(`./run.sh dev`)
```bash
./run.sh dev # 前后端热重载 (5173 + 8080)
./run.sh stop # 停止
./run.sh restart # 重启
./run.sh status # 查看状态
./run.sh logs # 实时日志
```
## 常用命令
### 后端 (backend/)
```bash
cd backend
# 编译
unset http_proxy https_proxy && export GOPROXY=https://goproxy.cn,direct && GOTOOLCHAIN=local CGO_ENABLED=1 go build -o aiops-server ./cmd/
# 直接运行
go run ./cmd/
# 代码检查
go vet ./...
```
### 前端 (frontend/)
```bash
cd frontend
npm run dev # 开发服务器 (端口 5173)
npm run build # 生产构建
npx tsc --noEmit # 类型检查(提交前必须零错误)
```
### Agent (agent/)
```bash
cd agent
# 本地构建
CGO_ENABLED=0 go build -o aiops-agent .
# 交叉编译
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o aiops-agent-linux-amd64 .
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o aiops-agent-linux-arm64 .
# 运行
./aiops-agent --server http://localhost:8080 --token <JWT_TOKEN>
```
## 架构说明
### 项目结构
```
aiops/
├── backend/
│ ├── cmd/
│ │ ├── main.go # 应用入口
│ │ ├── embed.go # go:embed 前端静态资源
│ │ ├── seed.go # 种子数据
│ │ └── static/ # embed 目标目录 (必须存在)
│ ├── internal/
│ │ ├── config/config.go # Viper 配置
│ │ ├── models/ # GORM 模型
│ │ └── api/
│ │ ├── handlers/ # HTTP handler
│ │ ├── middleware/ # JWT + Admin + PipelineAccess
│ │ └── routes/ # 路由注册
│ ├── pkg/
│ │ ├── database/ # DB 连接 + AutoMigrate
│ │ ├── kubernetesclient/ # 轻量 K8s API 客户端
│ │ ├── remoteexec/ # Go-native SSH 远程执行
│ │ └── toolinstaller/ # 工具懒加载 + 镜像回退
│ └── Dockerfile # 3 阶段构建 (Backend+Agent→Alpine Runtime)
│
├── frontend/
│ ├── src/components/
│ │ ├── dashboard/ # 仪表盘
│ │ ├── server/ # 服务器管理
│ │ ├── cloud/ # 云资源
│ │ ├── k8s/ # K8s 集群管理
│ │ ├── deploy/ # 应用发布(流水线/发布配置/发布权限/工具配置)
│ │ ├── monitor/ # 监控告警
│ │ ├── automation/ # 定时任务/脚本库/远程执行
│ │ ├── approval/ # 资源申请审批
│ │ ├── aiops/ # AI 智能运维(助手/告警分析/容量预测)
│ │ ├── system/ # 系统管理
│ │ └── layout/ # Sidebar/Header
│ ├── src/services/
│ │ ├── api.ts # API 定义
│ │ └── http.ts # http 封装(自动解包 data + Token 注入)
│ └── Dockerfile # Node build → nginx:alpine
│
├── agent/ # 监控 Agent(独立 Go module)
│ ├── collector/ # /proc 采集器
│ ├── task/ # 远程任务执行器
│ └── reporter/ # HTTP 上报
│
├── deploy/k8s/ # K8s 部署清单 (devops 命名空间)
├── Dockerfile.embed # 4 阶段 Embed 镜像 (前端→后端→Agent→Runtime)
├── docker-compose.yml # 4 容器部署 (mysql+redis+backend+frontend)
├── run.sh # 统一入口脚本
└── Makefile # 快捷命令
```
### API 响应格式
```go
// 统一响应
type Response struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data"`
}
// 列表响应
type ListResponse struct {
List interface{} `json:"list"`
Total int64 `json:"total"`
}
```
**前端 http.ts 已自动提取 `.data`**,组件中拿到的就是 `Response.Data`。列表返回 `{list, total}`。
### 认证流程
```
Login(本地/LDAP fallback) → JWT Token → 前端 Zustand persist + localStorage 双写
→ http.ts 自动注入 Bearer → JWTAuth 中间件 → AdminAuth 中间件(管理类路由)
```
WebSocket 无法设自定义 header → 后端 JWTAuth 支持 `?token=` query param 回退。
### Agent 双通道架构
```
指标通道: ticker(10s) → collect(/proc) → POST /agent/report
任务通道: ticker(5s) → GET /agent/tasks/poll → execute → POST /agent/tasks/:id/result
```
## 开发规范
### ⛔ 文件大小红线
| 类型 | 上限 | 超出处理 |
|------|------|----------|
| Go handler | **400 行** | 按 sub-domain 拆分 |
| Go model | **300 行** | 按模块拆分 |
| React 组件 (.tsx) | **700 行** | 提取子组件 |
| 任何文件 | **700 行(硬上限)** | 必须拆分 |
### ⛔ Go 代码规范
1. **所有 handler 返回必须用 `models.Response{Code:200, Data:...}` 包裹**
2. **编译命令**: `unset proxy + GOPROXY=goproxy.cn + GOTOOLCHAIN=local + CGO_ENABLED=1`
3. **新增 handler 不绑 model** — 用独立 request struct
4. **GORM 指针字段必须解引用** — `*field` 后再用
5. **Update handler 禁止复用 CreateRequest** — 用 `map[string]interface{}` 接收
### ⛔ React 前端规范
1. **API 列表响应解包** — `http.ts` 自动取 `.data`,列表返回 `{list, total}`
2. **禁止 `window.confirm()`/`alert()`** — 用 `useConfirm()` + `toast`
3. **Radix Dialog 必须有 `<DialogDescription>`**
4. **Token 双保险**: `useUserStore.getState().token || localStorage.getItem('token')`
### ⛔ UI 设计原则
- **能去掉的都去掉** — 不要多余边框、装饰线
- **按钮文案 2-4 字** — "批量导入" 而非 "批量导入用户"
- **不留占位按钮** — 功能没做好就不放按钮
- **页面打开即用** — 不需要额外"新建"按钮跳转
- **主题感知** — 用 CSS 变量 `var(--dg-xxx)`,不硬编码颜色
### ⛔ 通用开发流程
```
分析需求 → 写代码 → go build + tsc --noEmit → ./run.sh docker up → curl 验证 → git commit + push
```
- **代码改完不算完成,端到端验证通过才算完成**
- **大变更前先 git commit** — 方便回滚
## 默认账号
| 用户名 | 密码 | 角色 |
|--------|------|------|
| admin | 123456 | 超级管理员 |
| ops01 | 123456 | 运维 |
| dev01 | 123456 | 开发 |
| logan | zxc987 | LDAP 用户 |
⚠️ **生产环境请修改默认密码**
## 访问地址
- 前端:`http://localhost:5173` (dev) / `http://localhost:80` (docker)
- 后端:`http://localhost:8080`
- 健康检查:`http://localhost:8080/health`
- K8s:`http://<NODE_IP>:30080`
## 常见陷阱速查
| # | 陷阱 | 解决 |
|---|------|------|
| Go1 | go build 超时 | `unset proxy + GOPROXY=goproxy.cn + GOTOOLCHAIN=local` |
| Go2 | handler 不包裹 Response | 必须 `models.Response{Code:200, Data:...}` |
| Go3 | GORM 指针字段 | `*field` 解引用后再用 |
| Go4 | Update 复用 CreateRequest | 用 `map[string]interface{}` |
| Go5 | CGO_ENABLED=0 + redka → 缓存静默失败 | `--redis-driver redis` |
| FE1 | 白屏无堆栈 | 90% 是列表 `{list,total}` 未解包 |
| FE2 | confirm() 冻结自动化 | 用 `useConfirm()` |
| FE3 | Token 获取 | `useUserStore.getState().token` + `localStorage` |
| FE4 | Radix Dialog 警告 | 必须有 `<DialogDescription>` |
| FE5 | Select.Item 空字符串 value | 用 sentinel 值 `__manual` |
| FE6 | API 字段名不匹配 | 检查前后端命名一致性 |
## 注释规范
新增或修改代码必须写中文注释,注释结尾署名 `// Logan.Li`。
## 远程仓库
```
https://gitee.com/attacker/aiops.git
Git 用户: attacker / attacker@gitee.com
分支: main
```
## 关键设计决策
- **凭证驱动管理** — 不在表单手动输入密码/密钥,用凭证下拉关联(7 种类型统一模型)
- **工具懒加载** — kubectl/maven/nodejs/helm 首次使用时自动下载,国内网络自动优先国内镜像
- **远程执行** — Ansible 已替换为 Go-native SSH(`pkg/remoteexec/`),零新增依赖
- **K8s 客户端** — 轻量自研(net/http + crypto/tls),不引入 50MB+ 的 client-go
- **BuildKit cache mount** — Docker 构建从 13min 降至 3sec(二次构建)
- **健康检查用 `/version`** — K8s 中 `/health` 可能依赖 DB,`/version` 始终 200