Files
ocdp-go/README.md
Ivan087 33ddaf97db fix: scale replicas in response, K8s metrics client, quota precheck, auth tests
- Add GetMetrics method to MetricsClient interface and implement cluster metrics API
- Add QuotaPrecheck service for validating resource quotas before deployment
- Add auth DTO with role/permission models and auth handler tests
- Add instance diagnostics: mounted NFS volumes, labels, annotations in pod diagnostics
- Update workspace handler with GetWorkspace endpoint and shared-user list
- Fix monitoring handler to use correct service method name
- Add tail_lines fallback in instance handler for snake_case query params
- Update nginx config for SSE log streaming support (no buffering)
- Add comprehensive test coverage: auth_service_test, auth_handler_test,
  auth_dto_test, metrics_client_test, quota_precheck_test
- Update error messages for quota validation and instance operations
- ModifyModal: fix YAML lineWidth:0, modified keys summary, delta-only submit
- InstanceCard: correctly disable scale-minus when replicas <= 0
- SidebarLayout: add hover transition for sidebar items
- Update todo.md and lessons.md with latest fixes
2026-05-20 16:56:29 +08:00

12 KiB
Raw Blame History

OCDP - One Click Deployment Platform

OCDP 是一个面向 Kubernetes 的大模型推理部署平台。当前核心场景是:用户在页面选择 Harbor 中的 vllm-serve Helm Chart填写实例名称、命名空间和 values 后,后端从 Harbor 拉取封装好的 OCI Helm Chart并通过 Helm SDK 部署到已配置好的 Kubernetes 集群。

当前能力

  • 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 注入管理员账号。

技术栈

  • 后端Go 1.24Gorilla MuxHexagonal ArchitecturePostgreSQLORAS SDKHelm SDKKubernetes client-go。
  • 前端React 18TypeScriptViteTailwindCSS。
  • 部署Docker ComposeNginx 静态文件与 /api 反向代理PostgreSQL 持久化。

项目结构

ocdp-go/
├── 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 job + Nginx
├── backend/docker-compose.yml   # PostgreSQL + Backend + pgAdmin
├── Makefile                     # 推荐入口up / restart / stop / logs / ps
└── tasks/                       # Agent 工作记录

后端部署链路

  1. 前端调用 POST /api/v1/clusters/{clusterId}/instances,提交 namenamespaceregistryIdrepositorytag 和可选 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 操作目标集群。

部署前准备

需要本机已安装:

  • Docker
  • Docker Compose v2 或更高版本
  • Make可选没有 Make 时可直接执行 Compose 命令

根目录 .env 用于开发环境启动时注入端口、数据库、初始账号、Harbor 和 Kubernetes 集群。它是开发/测试 bootstrap 数据,不是长期配置中心;系统启动后建议在页面里维护 Registry 和 Cluster。不要提交真实 .env

关键变量如下,实际值以你的 .env 为准:

# 登录账号 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

说明:

  • BOOTSTRAP_CONFIG_JSON 优先级最高,适合把完整 bootstrap 配置作为 JSON 注入。
  • 没有 BOOTSTRAP_CONFIG_JSON 时,后端会读取 BOOTSTRAP_* 变量生成初始账号、Registry 和 Cluster。
  • 没有任何显式 bootstrap 配置时后端不会预注入用户、Registry 或 Cluster代码中不再保留真实 Harbor、admin 或集群 fallback。
  • 初始管理员必须显式配置 BOOTSTRAP_ADMIN_USERBOOTSTRAP_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 密码和集群凭据;生产环境首次启动后不要随意更换,否则旧数据无法解密。

推荐部署流程

当前只有一个推荐启动入口:在项目根目录执行 make up。它会启动同一套完整 Docker Compose 栈:

  • postgres:数据库,常驻服务。
  • backendGo API常驻服务宿主机默认端口 18081
  • frontend-build:一次性构建任务,构建完成后退出是正常现象。
  • nginx:统一 Web 入口,常驻服务,宿主机默认端口 18080;前端静态文件和 /api/* 都从这里访问。

所以看到 frontend-build 处于 Exited (0) 不代表前端没运行;前端由 nginx 服务。正常运行时至少应看到 postgresbackendnginx 三个容器为 Up

# 1. 在根目录检查 .env
ls .env

# 2. 如果默认高位端口被其他项目占用,先换端口;不要杀其他项目进程
export WEB_HTTP_PORT=18080
export WEB_HTTPS_PORT=18443
export BACKEND_PORT=18081
export POSTGRES_PORT=15432

# 3. 构建并后台启动完整平台
make up

# 4. 查看服务postgres/backend/nginx 应为 Upfrontend-build Exited(0) 正常
make docker-ps

访问地址:

兼容旧文档的命令仍可用,但只是 make up 的别名:

make run-2
make docker-dev
make docker-prod
make docker-up

没有 Make 时,直接用根目录 Compose 文件:

docker compose up --build -d
docker compose ps -a

代码、Dockerfile、前端资源变更后都建议使用 make updocker compose up --build -d,避免复用旧镜像或旧前端静态资源。

验证部署

# 健康检查
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>"

curl http://localhost:${BACKEND_PORT:-18081}/api/v1/clusters \
  -H "Authorization: Bearer <token>"

页面验证:

  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

# 只验证登录、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

# 允许真实部署时,会创建测试 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

常用运维命令

# 一条命令启动/更新完整平台
make up

# 强制重建并重启完整平台
make restart

# 查看当前状态;需要关注 postgres/backend/nginx 是否 Up
make docker-ps
docker compose ps -a

# 查看日志
make docker-logs

# 只重启后端
docker compose restart backend

# 只重启 Web 网关
docker compose restart nginx

# 停止本项目服务,保留数据库和前端构建卷
make stop

# 清理本项目容器和数据卷,谨慎使用,会删除 PostgreSQL 数据
make clean

本地开发与测试

后端:

cd backend
go test ./...
go run cmd/api/main.go

前端:

cd frontend
npm ci
npm run build

Mock 后端仍可通过 backend/docker-compose.ymlmock profile 启动:

docker compose -f backend/docker-compose.yml --profile mock up -d backend-mock

注意事项

  • 不要为了端口冲突停止其他项目;优先通过 WEB_HTTP_PORTWEB_HTTPS_PORTBACKEND_PORTPOSTGRES_PORT 换端口。当前默认端口已经是 18080/18443/18081/15432
  • frontend-build 是一次性构建任务,退出码 0 是正常状态;前端页面由 nginx 容器提供。若只看到 backend/postgres 在运行,请执行 make updocker compose up --build -d 恢复完整栈。
  • 如果旧文档提到 make docker-devmake docker-prod,现在这些命令仍可用,都会调用 make up 启动同一套 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 文档