Files
homelab-frontend/README.md
T

105 lines
4.6 KiB
Markdown
Raw Normal View History

2026-08-19 20:52:13 -07:00
# homelab-frontend
A Go API gateway for the homelab cluster. One capability per subdomain, one auth
implementation, one routing table.
Replaces Kong OSS entirely — see
[ADR-0001](docs/adr/ADR-0001-retire-kong-for-go-gateway.md) for why, and
[docs/MIGRATION-kong.md](docs/MIGRATION-kong.md) for the cutover.
## Position in the stack
```
browser / SDK ──▶ Cloudflare ──▶ ingress-nginx (TLS, edge)
┌─────────────────────────────┐
│ homelab-frontend │
│ routing · authn · budgets │
└──────────────┬──────────────┘
/v1 /sqs /workflow /cluster
│ │ │ │
▼ ▼ ▼ ▼
llm-serving kmsvc/Kafka temporal atlas
(predictors) (sqs ns) (temporal ns) (riotpiao-backend)
└──── in-cluster Services ────┘
```
ingress-nginx keeps TLS and the edge. The gateway owns everything after it.
Backend services are reached through the gateway rather than published
individually — a single place for authentication, budgets, timeouts and
observability, and a single hostname surface to reason about.
## Capability map
One host, one path prefix per capability.
| Prefix on `api.riotpiao.com` | Backs onto | Status |
|---|---|---|
| `/v1/*` | `llm-serving` predictors (vLLM, Ollama, TEI) | migrating off Kong |
| `/sqs/*` | kmsvc management-service + Kafka/Strimzi (`sqs` ns) | future |
| `/workflow/*` | Temporal (`temporal` ns) | future |
| `/cluster/*` | atlas — cluster topology / Argo delivery (separate repo) | future |
| `/db/*` | CloudNativePG, MinIO, monitoring/metrics reads | future |
`/v1/*` is reserved for the OpenAI-compatible surface. An SDK expects
`/v1/chat/completions` at the base URL, so that prefix cannot be repurposed.
Paths rather than subdomains: one DNS record, one tunnel hostname, one Ingress.
Promoting a prefix to its own subdomain later is additive and can run alongside the
path — the reverse is not, because clients hardcode hostnames.
atlas lives in its own repo (`riotpiao-backend`) and keeps its own informers and
RBAC. The gateway routes to it; it does not absorb it. Cluster-read permissions
stay out of the public edge process.
## Design rules
1. **Standard protocol shapes.** `POST /v1/chat/completions` selects its model from
the request body, like every OpenAI-compatible server. No path-per-model, no
bespoke client configuration. Kong OSS could not do this; that limitation does
not survive into the replacement.
2. **Bearer tokens, validated against Authentik.** JWKS is fetched at runtime and
cached, so key rotation needs no runbook and no pinned PEM.
3. **Policy lives where the state is.** GPU slot semaphores, per-caller budgets,
queue depth and disconnect propagation are application concerns. They belong
here, not in a proxy plugin.
4. **Streaming is first-class.** SSE and WebSocket pass through unbuffered, and a
client disconnect cancels the upstream request rather than orphaning it.
5. **The gateway holds no cluster credentials.** It proxies to services that do.
## Layout
```
cmd/gateway/ entrypoint
internal/
auth/ Authentik OIDC, JWKS cache, service-account tokens
llm/ model registry, body-based dispatch, upstream map
queue/ sqs.riotpiao.com surface
workflow/ workflow.riotpiao.com surface
proxy/ reverse proxy, streaming, timeouts, disconnect propagation
config/ upstream + route configuration
observability/ Prometheus metrics, structured logging
deploy/
base/ Kubernetes manifests
argocd/ Argo Application
docs/adr/ architecture decision records
tasks/ task board — see tasks/INDEX.md
testdata/ fixtures for offline tests
```
## Local development
The gateway must be runnable with no cluster, no kubeconfig and no credentials, so
that changes can be verified in a closed loop before touching live traffic.
Upstreams are configuration, so pointing them at local stubs is the whole
mechanism. See [tasks/INDEX.md](tasks/INDEX.md).
## Status
Scaffolded 2026-08-19. Nothing is wired yet. Kong is still serving live traffic on
`api.riotpiao.com`.