Skip to content

Latest commit

 

History

History
407 lines (313 loc) · 12.5 KB

File metadata and controls

407 lines (313 loc) · 12.5 KB

CODEBUDDY.md

本文件为 CodeBuddy Code 在此代码仓库中工作时提供指导。

项目概述

K8M 是一款 AI 驱动的 Mini Kubernetes AI Dashboard 轻量级控制台工具,采用 Golang 后端和 AMIS 前端构建。它使用 kom 库作为 Kubernetes API 客户端,并拥有完整的插件系统以实现功能扩展。

开发命令

构建

# 为当前平台构建
make build

# 为所有平台构建(Linux、macOS、Windows、多种架构)
make build-all

# 仅构建 Linux 平台
make build-linux

# 构建 Docker 镜像
make docker

运行

# 使用 air 运行(热重载,推荐用于开发)
air

# 运行构建的二进制文件
./bin/k8m

# 以调试模式运行
./k8m -d -v 6 --print-config --enable-temp-admin

前端开发

# 构建前端(首次运行前必需)
cd ui
pnpm run build

# 开发模式(热重载)
cd ui
pnpm run dev
# 前端运行在 localhost:3000,代理后端到 3618

测试

# 运行所有测试
go test ./...

# 运行特定包的测试
go test ./pkg/comm/utils

# 以详细输出运行测试
go test -v ./...

# 运行特定测试
go test -v ./pkg/comm/utils -run TestRandIntOverflow

代码检查

# 检查前端代码
cd ui
pnpm run lint

架构

项目结构

k8m/
├── main.go                 # 应用程序入口点、路由设置、初始化
├── pkg/
│   ├── controller/         # HTTP 处理器,按资源类型组织
│   │   ├── admin/         # 仅管理员端点(集群、配置、用户、菜单)
│   │   ├── pod/           # Pod 相关端点(日志、执行、文件、指标)
│   │   ├── node/          # Node 相关端点
│   │   ├── deploy/        # Deployment 端点
│   │   └── ...            # 其他资源控制器
│   ├── plugins/           # 插件系统核心
│   │   ├── modules/       # 插件实现
│   │   ├── api/           # 插件能力抽象接口
│   │   └── readme.md      # 完整的插件架构文档
│   ├── service/           # 业务逻辑层
│   │   ├── clusters.go     # 集群管理(多集群支持)
│   │   └── ...            # 其他服务模块
│   ├── models/            # GORM 数据库模型
│   ├── middleware/        # HTTP 中间件(认证、集群选择)
│   └── response/          # 响应处理工具
├── internal/dao/          # 数据库访问层
├── ui/                    # 前端(React + AMIS)
│   └── package.json
└── docs/                  # 文档

关键架构模式

1. 插件系统

