# 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.24,Gorilla Mux,Hexagonal Architecture,PostgreSQL,ORAS SDK,Helm SDK,Kubernetes client-go。 - 前端:React 18,TypeScript,Vite,TailwindCSS。 - 部署:Docker Compose,Nginx 静态文件与 `/api` 反向代理,PostgreSQL 持久化。 ## 项目结构 ```text 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`,提交 `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 操作目标集群。 ## 部署前准备 需要本机已安装: - 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_ENABLE_CLUSTERS=true 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,可配置 TOKEN;CERT/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_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 密码和集群凭据;生产环境首次启动后不要随意更换,否则旧数据无法解密。 ## 推荐部署流程 `.env` 文件为可选配置。不提供 `.env` 时,系统以空白状态启动,首次访问时展示管理员注册页面(Setup),第一个注册用户即为管理员。 ```bash # 1. 克隆代码 git clone https://gitea.bwgdi.com/OCDP/ocdp-go.git cd ocdp-go # 2. 构建并后台启动完整平台(无需 .env) make up # 3. 打开浏览器访问 http://:18080 # 首次访问会看到 Initial Setup 页面,创建管理员账号和密码即可开始使用 ``` 有 `.env` 时,可以预注入初始管理员账号、Registry 和 Cluster(用于开发/测试): # 4. 查看服务;postgres/backend/nginx 应为 Up,frontend-build Exited(0) 正常 make docker-ps ``` 访问地址: - 前端入口:http://localhost:${WEB_HTTP_PORT:-18080} - 后端健康检查:http://localhost:${BACKEND_PORT:-18081}/health - Swagger UI:http://localhost:${BACKEND_PORT:-18081}/api/docs - Nginx 健康检查:http://localhost:${WEB_HTTP_PORT:-18080}/healthz 兼容旧文档的命令仍可用,但只是 `make up` 的别名: ```bash make run-2 make docker-dev make docker-prod make docker-up ``` 没有 Make 时,直接用根目录 Compose 文件: ```bash docker compose up --build -d docker compose ps -a ``` 代码、Dockerfile、前端资源变更后都建议使用 `make up` 或 `docker compose up --build -d`,避免复用旧镜像或旧前端静态资源。 ## 验证部署 ```bash # 健康检查 curl http://localhost:${BACKEND_PORT:-18081}/health curl http://localhost:${WEB_HTTP_PORT:-18080}/healthz # 检查是否需要初始化管理员(无 .env 部署时返回 needsSetup: true) curl http://localhost:${BACKEND_PORT:-18081}/api/v1/auth/status # 初始化管理员账号(仅限尚无管理员时可用) curl -s -X POST http://localhost:${BACKEND_PORT:-18081}/api/v1/auth/setup \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"your-password"}' # 登录 curl -s -X POST http://localhost:${BACKEND_PORT:-18081}/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"your-password"}' # 查看 bootstrap 是否生效,需要带 Bearer token curl http://localhost:${BACKEND_PORT:-18081}/api/v1/registries \ -H "Authorization: Bearer " curl http://localhost:${BACKEND_PORT:-18081}/api/v1/clusters \ -H "Authorization: Bearer " ``` 页面验证: 1. 打开前端入口并登录。 2. 进入 Chart Browser,确认能看到 Harbor 中的 `vllm-serve` 或 nginx chart repository。当前默认只展示可部署 Helm chart。 3. 选择 chart tag,点击 Launch。 4. 选择目标集群、命名空间,填写实例名和 values。values 支持 schema 表单或 YAML;YAML 会在前端校验,并由后端解析为 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="" \ ./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="" \ ./test/current-platform-smoke.sh ``` ## 常用运维命令 ```bash # 一条命令启动/更新完整平台 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 ``` ## 本地开发与测试 后端: ```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`。 - `frontend-build` 是一次性构建任务,退出码 `0` 是正常状态;前端页面由 `nginx` 容器提供。若只看到 backend/postgres 在运行,请执行 `make up` 或 `docker compose up --build -d` 恢复完整栈。 - 如果旧文档提到 `make docker-dev`、`make 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 文档 - OpenAPI YAML:[backend/docs/openapi.yaml](./backend/docs/openapi.yaml) - 运行后 Swagger UI:`/api/docs`