refactor: full-stack restructure with multi-tenancy, workspace management, and K8s diagnostics

- Add Workspace domain (entity, repository, service, handler, DTO)
- Add multi-tenant K8s client with tenant binding and quota management
- Add K8s diagnostics client (instance diagnostics)
- Add authorization middleware (authz package)
- Restructure frontend to feature-based architecture (features/)
- Add User Management page in configuration
- Add AccessDenied page and route guards
- Refactor shared components (form inputs, layout, UI)
- Update Tailwind config for new design system
- Add comprehensive documentation (docs/, tasks/, plans)
- Improve cluster service with better kubeconfig handling
- Add tests for crypto, config, helm client, tenant binding
This commit is contained in:
Ivan087
2026-05-12 16:15:14 +08:00
parent c5e51ed069
commit 7f238a3168
172 changed files with 15703 additions and 3162 deletions

497
README.md
View File

@ -1,336 +1,267 @@
# OCDP - Open Cloud Development Platform
# OCDP - Open Cloud Deployment Platform
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Go Version](https://img.shields.io/badge/go-1.24+-00ADD8?logo=go)](https://go.dev/)
[![Node Version](https://img.shields.io/badge/node-20+-339933?logo=node.js)](https://nodejs.org/)
[![Docker](https://img.shields.io/badge/docker-20.10+-2496ED?logo=docker)](https://www.docker.com/)
OCDP 是一个面向 Kubernetes 的大模型推理部署平台。当前核心场景是:用户在页面选择 Harbor 中的 `vllm-serve` Helm Chart填写实例名称、命名空间和 values 后,后端从 Harbor 拉取封装好的 OCI Helm Chart并通过 Helm SDK 部署到已配置好的 Kubernetes 集群。
开源云原生开发平台,用于管理 Kubernetes 集群、OCI Registry 和 Helm Charts 部署。
## 当前能力
---
- Registry 管理:保存 Harbor / OCI Registry 地址与凭据,敏感字段加密入库。
- Artifact 浏览:通过 Harbor v2.0 API 浏览当前凭据可见的项目、repositories 和 chart tags避免依赖 `/v2/_catalog` 全局 catalog 权限。
- 一键部署:从前端发起实例创建,后端拉取 Chart 并在目标集群执行 Helm install/upgrade/uninstall。
- 集群管理:保存 Kubernetes API Server、CA、客户端证书或 token用于后端连接集群。
- 实例管理查看部署状态、Helm revision、Service/Ingress 入口信息。
- 认证:内置 JWT 登录,首次启动可通过 bootstrap 注入管理员账号。
## ✨ 特性
## 技术栈
- 🎯 **Registry 管理** - 支持 Harbor、Docker Registry、OCI 标准仓库
- 📦 **Artifact 浏览** - 浏览和管理 Helm Charts、容器镜像
- 🚀 **一键部署** - 可视化部署 Helm Charts 到 Kubernetes 集群
- 🔍 **智能过滤** - 按 MediaType 过滤 artifactschart、image、other
- 🎨 **现代 UI** - 响应式设计,基于 React + TypeScript
- 🔐 **安全认证** - JWT 认证,加密存储敏感信息
- 🐳 **容器化** - 完整的 Docker 支持,多种运行模式
- 🔄 **热重载** - 开发模式支持代码热重载
- 后端Go 1.24Gorilla MuxHexagonal ArchitecturePostgreSQLORAS SDKHelm SDKKubernetes client-go。
- 前端React 18TypeScriptViteTailwindCSS。
- 部署Docker ComposeNginx 静态文件与 `/api` 反向代理PostgreSQL 持久化。
---
## 项目结构
## 🚀 快速开始
### 前置要求
- Docker 20.10+
- Docker Compose 2.0+
- (可选) Make 工具
### 5分钟快速体验
```bash
# 1. 克隆项目
git clone <repository-url>
cd ocdp-go
# 2. 启动开发环境Mock 模式,无需数据库)
make docker-dev
# 3. 访问应用
# - 前端http://localhost:5173
# - 后端http://localhost:8080
# - 默认账号admin / admin123
```
**详细指南**:查看 [快速开始指南](./QUICK_START.md)
---
## 📚 文档导航
### 📖 核心文档(必读)
- 🚀 [快速开始](./QUICK_START.md) - 5分钟快速上手
- 📋 [使用指南](./USAGE_GUIDE.md) - 详细使用说明(推荐)
- 💡 [命令速查表](./COMMANDS_CHEATSHEET.md) - 常用命令快速参考
- 📚 [文档中心](./docs/README.md) - 完整文档索引
### 🔧 专业文档
- 📐 [开发规范](./docs/development/specification.md) - 代码规范和架构
- 🚢 [部署指南](./docs/deployment/docker-guide.md) - 生产环境部署
- 🔒 [安全实践](./docs/security/security-implementation.md) - 安全配置
- 🎨 [功能文档](./docs/features/) - 详细功能说明
### 🔗 其他资源
- 📋 [OpenAPI 规范](./backend/docs/openapi.yaml) - RESTful API 定义
- 📦 [历史文档](./docs/archive/) - 项目演进历史
---
## 🏗️ 技术架构
### 技术栈
**后端**
- Go 1.24+ (Hexagonal Architecture)
- PostgreSQL 16
- Redis 7
**前端**
- React 18
- TypeScript 5
- Vite 6
- TailwindCSS 3
**容器化**
- Docker
- Docker Compose
- Multi-stage builds
### 架构图
```
┌─────────────────────────────────────────────────────────────┐
│ Frontend │
│ React + TypeScript + Vite │
└──────────────────────────┬──────────────────────────────────┘
│ HTTP/REST
┌──────────────────────────┼──────────────────────────────────┐
│ │ Backend API │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ Input Adapters │ │
│ │ (REST/GraphQL) │ │
│ └──────────┬──────────┘ │
│ │ │
│ ┌──────────▼──────────┐ │
│ │ Domain Services │ │
│ │ (Business Logic) │ │
│ └──────────┬──────────┘ │
│ │ │
│ ┌──────────▼──────────┐ │
│ │ Output Adapters │ │
│ │ (Repos/Clients) │ │
│ └──────────┬──────────┘ │
└───────────────────────┼─┴────────────────────────────────┘
┌───────────────┼───────────────┐
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│ PG DB │ │ Redis │ │ OCI │
│ │ │ │ │ Registry│
└─────────┘ └─────────┘ └─────────┘
```
### 运行模式
| 模式 | 特点 | 适用场景 | 命令 |
|------|------|----------|------|
| **开发模式** | Mock 数据,热重载 | 日常开发 | `make docker-dev` |
| **生产模式** | 真实数据库,完整功能 | 生产部署 | `make docker-prod` |
| **Mock 模式** | 独立测试单个服务 | 单元测试 | `make docker-test-backend` |
---
## 🛠️ 开发指南
### 项目结构
```
```text
ocdp-go/
├── backend/ # Go 后端服务
│ ├── cmd/api/ # 应用入口
│ ├── internal/ # 内部代码
│ ├── adapter/ # 适配器层
│ ├── domain/ # 领域层
│ └── bootstrap/ # 启动配置
│ ├── Dockerfile # 生产环境
│ ├── Dockerfile.dev # 开发环境
│ └── Dockerfile.mock # Mock 测试
├── frontend/ # React 前端应用
│ ├── src/
│ │ ├── core/ # 核心功能
│ │ ├── features/ # 功能模块
│ │ └── shared/ # 共享组件
│ ├── Dockerfile # 生产环境
│ ├── Dockerfile.dev # 开发环境
│ └── Dockerfile.mock # Mock 测试
├── api/ # API 规范
│ └── openapi.yaml # OpenAPI 定义
├── docs/ # 项目文档
│ ├── features/ # 功能文档
│ ├── deployment/ # 部署文档
│ └── development/ # 开发文档
├── docker-compose.yml # 统一配置(使用 profiles
└── Makefile # 便捷命令
├── backend/ # Go 后端
│ ├── cmd/api/ # API 入口
│ ├── internal/adapter/input/ # HTTP REST handlers / DTO
│ ├── internal/adapter/output/ # PostgreSQL / ORAS / Helm / K8s 实现
│ ├── internal/domain/ # Entity / Repository interface / Service
│ └── internal/bootstrap/ # 首次启动数据注入
├── frontend/ # React + Vite 前端
├── infra/nginx/ # Nginx 网关配置和 TLS 证书
── docker-compose.yml # 本地完整部署PostgreSQL + Backend + 前端 build + Nginx
├── backend/docker-compose.yml # PostgreSQL + Backend + pgAdmin
├── Makefile # 推荐入口install / run-2 / docker-dev / docker-down
└── tasks/ # Agent 工作记录
```
### 常用命令
## 后端部署链路
```bash
# Docker 服务(推荐)
make docker-dev # 启动开发环境
make docker-prod # 启动生产环境
make docker-test-backend # 测试后端
make docker-test-frontend # 测试前端
make docker-logs # 查看日志
make docker-down # 停止服务
1. 前端调用 `POST /api/v1/clusters/{clusterId}/instances`,提交 `name``namespace``registryId``repository``tag` 和可选 `values`
2. 后端 `InstanceService.CreateInstance` 校验集群、Registry 和实例名唯一性,创建 pending 记录。
3. Chart 浏览使用 Harbor v2.0 API实际部署时后端使用 ORAS SDK 访问 Harbor将指定 repository/tag 的 Helm Chart layer 下载到 `/tmp/charts/{chart}-{version}.tgz`
4. 后端用数据库中保存的集群凭据生成临时 kubeconfig。
5. Helm SDK 加载本地 chart 包,并对目标集群执行 `install`;后续通过 Helm status 同步实例状态。
6. 删除、升级和回滚实例同样通过 Helm SDK 操作目标集群。
# OpenAPI 工作流
make openapi-validate # 验证 API 规范
make openapi-gen # 生成代码
make openapi-docs # 生成文档
## 部署前准备
# 本地开发(不使用 Docker
make install # 安装依赖
make dev-local # 启动本地开发
make test # 运行测试
需要本机已安装:
- Docker
- Docker Compose v2 或更高版本
- Make可选没有 Make 时可直接执行 Compose 命令
根目录 `.env` 用于开发环境启动时注入端口、数据库、初始账号、Harbor 和 Kubernetes 集群。它是开发/测试 bootstrap 数据,不是长期配置中心;系统启动后建议在页面里维护 Registry 和 Cluster。不要提交真实 `.env`
关键变量如下,实际值以你的 `.env` 为准:
```dotenv
# 登录账号 bootstrap
BOOTSTRAP_ADMIN_USER=admin
BOOTSTRAP_ADMIN_PASS=change-me
BOOTSTRAP_ADMIN_EMAIL=admin@example.com
# Harbor bootstrap
BOOTSTRAP_REGISTRY_NAME=harbor
BOOTSTRAP_REGISTRY_URL=https://harbor.example.com
BOOTSTRAP_REGISTRY_DESC=Harbor Registry
# 推荐使用 Harbor robot 账号,只授予目标项目 pull/read 权限
BOOTSTRAP_REGISTRY_ROBOT_USER='robot$project+ocdp'
BOOTSTRAP_REGISTRY_ROBOT_PASS='robot-token'
# 可选 fallback未配置 ROBOT 变量时才会使用
BOOTSTRAP_REGISTRY_USER=admin-or-user
BOOTSTRAP_REGISTRY_PASS=change-me
BOOTSTRAP_REGISTRY_INSECURE=false
# Kubernetes 集群 bootstrap名称列表用逗号分隔
BOOTSTRAP_CLUSTERS=cluster1,cluster2
BOOTSTRAP_CLUSTER_CLUSTER1_HOST=https://x.x.x.x:6443
BOOTSTRAP_CLUSTER_CLUSTER1_DESC=GPU Cluster 1
BOOTSTRAP_CLUSTER_CLUSTER1_CA=base64-ca-data
BOOTSTRAP_CLUSTER_CLUSTER1_CERT=base64-client-cert-data
BOOTSTRAP_CLUSTER_CLUSTER1_KEY=base64-client-key-data
# 如使用 token可配置 TOKENCERT/KEY 可按实际鉴权方式留空
BOOTSTRAP_CLUSTER_CLUSTER2_HOST=https://x.x.x.x:6443
BOOTSTRAP_CLUSTER_CLUSTER2_TOKEN=token-value
# 服务端口,默认使用高位端口避免和本机其他项目冲突
WEB_HTTP_PORT=18080
WEB_HTTPS_PORT=18443
BACKEND_PORT=18081
POSTGRES_PORT=15432
# 安全与数据库
JWT_SECRET=replace-with-a-strong-secret
ENCRYPTION_KEY=replace-with-32-byte-key
POSTGRES_DB=ocdp
POSTGRES_USER=postgres
POSTGRES_PASSWORD=replace-me
# 可选Docker 构建后端时使用的 Go module proxy。
# 国内网络建议保留默认值;如公司网络要求,也可改回 https://proxy.golang.org,direct。
GOPROXY=https://goproxy.cn,direct
GOSUMDB=sum.golang.google.cn
```
### 开发工作流
说明:
1. **启动开发环境**
```bash
make docker-dev
```
- `BOOTSTRAP_CONFIG_JSON` 优先级最高,适合把完整 bootstrap 配置作为 JSON 注入。
- 没有 `BOOTSTRAP_CONFIG_JSON` 时,后端会读取 `BOOTSTRAP_*` 变量生成初始账号、Registry 和 Cluster。
- 没有任何显式 bootstrap 配置时后端不会预注入用户、Registry 或 Cluster代码中不再保留真实 Harbor、admin 或集群 fallback。
- 初始管理员必须显式配置 `BOOTSTRAP_ADMIN_USER``BOOTSTRAP_ADMIN_PASS`。如果只配置 Registry/Cluster 而未配置管理员账号,系统不会自动创建默认账号。
- Registry bootstrap 凭据优先级为 `BOOTSTRAP_REGISTRY_ROBOT_USER/PASS`,然后才是 `BOOTSTRAP_REGISTRY_USER/PASS`。Harbor robot 账号需要能访问目标项目的 repositories 和 artifacts。
- Harbor robot 用户名通常包含 `$`。本项目 Compose 已使用 raw `env_file` 传给后端;如果你在 shell 里临时 `export BOOTSTRAP_REGISTRY_ROBOT_USER=...`,请用单引号包住值,避免 shell 展开 `$project`
- 已存在同名用户、Registry 或 Cluster 时bootstrap 会跳过,不会覆盖数据库里的记录。
- `ENCRYPTION_KEY` 用于加密保存 Harbor 密码和集群凭据;生产环境首次启动后不要随意更换,否则旧数据无法解密。
2. **修改代码**(自动热重载):
- 后端:编辑 `backend/` 下的 Go 文件
- 前端:编辑 `frontend/src/` 下的 React 组件
## 推荐部署流程
3. **查看日志**
```bash
make docker-logs
```
4. **测试功能**
- 前端http://localhost:5173
- 后端http://localhost:8080
5. **提交代码**
```bash
git add .
git commit -m "feat: add new feature"
git push
```
---
## 🧪 测试
### 后端测试
当前推荐使用根目录 Makefile。`docker-dev``docker-prod``docker-up` 都是兼容旧文档的别名,实际会启动同一套完整 Docker Compose 栈PostgreSQL、Backend、前端静态构建和 Nginx。
```bash
# 启动后端 Mock
make docker-test-backend-bg
# 1. 在根目录检查 .env
ls .env
# 测试健康检查
curl http://localhost:8080/health
# 2. 可选:安装本地依赖。只部署 Docker 栈时不是必须,但这个命令可用。
make install
# 测试登录
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}'
# 3. 如果默认高位端口仍被其他项目占用,再临时换端口
export WEB_HTTP_PORT=18080
export WEB_HTTPS_PORT=18443
export BACKEND_PORT=18081
export POSTGRES_PORT=15432
# 测试 API
curl http://localhost:8080/api/v1/registries
curl http://localhost:8080/api/v1/clusters
```
# 4. 构建并后台启动完整栈
make run-2
### 前端测试
```bash
# 启动前端 Mock
make docker-test-frontend-bg
# 访问前端
open http://localhost:3000
```
### 集成测试
```bash
# 启动完整环境
# 兼容旧文档,也可以执行:
make docker-dev
make docker-prod
# 运行测试套件
make test
# 5. 查看服务
make docker-ps
```
---
访问地址:
## 📦 部署
- 前端入口http://localhost:${WEB_HTTP_PORT:-18080}
- 后端健康检查http://localhost:${BACKEND_PORT:-18081}/health
- Swagger UIhttp://localhost:${BACKEND_PORT:-18081}/api/docs
- Nginx 健康检查http://localhost:${WEB_HTTP_PORT:-18080}/healthz
### Docker Compose 部署(推荐)
没有 Make 时,直接用根目录 Compose 文件即可。注意要加 `--build`,因为后端镜像和前端静态资源需要构建:
```bash
# 1. 配置环境变量
export JWT_SECRET="your-production-secret"
export ENCRYPTION_KEY="your-32-byte-encryption-key"
# 2. 启动服务
docker compose up -d
# 3. 查看状态
docker compose up --build -d postgres backend nginx
docker compose ps
```
### Kubernetes 部署
如果直接执行 `docker compose up`Compose 也会使用同一个完整栈;但在代码或 Dockerfile 改动后建议显式加 `--build`,避免复用旧镜像。
查看 [Kubernetes 部署指南](./docs/deployment/kubernetes-guide.md)
## 验证部署
---
```bash
# 健康检查
curl http://localhost:${BACKEND_PORT:-18081}/health
curl http://localhost:${WEB_HTTP_PORT:-18080}/healthz
## 🤝 贡献
# 登录,返回 token。把 password 替换成 .env 里的 BOOTSTRAP_ADMIN_PASS。
curl -s -X POST http://localhost:${BACKEND_PORT:-18081}/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"<BOOTSTRAP_ADMIN_PASS>"}'
欢迎贡献代码!请遵循以下步骤:
# 查看 bootstrap 是否生效,需要带 Bearer token
curl http://localhost:${BACKEND_PORT:-18081}/api/v1/registries \
-H "Authorization: Bearer <token>"
1. Fork 项目
2. 创建功能分支 (`git checkout -b feature/amazing-feature`)
3. 提交更改 (`git commit -m 'feat: add amazing feature'`)
4. 推送分支 (`git push origin feature/amazing-feature`)
5. 创建 Pull Request
curl http://localhost:${BACKEND_PORT:-18081}/api/v1/clusters \
-H "Authorization: Bearer <token>"
```
### 开发规范
页面验证:
- **代码风格**Go (gofmt)TypeScript (ESLint + Prettier)
- **提交规范**:遵循 [Conventional Commits](https://www.conventionalcommits.org/)
- **测试覆盖**:新功能必须包含测试
1. 打开前端入口并登录。
2. 进入 Chart Browser确认能看到 Harbor 中的 `vllm-serve` 或 nginx chart repository。当前默认只展示可部署 Helm chart。
3. 选择 chart tag点击 Launch。
4. 选择目标集群、命名空间,填写实例名和 values。values 支持 schema 表单或 YAMLYAML 会在前端校验,并由后端解析为 Helm values map。
5. 提交后到实例页面查看状态;后端会异步安装并同步 Helm 状态。
---
命令行 smoke test
## 📄 许可证
```bash
# 只验证登录、Registry health、Harbor chart 浏览和 values schema
BASE_URL=http://localhost:${BACKEND_PORT:-18081}/api/v1 \
ADMIN_USER="${BOOTSTRAP_ADMIN_USER:-admin}" \
ADMIN_PASS="<BOOTSTRAP_ADMIN_PASS>" \
./test/current-platform-smoke.sh
本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情
# 允许真实部署时,会创建测试 release 并在结束后调用平台删除
RUN_DEPLOY_TEST=true \
TEST_NAMESPACE=ocdp-smoke \
TEST_RELEASE=ocdp-smoke-nginx \
BASE_URL=http://localhost:${BACKEND_PORT:-18081}/api/v1 \
ADMIN_PASS="<BOOTSTRAP_ADMIN_PASS>" \
./test/current-platform-smoke.sh
```
---
## 常用运维命令
## 🙏 致谢
```bash
# 查看日志
make docker-logs
- [Go](https://go.dev/) - 后端开发语言
- [React](https://react.dev/) - 前端框架
- [Vite](https://vitejs.dev/) - 构建工具
- [Docker](https://www.docker.com/) - 容器化平台
- [Kubernetes](https://kubernetes.io/) - 容器编排
- [Harbor](https://goharbor.io/) - OCI Registry
# 重启后端
docker compose restart backend
---
# 如果后端容器被重建过Nginx 可能仍缓存旧 upstream IP只需重启本项目 Nginx
docker compose restart nginx
## 📞 联系方式
# 停止本项目服务,但保留数据卷
make docker-down
- **项目主页**https://github.com/your-org/ocdp-go
- **问题反馈**https://github.com/your-org/ocdp-go/issues
- **文档网站**https://docs.ocdp.example.com
# 清理本项目容器和数据卷,谨慎使用
make clean-2
```
---
## 本地开发与测试
<div align="center">
<sub>Built with ❤️ by the OCDP Team</sub>
</div>
后端:
```bash
cd backend
go test ./...
go run cmd/api/main.go
```
前端:
```bash
cd frontend
npm ci
npm run build
```
Mock 后端仍可通过 `backend/docker-compose.yml``mock` profile 启动:
```bash
docker compose -f backend/docker-compose.yml --profile mock up -d backend-mock
```
## 注意事项
- 不要为了端口冲突停止其他项目;优先通过 `WEB_HTTP_PORT``WEB_HTTPS_PORT``BACKEND_PORT``POSTGRES_PORT` 换端口。当前默认端口已经是 `18080/18443/18081/15432`
- 如果旧文档提到 `make docker-dev``make docker-prod`,现在这些命令仍可用,都会启动同一套 Docker 栈。
- 如果之前用旧配置启动失败过PostgreSQL 卷里可能残留旧的加密数据,表现为 `/api/v1/clusters``/api/v1/registries` 解密失败。开发/重装环境可执行 `make clean-2 && make docker-dev` 重新初始化;生产环境不要直接删卷,应先备份数据库。
- `vllm-serve` 必须以 Helm Chart OCI artifact 的形式存在于 Harbor 中;后端会寻找 Helm Chart layer 并保存为 `.tgz`
- Harbor 浏览使用 `/api/v2.0/projects`、project repositories 和 artifacts API。若 robot 账号无法列项目或 artifacts页面会显示明确错误请检查 Harbor 项目成员/robot 权限,而不是给普通用户开放全局 catalog。
- values YAML 已按 YAML 解析;顶层必须是 mapping例如 `replicaCount: 1`
- Nginx 默认同时监听 HTTP 和 HTTPS证书位于 `infra/nginx/certs/`,生产环境应替换为正式证书。
- `make clean-2` 会删除本项目 Compose 卷,包括 PostgreSQL 数据;只想停服务时使用 `docker compose ... down --remove-orphans`
## API 文档
- OpenAPI YAML[backend/docs/openapi.yaml](./backend/docs/openapi.yaml)
- 运行后 Swagger UI`/api/docs`