Skip to content

stlin256/GPU-Fleet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

94 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GPUFleet logo GPUFleet

DeepWiki

GPUFleet 是一个依赖尽量简单的 NVIDIA GPU 多设备监控系统。它由公网服务端和多台 Windows/Linux 客户端 Agent 组成,用于聚合不同网络环境中多台机器的 GPU 运行信息,并在一个支持深浅主题和移动端适配的 Web 面板中展示、统计和下载数据。

English documentation: README-en.md
安装指南 / Installation guide: docs/14-installation.md
当前版本:0.1.7
作者:stlin256
仓库:https://github.com/stlin256/GPU-Fleet

核心目标

  • 客户端只做本机只读采集,主动访问公网服务端,不开放监听端口。
  • 服务端只接收、校验、存储、统计和展示数据,不向客户端下发命令或配置。
  • 默认使用 Go 单文件服务端、Go 单文件 Agent、gzip JSONL 分段文件和 JSON 元数据,避免引入复杂基础设施。
  • 数据库具备压缩、保留期清理和空间保护,默认预留 800MiB 空闲磁盘。
  • Web 面板优先展示多机多卡 GPU Fleet 卡片,卡片内使用历史图表而非进度条,支持离线蒙版、同设备边框同色和悬浮读数。
  • 首次启动通过浏览器配置访问密码、端口和可选 HTTPS 证书;未配置证书时使用 HTTP,配置证书并重启后使用 HTTPS。
  • 首次启动先选择界面语言,当前支持简体中文和 English;后续可在设置页修改,语言配置保存在服务端元数据中。
  • Web 登录仅使用密码,登录后记住当前浏览器设备 30 天。

当前能力

模块 状态 说明
服务端 已实现 HTTP/HTTPS、HMAC Agent 接入、Web API、静态面板托管、内置 fallback 面板
Agent 已实现 Windows/Linux,基于 nvidia-smi 只读采集,支持离线队列
Web 面板 已实现 React + Vite + TypeScript + TanStack Query + ECharts + lucide-react
i18n 已实现 首次配置语言选择、设置页语言切换、服务端语言持久化、可扩展词表、中文/英文
设备管理 已实现 创建设备、一次性密钥、改名、禁用/启用、删除、轮换密钥、危险操作确认
数据存储 已实现 gzip JSONL 分段指标、JSON 元数据、保留期清理、数据库下载
安全防护 已实现 HMAC 签名、nonce 重放保护、登录限流、递进锁定、30 天会话
版本机制 已实现 -version 命令、/api/v1/version、设置页版本与 Changelog、CHANGELOG.md
在线更新 已实现 设置页检查 Git upstream、显示提交差异,并在依赖完整时执行构建、fast-forward 拉取和自动重启

产品截图

GPUFleet 总览面板

GPUFleet 设备管理

GPUFleet GPU 监控

GPUFleet 服务设置

总体架构

flowchart LR
  subgraph "不同网络环境"
    A1["Windows Agent\nnvidia-smi 只读采集"]
    A2["Linux Agent\nnvidia-smi 只读采集"]
    A3["多卡工作站 Agent\n离线队列"]
  end

  subgraph "公网服务端"
    API["Go Server\nHTTP/HTTPS + Web API"]
    Auth["认证与限流\nHMAC / Session / Lockout"]
    Store["压缩指标存储\ngzip JSONL segments"]
    Meta["元数据\nJSON files"]
    Web["Web Dashboard\nReact build or fallback"]
  end

  Browser["浏览器\n桌面 / 平板 / 手机"]

  A1 -->|"主动上报 HMAC 请求"| API
  A2 -->|"主动上报 HMAC 请求"| API
  A3 -->|"失败缓存,恢复后回放"| API
  API --> Auth
  Auth --> Store
  Auth --> Meta
  Web --> API
  Browser --> Web
  Browser --> API
Loading

安全边界

GPUFleet 的安全边界是产品设计的一部分:服务端不能对客户端产生设置影响,也不能远程执行客户端动作。