整个应用围绕插件架构构建。所有功能都以插件形式实现,具有完整的生命周期管理:

  • 插件类型:模块在编译时通过 Go 注册发现
  • 生命周期:安装 → 启用 → 启动 → 运行中 → 停止 → 禁用 → 卸载
  • 路由类型
    • ClusterRouter: /k8s/cluster/{cluster}/plugins/{name}/* - 集群特定操作
    • ManagementRouter: /mgm/plugins/{name}/* - 通用管理操作
    • PluginAdminRouter: /admin/plugins/{name}/* - 平台管理员操作
    • RootRouter: 根级路由(很少使用)
  • 依赖关系:插件声明强依赖(Dependencies)和启动顺序(RunAfter
  • 前端:所有插件使用 AMIS JSON 构建 UI(插件中不使用 React/Vue 代码)
  • 数据库:每个插件使用 GORM AutoMigrate 管理自己的表

插件目录结构

pkg/plugins/modules/{plugin-name}/
├── metadata.go          # 插件元信息和能力声明
├── lifecycle.go         # 生命周期接口实现
├── models/              # 数据库模型
│   ├── db.go           # Init/Upgrade/DropDB 函数
│   └── *.go            # 模型定义
├── route/               # 路由注册
│   ├── cluster_api.go  # 集群操作
│   ├── mgm_api.go      # 管理操作
│   └── admin_api.go    # 管理员操作
├── frontend/            # AMIS JSON 文件
├── controller/          # HTTP 处理器(可选)
└── service/             # 业务逻辑(可选)

关键:所有插件描述必须使用 Go 代码(不使用 YAML/JSON)。所有生命周期方法必须是幂等的。

2. 多集群管理

  • 集群服务 (pkg/service/clusters.go):管理多个 Kubernetes 集群
  • 注册方式
    • InCluster 模式:自动注册宿主集群
    • Kubeconfig 扫描:扫描目录中的配置文件
    • 数据库:存储已注册的集群
  • 上下文:集群 ID 通过 EnsureSelectedClusterMiddleware 注入到请求中

3. 分层架构

HTTP 请求
    ↓
中间件(认证、集群选择)
    ↓
控制器(pkg/controller/*)  # 路由处理器
    ↓
服务层(pkg/service/*)       # 业务逻辑
    ↓
Kom(Kubernetes 客户端)       # K8s API 调用
    ↓
数据库(GORM)                # 数据持久化

4. 响应处理

所有 HTTP 处理器使用 pkg/response.Context,提供:

  • JSON(status, obj) - JSON 响应
  • ShouldBindJSON(obj) - JSON 请求绑定
  • Param(key) - URL 参数
  • Query(key) - 查询参数
  • 响应上下文池以提高性能

5. 数据库抽象

  • ORM:支持 SQLite、MySQL、PostgreSQL 的 GORM
  • 迁移:每个插件通过 AutoMigrate 处理自己的模式
  • 访问internal/dao 包提供 dao.DB() 单例
  • 配置:参见 docs/database.md 了解数据库设置选项

前端架构

  • 框架:React 18 + AMIS(百度的低代码 UI 框架)
  • 构建:Vite + TypeScript
  • UI 库:AMIS JSON 模式(不是 React 组件)
  • 嵌入:前端通过 //go:embed 嵌入到 Go 二进制文件中
  • 开发:Vite 开发服务器运行在 3000 端口,代理 API 到 3618

Fetcher 封装

前端所有 HTTP 请求都通过 ui/src/components/Amis/fetcher.ts 封装。该 fetcher 是 AMIS 框架的标准接口。

核心功能

  1. 自动认证:从 localStorage 获取 token,自动添加 Authorization: Bearer ${token} 请求头

  2. 集群上下文注入

    • 自动处理集群 URL 重写
    • 支持通过 x-k8m-target-cluster 请求头或 __cluster 参数指定目标集群
    • 调用 ProcessK8sUrlWithCluster() 函数处理 K8s 集群相关 URL
  3. 错误处理

    • 401:自动跳转到登录页面(/#/login
    • 512:提示集群权限不足,跳转到集群用户管理页面
    • 403:提示权限不足
  4. 请求方法

    • GET:data 对象自动转换为查询参数
    • POST/PUT/DELETE:data 作为请求体
  5. 响应验证

    • 检查空响应或无效响应
    • 在开发模式下打印响应日志
    • 对 204、205、HEAD 请求跳过空数据检查

使用方式

fetcher 在 AMIS 渲染时自动配置(见 ui/src/components/Amis/index.tsx:148):

renderAmis(schema, initialData, {
    theme: 'cxd',
    fetcher,  // 注入自定义 fetcher
    isCancel: value => axios.isCancel(value),
})

在 AMIS Schema 中使用

AMIS 组件的 api 字段会自动使用这个 fetcher,例如:

{
  "type": "crud",
  "api": {
    "method": "get",
    "url": "/k8s/cluster/${cluster}/pods"
  },
  ...
}

fetcher 会自动:

  • 添加认证 token
  • 处理集群 URL 重写
  • 处理错误响应
  • 验证响应数据

重要规则(来自 .trae/rules/project_rules.md)

  1. 热重载:使用 air 进行代码热重载。您可以编译验证代码,但不要执行 k8m 命令。
  2. 登录凭据:测试时默认用户名/密码为 k8m/k8m
  3. 日志:使用中文打印日志消息。使用 klog.V(6).Infof 打印日志。
  4. 注释:可以添加或修改现有注释,但不要删除注释。如果需要删除,请标记为 [注释待删除](comment pending deletion)。

关键配置

环境变量

所有配置选项请参见 .env.example

  • PORT:服务器端口(默认:3618)
  • KUBECONFIG:kubeconfig 文件路径
  • OPENAI_API_KEYOPENAI_API_URLOPENAI_MODEL:AI 模型配置
  • IN_CLUSTER:启用 InCluster 模式
  • DB_DRIVER:数据库类型(sqlite/mysql/postgresql)
  • DEBUG:调试模式
  • LOG_V:klog 详细程度级别(默认:2)

数据库配置

支持 SQLite(开发默认)、MySQL、PostgreSQL。详细配置请参见 docs/database.md

启动流程

  1. 从标志/环境变量/数据库加载配置
  2. 使用内置模型初始化 AI 服务
  3. 注册 kom 回调
  4. 注册 InCluster 集群(如果启用)
  5. 从数据库和 kubeconfig 目录扫描并注册集群
  6. 连接集群(如果启用了 --connect-cluster
  7. 启动插件管理器(根据配置加载和启用插件)
  8. 构建并服务 HTTP 路由器

插件开发

创建新插件

  1. 创建目录:pkg/plugins/modules/{plugin-name}/
  2. metadata.go 中定义元数据,遵循 demo 插件结构
  3. lifecycle.go 中实现生命周期接口
  4. models/db.go 中添加模型,包含 InitDB()UpgradeDB()DropDB()
  5. route/*.go 中注册路由
  6. frontend/*.json 中添加前端 AMIS JSON
  7. pkg/plugins/modules/registrar/ 中注册插件

关键参考:完整的插件架构文档请参见 pkg/plugins/readme.md(857 行)。

插件生命周期方法

所有方法必须是幂等的:

  • Install(ctx):创建表、初始化数据
  • Upgrade(ctx):版本变更时迁移模式/数据
  • Enable(ctx):注册路由、暴露菜单
  • Disable(ctx):隐藏菜单、取消注册路由
  • Start(ctx):启动后台协程、订阅 EventBus
  • Stop(ctx):停止协程、清理资源
  • StartCron(ctx, spec):执行计划任务
  • Uninstall(ctx):删除表(或根据请求保留数据)

EventBus

插件可以订阅系统事件:

  • EventLeaderElected:当此实例成为 leader 时
  • EventLeaderLost:当此实例失去 leader 状态时
elect := ctx.Bus().Subscribe(eventbus.EventLeaderElected)
lost := ctx.Bus().Subscribe(eventbus.EventLeaderLost)

API 路由结构

完整的路由图请参见 docs/route_structure.md

  • /auth/*:认证(登录、SSO)
  • /k8s/cluster/{cluster}/*:集群特定操作
    • /plugins/{name}/*:插件集群操作
  • /mgm/*:管理操作
    • /plugins/{name}/*:插件管理操作
  • /admin/*:仅平台管理员
    • /plugins/{name}/*:插件管理员操作
  • /swagger/*:API 文档(如果启用了 swagger 插件)

测试

  • 测试文件位于:pkg/comm/utils/*_test.gopkg/plugins/modules/webhook/core/*_test.go
  • 使用 go test 运行测试
  • 测试应遵循 Go 惯例
  • 使用表驱动测试进行多用例测试

常见开发任务

添加新的 API 端点

  1. 在适当的 pkg/controller/* 包中添加控制器函数
  2. main.go buildRouter 函数中注册路由
  3. 使用 response.Adapter 包装处理器
  4. 使用 c.JSON() 返回响应
  5. 如果需要,添加文档(Swagger)

前端调用

  • 在 AMIS JSON 中使用 api 字段定义请求
  • fetcher 会自动处理认证、集群上下文、错误处理
  • GET 请求的查询参数通过 sendOn 配置发送

示例:

{
  "type": "crud",
  "api": {
    "method": "get",
    "url": "/k8s/cluster/${cluster}/pods",
    "data": {
      "namespace": "${selectedNs}"
    },
    "sendOn": "init"
  }
}

添加新的 Kubernetes 资源类型

  1. pkg/controller/{resource}/ 中创建控制器包
  2. 使用 kom 客户端实现 CRUD 操作
  3. main.go 中的 /k8s/cluster/{cluster}/ 下注册路由
  4. 为 UI 添加前端 AMIS JSON

调试

  • 使用 -d 标志启用调试模式
  • 使用 -v 6 获取详细日志
  • 使用 --print-config 查看启动时的配置
  • 使用 klog.V(6).Infof() 打印调试日志(仅中文)

插件能力 API

pkg/plugins/api 包提供抽象的插件能力:

  • AIChatService():AI 聊天功能
  • WebhookService():Webhook 发送
  • 其他能力可以按模式添加

这使用 No-Op 模式:调用未注册的能力返回安全的无操作实现。

重要提示

  • 运行前必须构建前端:cd ui && pnpm run build
  • 嵌入式前端从 ui/dist/ 加载
  • Air 配置在 .air.toml
  • Air 监视 .go 文件,排除 bin/vendor/ui/images/
  • 生产构建使用 make build
  • 所有插件操作必须使用带 dao.DB() 的 GORM
  • 集群上下文通过中间件在集群路由中可用
  • 所有面向用户的消息和日志使用中文
  • 永远不要删除现有注释而不标记它们