本文件为 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 lintk8m/
├── 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/ # 文档
整个应用围绕插件架构构建。所有功能都以插件形式实现,具有完整的生命周期管理:
- 插件类型:模块在编译时通过 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)。所有生命周期方法必须是幂等的。
- 集群服务 (
pkg/service/clusters.go):管理多个 Kubernetes 集群 - 注册方式:
- InCluster 模式:自动注册宿主集群
- Kubeconfig 扫描:扫描目录中的配置文件
- 数据库:存储已注册的集群
- 上下文:集群 ID 通过
EnsureSelectedClusterMiddleware注入到请求中
HTTP 请求
↓
中间件(认证、集群选择)
↓
控制器(pkg/controller/*) # 路由处理器
↓
服务层(pkg/service/*) # 业务逻辑
↓
Kom(Kubernetes 客户端) # K8s API 调用
↓
数据库(GORM) # 数据持久化
所有 HTTP 处理器使用 pkg/response.Context,提供:
JSON(status, obj)- JSON 响应ShouldBindJSON(obj)- JSON 请求绑定Param(key)- URL 参数Query(key)- 查询参数- 响应上下文池以提高性能
- 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
前端所有 HTTP 请求都通过 ui/src/components/Amis/fetcher.ts 封装。该 fetcher 是 AMIS 框架的标准接口。
核心功能:
-
自动认证:从 localStorage 获取 token,自动添加
Authorization: Bearer ${token}请求头 -
集群上下文注入:
- 自动处理集群 URL 重写
- 支持通过
x-k8m-target-cluster请求头或__cluster参数指定目标集群 - 调用
ProcessK8sUrlWithCluster()函数处理 K8s 集群相关 URL
-
错误处理:
- 401:自动跳转到登录页面(
/#/login) - 512:提示集群权限不足,跳转到集群用户管理页面
- 403:提示权限不足
- 401:自动跳转到登录页面(
-
请求方法:
- GET:data 对象自动转换为查询参数
- POST/PUT/DELETE:data 作为请求体
-
响应验证:
- 检查空响应或无效响应
- 在开发模式下打印响应日志
- 对 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 重写
- 处理错误响应
- 验证响应数据
- 热重载:使用
air进行代码热重载。您可以编译验证代码,但不要执行k8m命令。 - 登录凭据:测试时默认用户名/密码为
k8m/k8m。 - 日志:使用中文打印日志消息。使用
klog.V(6).Infof打印日志。 - 注释:可以添加或修改现有注释,但不要删除注释。如果需要删除,请标记为
[注释待删除](comment pending deletion)。
所有配置选项请参见 .env.example:
PORT:服务器端口(默认:3618)KUBECONFIG:kubeconfig 文件路径OPENAI_API_KEY、OPENAI_API_URL、OPENAI_MODEL:AI 模型配置IN_CLUSTER:启用 InCluster 模式DB_DRIVER:数据库类型(sqlite/mysql/postgresql)DEBUG:调试模式LOG_V:klog 详细程度级别(默认:2)
支持 SQLite(开发默认)、MySQL、PostgreSQL。详细配置请参见 docs/database.md。
- 从标志/环境变量/数据库加载配置
- 使用内置模型初始化 AI 服务
- 注册 kom 回调
- 注册 InCluster 集群(如果启用)
- 从数据库和 kubeconfig 目录扫描并注册集群
- 连接集群(如果启用了
--connect-cluster) - 启动插件管理器(根据配置加载和启用插件)
- 构建并服务 HTTP 路由器
- 创建目录:
pkg/plugins/modules/{plugin-name}/ - 在
metadata.go中定义元数据,遵循 demo 插件结构 - 在
lifecycle.go中实现生命周期接口 - 在
models/db.go中添加模型,包含InitDB()、UpgradeDB()、DropDB() - 在
route/*.go中注册路由 - 在
frontend/*.json中添加前端 AMIS JSON - 在
pkg/plugins/modules/registrar/中注册插件
关键参考:完整的插件架构文档请参见 pkg/plugins/readme.md(857 行)。
所有方法必须是幂等的:
Install(ctx):创建表、初始化数据Upgrade(ctx):版本变更时迁移模式/数据Enable(ctx):注册路由、暴露菜单Disable(ctx):隐藏菜单、取消注册路由Start(ctx):启动后台协程、订阅 EventBusStop(ctx):停止协程、清理资源StartCron(ctx, spec):执行计划任务Uninstall(ctx):删除表(或根据请求保留数据)
插件可以订阅系统事件:
EventLeaderElected:当此实例成为 leader 时EventLeaderLost:当此实例失去 leader 状态时
elect := ctx.Bus().Subscribe(eventbus.EventLeaderElected)
lost := ctx.Bus().Subscribe(eventbus.EventLeaderLost)完整的路由图请参见 docs/route_structure.md:
/auth/*:认证(登录、SSO)/k8s/cluster/{cluster}/*:集群特定操作/plugins/{name}/*:插件集群操作
/mgm/*:管理操作/plugins/{name}/*:插件管理操作
/admin/*:仅平台管理员/plugins/{name}/*:插件管理员操作
/swagger/*:API 文档(如果启用了 swagger 插件)
- 测试文件位于:
pkg/comm/utils/*_test.go、pkg/plugins/modules/webhook/core/*_test.go - 使用
go test运行测试 - 测试应遵循 Go 惯例
- 使用表驱动测试进行多用例测试
- 在适当的
pkg/controller/*包中添加控制器函数 - 在
main.gobuildRouter 函数中注册路由 - 使用
response.Adapter包装处理器 - 使用
c.JSON()返回响应 - 如果需要,添加文档(Swagger)
前端调用:
- 在 AMIS JSON 中使用
api字段定义请求 - fetcher 会自动处理认证、集群上下文、错误处理
- GET 请求的查询参数通过
sendOn配置发送
示例:
{
"type": "crud",
"api": {
"method": "get",
"url": "/k8s/cluster/${cluster}/pods",
"data": {
"namespace": "${selectedNs}"
},
"sendOn": "init"
}
}- 在
pkg/controller/{resource}/中创建控制器包 - 使用
kom客户端实现 CRUD 操作 - 在
main.go中的/k8s/cluster/{cluster}/下注册路由 - 为 UI 添加前端 AMIS JSON
- 使用
-d标志启用调试模式 - 使用
-v 6获取详细日志 - 使用
--print-config查看启动时的配置 - 使用
klog.V(6).Infof()打印调试日志(仅中文)
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 - 集群上下文通过中间件在集群路由中可用
- 所有面向用户的消息和日志使用中文
- 永远不要删除现有注释而不标记它们