flowchart TB
  subgraph "客户端设备"
    Agent["Agent\n只读采集 GPU/进程快照"]
    LocalConfig["本地配置\nServer URL / Device ID / Secret"]
    GPU["NVIDIA GPU\n运行状态"]
  end

  subgraph "服务端"
    Receive["接收上报"]
    Verify["签名、时间戳、nonce、限流"]
    Admin["管理 API\n仅修改服务端记录"]
  end

  Agent -->|"读取"| GPU
  LocalConfig --> Agent
  Agent -->|"POST heartbeat / samples / process snapshots"| Receive
  Receive --> Verify
  Admin -->|"改名/启用/禁用/删除/轮换密钥"| Verify

  Receive -. "不提供命令下发" .- Agent
  Admin -. "不修改客户端本地配置" .- LocalConfig
  Admin -. "不修改 GPU 功耗/风扇/时钟/MIG" .- GPU
Loading

数据流

sequenceDiagram
  participant Agent as Agent
  participant Server as GPUFleet Server
  participant Auth as HMAC/Nonce Guard
  participant Store as Metrics Store
  participant Web as Web Dashboard

  Agent->>Agent: nvidia-smi 只读采集
  Agent->>Server: POST /api/v1/agent/heartbeat
  Agent->>Server: POST /api/v1/agent/samples
  Agent->>Server: POST /api/v1/agent/process-snapshots
  Server->>Auth: 校验设备、签名、时间戳、nonce、限流
  Auth-->>Server: accepted
  Server->>Store: 写入 gzip JSONL 分段
  Web->>Server: GET /api/v1/overview
  Web->>Server: GET /api/v1/gpus/{gpu_id}/series
  Web->>Server: GET /api/v1/version
  Server-->>Web: 当前状态、历史序列、版本与 Changelog
Loading

存储与磁盘保护

当前 MVP 不依赖外部数据库。服务端使用压缩分段文件保存时序指标,使用 JSON 文件保存元数据。每次写入前会先清理超过保留期的旧分段,再检查磁盘剩余空间;低于阈值时拒绝新指标写入,避免占满磁盘。

flowchart TD
  W["收到指标写入请求"] --> C["清理超过 retention-days 的旧分段"]
  C --> D["读取数据目录所在磁盘空闲空间"]
  D --> OK{"free >= min-free-mb?"}
  OK -->|"是"| G["追加写入 gzip JSONL 分段"]
  OK -->|"否"| R["拒绝写入\nHTTP 507"]
  G --> I["更新最新 GPU 状态索引"]
  I --> S["Web/API 可查询"]
Loading

默认参数:

参数 默认值 说明
-retention-days 30 压缩指标分段保留天数
-min-free-mb 800 写入前必须保留的最小空闲空间
-data-dir data 服务端运行数据目录
-web-dir web/dist React 构建产物目录
-repo-dir . 服务端自身 Git 仓库目录,用于在线更新检查

首次配置

首次启动时,服务端使用启动参数里的监听端口和 HTTP 协议。浏览器打开面板后会先选择界面语言,再进入配置引导,设置访问密码、下一次启动端口和可选 HTTPS 证书。

sequenceDiagram
  participant User as 用户浏览器
  participant Server as GPUFleet Server
  participant Config as 服务配置

  User->>Server: GET /
  Server-->>User: 首次配置引导
  User->>Server: POST /api/v1/setup/apply\nlanguage + password + port + optional cert
  Server->>Config: 保存语言、密码哈希、端口、证书
  Server-->>User: restart_required
  User->>Server: 重启后访问新端口/HTTPS
Loading

登录后也可以在设置页修改语言,或重新打开配置引导,集中调整密码、端口、语言和证书。语言切换即时生效;端口和 HTTPS 证书变更需要重启当前服务进程后完全生效。

快速运行

构建

Windows PowerShell:

$env:GOCACHE='F:\project\GPUFleet\.gocache'
go build -o bin\gpufleet-server.exe .\cmd\gpufleet-server
go build -o bin\gpufleet-agent.exe .\cmd\gpufleet-agent

前端修改后重新构建:

cd web
npm install
npm run build
cd ..

Linux Agent 交叉编译示例:

$env:GOOS='linux'
$env:GOARCH='amd64'
go build -o bin\gpufleet-agent ./cmd/gpufleet-agent
Remove-Item Env:\GOOS
Remove-Item Env:\GOARCH

启动服务端

