Skip to main content

Architecture and concepts

πŸ“š Documentation home β€” this page is the system overview. For how to drive the screens, see the user and administrator manuals.

In one paragraph​

GShare does not split GPUs itself. The actual partitioning is done by HAMi β€” vGPUs bounded by VRAM and core limits β€” or by handing over a full card. GShare is the control plane on top: it decides who gets what, for how long, and at what cost. On ordinary Kubernetes plus HAMi it adds session admission, occupancy-based billing, hierarchical limits, and reclamation of idle resources, so that many organizations, groups, and users can share one cluster.

Components and flow​

users and administrators
β”‚ browser
β–Ό
console (frontend, React SPA) ── user and admin screens, REST + SSE
β”‚ REST / SSE
β–Ό
control plane (backend, Python/FastAPI) ── owns state and money: authentication,
β”‚ β”œ gshare-api : admission, CRUD, token issuing authorization, credits,
β”‚ β”” gshare-worker : billing, budget rollup, queue, budgets, catalog,
β”‚ refills policy, scheduling
β”‚ applies GShareSession CR (via kubeconfig) β–² signed status and inventory
β–Ό β”‚ callbacks (internal JWT)
operator (Go, one per cluster) ──▢ Pod / Service / Ingress / Secret (gshare-sessions)
β”‚ session pod = interactive environment
β–Ό (VS Code, JupyterLab, web terminal)
HAMi + GPU nodes ── real partitioning (gpumem / gpucores) or a full card

postgres (state and ledger) Β· redis (queue, tokens, locks)
ComponentLanguage and locationResponsibilityDetails
ConsoleReact + TypeScript Β· frontend/User and administrator SPA over REST and SSEfrontend/README
Control planePython + FastAPI Β· backend/Authority on money and session state: admission, CRUD, tokensbackend/README
OperatorGo Β· operator/Reconciles GShareSession resources into pods, services, and ingress; reports status backoperator/README
GPU partitioningHAMi (external)vGPUs bounded by VRAM and cores, or exclusive full cardsβ€”

The control plane is cluster-agnostic: it applies custom resources to external GPU clusters through their kubeconfig, and each cluster's operator reconciles them and replies with status and inventory over a signed internal JWT callback. Decisions about money and state are made only in the control plane.

Core concepts​

  • Offering β€” the catalog of GPU models. One row per full-card model, carrying the hourly credit rate. Chosen when a session is created.
  • Preset β€” the catalog of session sizes: compute (CPU, memory, disk) plus a GPU fraction tier (XL Β½, L ΒΌ, M β…›, S 1/16) or an exclusive full card. VRAM and core limits are derived by applying the tier fraction to the offering's full-card VRAM.
  • Session β€” an interactive working environment, backed by a pod. Its mode is either fractional (a share of VRAM and cores) or exclusive (the whole card). MIG is a per-card pool, not a session mode: profile-aligned fractional requests may land on a MIG instance transparently.
  • Occupancy β€” max(VRAM fraction, core fraction). Billing is rate Γ— occupancy Γ— runtime; an exclusive session has occupancy 1.0.
  • Credits, wallets, budgets β€” credits are allocated down a hierarchy of wallets (system β†’ organization β†’ group β†’ individual), but a session is billed only to the requester's own personal wallet. A budget is a separate per-scope limit gate that can either warn or block.
  • Resource policy β€” limits on concurrent sessions, total allocated resources, and idle timeout. Resolved most-specific first: user β†’ group β†’ organization β†’ global.
  • Pause and resume β€” pausing tears the pod down so the operator returns the GPU (another session can take it immediately) and compute billing stops, while the session itself is preserved; retained volumes are free. Resuming re-acquires a GPU and rebuilds the pod. Idle GPU sessions can be paused automatically by policy, which is how capacity is reclaimed.
  • Queue and priority β€” when capacity is exhausted a session enters the queue instead of failing, and is admitted in priority order as resources come back.
  • Volumes β€” persistent personal or group storage, read-only or read-write, shareable. Snapshots are not implemented yet (the API answers 501). Not billed: storage is bounded by the per-user and per-group quotas in the resource policy, not by credits.
  • RBAC β€” super_admin (everything), org_admin (one organization), group_admin (one group), and member / guest. The user console and the administrator console are separate surfaces.
  • CUDA compatibility β€” an image whose CUDA version is below the offering's min_cuda is rejected.

Session admission​

A create-session request has to pass these gates, in order, before anything starts:

  1. References and CUDA β€” the offering, image, and wallet exist, and the image's CUDA version satisfies the offering.
  2. Mount permissions β€” the requested volumes are accessible in the requested mode.
  3. Billing wallet β€” the target wallet is the requester's own personal wallet.
  4. Resource policy quota β€” concurrency and total-resource limits (user β†’ group β†’ organization β†’ global).
  5. Budget gate β€” the scope budget; a blocking budget rejects the request when exceeded.
  6. Credit hold β€” the estimated cost is reserved from the balance; insufficient balance is rejected.
  7. VRAM reservation β€” an occupancy-aware two-dimensional best fit picks a card. If none fits, the session is queued.
  8. Handoff to the operator β€” the custom resource is applied, the pod starts, the running callback arrives, and billing begins.

CPU-only sessions are free and skip the budget, hold, VRAM, queue, and GPU steps entirely.

What makes it different​

On top of a partitioning mechanism (HAMi), GShare combines occupancy-aware placement and billing, automatic reclamation of idle GPUs through pause, in-place GPU yield with preemptive lending (lossless hand-off and resume), and hierarchical limit management.

Namespaces​

NamespacePurpose
gshare-systemControl plane: api, worker, operator, Postgres, Redis, ingress
gshare-sessionsTenant session pods; Pod Security Admission enforces baseline and audits/warns at restricted
gshare-infraPrivileged DaemonSets: node-problem-detector, Spegel, image pre-puller

Per-node metrics agent (optional)​

gshare-agent is a DaemonSet that reads each session's cgroup v2 counters directly on the node β€” cpu.stat and memory.current, the same files cAdvisor reads β€” once a second, and posts batches to the control plane over the internal JWT. The samples live in Redis as a five-minute ring per session and are served by GET /sessions/{id}/usage/live; the session page uses them for the CPU and memory lines when the DaemonSet is reporting and falls back to the Prometheus series when it is not.

It exists for one reason: cAdvisor aggregates on its own ~10 s housekeeping cycle, so no scrape interval makes a scraped reading fresher than that. Measured on a two-vCPU load, the agent shows the change in about a second where the metrics pipeline takes ten to thirty.

The agent is off by default, runs in the infra namespace (its read-only /sys/fs/cgroup bind needs a namespace that permits hostPath), holds no privileges, and reads only pods on its own node. Nothing depends on it: Prometheus remains the record, the only source of GPU and host series, and the source of the permanent per-session summary written at termination.