.\bin\gpufleet-server.exe `
  -addr 0.0.0.0:8088 `
  -data-dir data `
  -min-free-mb 800 `
  -retention-days 30 `
  -web-dir web/dist `
  -repo-dir .

浏览器打开:

http://127.0.0.1:8088

首次访问会进入配置引导。如果用于自动化测试,也可以传入 -admin-password 预置密码:

.\bin\gpufleet-server.exe `
  -addr 127.0.0.1:8088 `
  -data-dir data `
  -admin-password change-me `
  -min-free-mb 800 `
  -retention-days 30 `
  -web-dir web/dist `
  -repo-dir .

启动 Agent

先在 Web 面板的“设备”页创建设备并复制一次性密钥,然后在目标机器运行:

.\bin\gpufleet-agent.exe `
  -server-url http://your-server:8088 `
  -device-id device_20260603120000 `
  -secret replace-with-one-time-secret `
  -processes

一次性上报:

.\bin\gpufleet-agent.exe `
  -server-url http://127.0.0.1:8088 `
  -device-id local-dev `
  -secret local-dev-secret `
  -once `
  -processes

只在本机采集并打印,不上报:

.\bin\gpufleet-agent.exe -print

服务安装

Windows Service:

.\scripts\install-agent-windows.ps1 `
  -ServerUrl "https://your-server:8443" `
  -DeviceId "device_xxx" `
  -Secret "replace-with-device-secret"

Linux systemd:

sudo SERVER_URL="https://your-server:8443" \
  DEVICE_ID="device_xxx" \
  SECRET="replace-with-device-secret" \
  sh ./scripts/install-agent-linux.sh

卸载脚本:

.\scripts\uninstall-agent-windows.ps1
sudo sh ./scripts/uninstall-agent-linux.sh

Web 面板

Web 面板有四个主视图:

  • 总览:多机多卡 GPU Fleet 卡片、每卡 4 个历史趋势图、离线灰色蒙版、同设备 GPU 边框同色、设备和进程摘要。
  • 设备:创建设备、展示一次性密钥、改名、禁用/启用设备、删除设备、轮换密钥;危险操作使用应用内弹窗二次确认。
  • GPU:完整 GPU 运行字段、2x2 历史趋势图、进程快照和统计。
  • 设置:服务状态、密码更改、端口配置、语言设置、HTTPS 证书上传、证书到期日期、数据库下载、在线更新、配置引导、作者/仓库、版本号和 Changelog。
flowchart LR
  Web["Web Dashboard"] --> Overview["总览\nGPU Fleet 卡片"]
  Web --> Devices["设备\n注册/改名/删除/轮换密钥"]
  Web --> GPUs["GPU\n完整字段与趋势"]
  Web --> Settings["设置\n端口/证书/数据库/版本"]
  Overview --> Cards["多设备多 GPU 卡片"]
  Cards --> Charts["利用率/显存/温度/功耗历史图表"]
  Settings --> Release["版本号与 Changelog"]
  Settings --> Update["在线更新\n依赖预检 + 构建 + 自动重启"]
Loading

版本与 Changelog

版本信息由 internal/version 统一管理:

  • Version:当前版本号。
  • Commit:构建提交,可通过 -ldflags 注入。
  • BuildTime:构建时间,可通过 -ldflags 注入。
  • Changelog():结构化变更记录,用于 API 和设置页。

查看二进制版本:

.\bin\gpufleet-server.exe -version
.\bin\gpufleet-agent.exe -version

注入构建信息示例:

$commit = git rev-parse --short HEAD
$buildTime = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
go build `
  -ldflags "-X gpufleet/internal/version.Commit=$commit -X gpufleet/internal/version.BuildTime=$buildTime" `
  -o bin\gpufleet-server.exe .\cmd\gpufleet-server

Web 设置页通过登录后的接口读取版本信息:

GET /api/v1/version
flowchart TD
  Source["internal/version"] --> CLI["-version 命令输出"]
  Source --> API["GET /api/v1/version\n需要 Web Session"]
  Source --> UI["设置页\n版本与变更"]
  Source --> Docs["CHANGELOG.md\n人工维护发布说明"]
  Build["go build -ldflags"] --> Source
Loading

服务端在线更新

服务端可以在设置页检查当前 Git 上游是否有新版本,并由管理员点击“拉取并重启”。该机制只操作服务端自身仓库和当前服务端进程,不会连接或修改任何客户端 Agent。

sequenceDiagram
  participant Admin as 管理员浏览器
  participant Server as GPUFleet Server
  participant Git as Git upstream

  Admin->>Server: GET /api/v1/admin/update/status
  Server->>Git: git fetch --quiet --prune
  Server-->>Admin: branch / local / upstream / ahead / behind / dirty
  Admin->>Server: POST /api/v1/admin/update/apply
  Server->>Server: 校验依赖 + clean working tree + upstream + fast-forward
  Server->>Server: 临时 worktree 构建远端提交
  Server->>Git: git pull --ff-only
  Server->>Server: 安排替换二进制并自动重启
  Server-->>Admin: restarting
Loading

安全约束:

  • 需要已登录的 Web Cookie Session。
  • 前端不能传入命令、分支、远端或路径。
  • 服务端只在 -repo-dir 指定的仓库目录内执行固定 Git 参数,并使用固定的 go build ./cmd/gpufleet-server 构建服务端。
  • 更新前会检查 gitgo、Windows 的 powershell.exe 或 Linux 的 /bin/sh、服务端源码入口和当前可执行文件目录写入权限。
  • 工作区存在未提交改动、没有 upstream、本地超前或分叉时拒绝拉取。
  • 构建成功后才会 fast-forward 当前工作区;随后重启器替换当前服务端二进制,并按原启动参数拉起新进程。

API 概览

Agent API:

POST /api/v1/agent/heartbeat
POST /api/v1/agent/samples
POST /api/v1/agent/process-snapshots

Web API:

GET  /api/v1/setup/status
POST /api/v1/setup/apply
POST /api/v1/auth/login
POST /api/v1/auth/logout
GET  /api/v1/version
GET  /api/v1/overview
GET  /api/v1/gpus/{gpu_id}/series
GET  /api/v1/stats/gpu-utilization
GET  /api/v1/processes/latest
GET  /api/v1/admin/database/download
POST /api/v1/admin/language
GET  /api/v1/admin/update/status
POST /api/v1/admin/update/apply
POST /api/v1/admin/devices
PATCH /api/v1/admin/devices/{device_id}
DELETE /api/v1/admin/devices/{device_id}
POST /api/v1/admin/devices/{device_id}/enable
POST /api/v1/admin/devices/{device_id}/disable
POST /api/v1/admin/devices/{device_id}/rotate-secret

完整契约见 docs/06-api-contract.md

测试与验证

Go 测试:

$env:GOCACHE='F:\project\GPUFleet\.gocache'
go test ./...

前端构建:

cd web
npm run build
cd ..

初始化 5 块 GPU 演示数据,其中 2 块属于同一设备,且包含 1 台离线设备:

node scripts\seed-demo-data.mjs --data-dir logs\manual-demo\data

浏览器级验证:

node scripts\verify-frontend-chrome.mjs `
  --url http://127.0.0.1:8088 `
  --password demo-admin `
  --out logs\frontend-verify-manual `
  --min-fleet-cards 5 `
  --require-offline-mask true `
  --require-dual-device true

验证脚本会检查登录、30 天 Cookie 会话恢复、总览卡片、每卡历史图表、悬浮读数、离线蒙版、同设备边框同色、深浅主题、移动端无横向溢出、设置页操作入口、在线更新入口、版本号和 Changelog。

项目结构

cmd/
  gpufleet-server/      服务端入口
  gpufleet-agent/       Agent 入口
internal/
  agent/                采集、上报、本地队列
  auth/                 HMAC 签名
  disk/                 跨平台磁盘空间检测
  model/                API 数据模型
  server/               HTTP 服务、存储、会话、限流、fallback 面板
  version/              版本号与结构化 Changelog
web/
  src/                  React 面板源码
  public/brand/         SVG 品牌 Logo
  dist/                 已构建静态资源
scripts/                安装、卸载、演示数据、前端验证脚本
docs/                   设计、API、前端、测试和运维文档

详细文档

About

Lightweight self-hosted NVIDIA GPU fleet monitoring with read-only agents, secure ingestion, compressed storage, and a responsive React dashboard.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Contributors