Files
homelab/USAGE.md
T
Story Crater Bot 5b00616f41 docs: add foundation docs and cluster configuration templates
- README: cluster architecture, quick start, use cases
- USAGE: stack topology, custom CLI reference
- TROUBLESHOOTING: operational safety rules
- .env.example: configuration template
- Makefile: build shortcuts
2026-07-11 19:16:34 -07:00

218 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Cluster Architecture at a Glance
**Homelab** is a 2-node bare-metal Kubernetes cluster deployed with Talos Linux, designed for self-hosted services, observability, and GitOps-ready CI/CD.
### Deployment Stack (18 Helm releases)
| Layer | Component | Namespace | Purpose |
|-------|-----------|-----------|---------|
| **OS & Networking** | Talos Linux v1.13.3 | — | Immutable, declarative Linux |
| **CNI** | Cilium (eBPF) | kube-system | Advanced networking, no kube-proxy |
| **Ingress** | Nginx Ingress Controller | ingress-nginx | Reverse proxy, TLS termination |
| **Certificates** | cert-manager + homelab-ca | cert-manager | Self-signed CA, auto-renewal |
| **Storage (Block)** | Longhorn v1.7.0 | longhorn-system | Persistent volumes, default StorageClass |
| **Storage (Object)** | MinIO (3-node, site-repl) | storage | S3-compatible, multi-AZ replication |
| **Database** | CloudNativePG (3 replicas) | ddb | PostgreSQL 16 + pgvector |
| **IAM / OIDC** | Authentik | iam | Federated OIDC provider for all services |
| **Secrets** | HashiCorp Vault | iam | KV secrets backend, JWT auth |
| **Logs** | Loki (SingleBinary) | logging | 10-day retention, MinIO backend |
| **Log Collection** | Promtail (DaemonSet) | logging | Pod + kernel logs → Loki |
| **Metrics** | Prometheus + kube-state-metrics | monitoring | Time-series metrics, service discovery |
| **Dashboards** | Grafana | logging | Unified UI for Prometheus + Loki |
| **Uptime Monitoring** | Blackbox Exporter | monitoring | External endpoint probes |
| **Git Forge** | Forgejo (self-hosted) | cicd | Git server, OCI registry, Forgejo Actions |
| **CI Runner** | Forgejo Actions Runner | cicd | Privileged build pods, image push |
| **CD** | Argo CD | cicd | Pull-based GitOps, declarative deployments |
| **Message Queue** | Kafka (Strimzi KRaft mode) | sqs | SQS-like message queue service |
| **Queue Redis** | Redis | sqs | In-flight message tracking, dedup |
| **Queue API** | kmsvc (gRPC + REST) | sqs | Message service (SendMessage, ReceiveMessage, etc.) |
| **Workflows** | Temporal | temporal | Distributed workflow engine |
| **Container UI** | Portainer CE | dashboard | Pod/workload management UI |
| **Terminal** | Claude Terminal | dev-tools | Persistent dev environment (optional) |
| **Config Reload** | Reloader | reloader | Auto-reload pods on ConfigMap/Secret changes |
### Dependency Chain (Release Order)
```
cert-manager (root)
├─→ ingress-nginx
├─→ cilium (network policies)
└─→ cloudnative-pg
├─→ authentik (DB: authentik)
│ ├─→ vault (uses Authentik OIDC)
│ ├─→ forgejo (OIDC login)
│ ├─→ argocd (OIDC login)
│ └─→ kmsvc (JWT auth)
└─→ story-crater-backend (DB: story_crater)
storage (MinIO 3-node)
├─→ loki (object backend)
├─→ vault (unseal keys bucket)
└─→ monitoring (Prometheus scrape)
monitoring (Prometheus operator)
├─→ ingress-nginx (requires ServiceMonitor CRDs)
├─→ authentik (requires ServiceMonitor CRDs)
├─→ minio-az-a (requires ServiceMonitor CRDs)
└─→ temporal (requires ServiceMonitor CRDs)
logging (Loki + Grafana)
├─→ promtail (pod log collection)
└─→ grafana (dashboards)
sqs (Kafka + Message Queue)
├─→ strimzi-operator
├─→ kafka-cluster (KRaft mode, 3 brokers)
├─→ kmsvc-redis (in-flight tracking)
├─→ queue-crd (operator)
└─→ management-service (gRPC/REST API)
```
---
## Custom CLI — `talos`
Homelab cluster control CLI (`core/`). Manages cluster nodes and Vault secrets.
### Secret path convention
All secrets live under `cluster/<VARIABLE_NAME>`. The field name is always the variable name itself (SCREAMING_SNAKE_CASE), matching the `.env` key. Example paths:
```
cluster/ANTHROPIC_API_KEY
cluster/AUTHENTIK_FORGEJO_CLIENT_ID
cluster/AUTHENTIK_ARGOCD_CLIENT_SECRET
```
### `talos put` — write a secret to Vault
```bash
talos put cluster/VARIABLE_NAME VARIABLE_NAME="secret-value"
talos put cluster/FORGEJO_ADMIN_PASSWORD FORGEJO_ADMIN_PASSWORD="$FORGEJO_ADMIN_PASSWORD"
```
Field name = variable name — never `value`.
### `talos get` — fetch a secret from Vault
```bash
talos get cluster/VARIABLE_NAME --key VARIABLE_NAME # always specify --key
talos get cluster/FORGEJO_ADMIN_PASSWORD --key FORGEJO_ADMIN_PASSWORD
talos get cluster/VARIABLE_NAME --json # full secret as JSON
```
Note: `talos get` uses `--key` (long flag), not a positional arg — unlike `talos secrets get`.
### `vsource` — load a `.env` into the shell
zsh function (lives in `~/.zshrc`, not in the repo — can reference but cannot run directly).
Empty `.env` values are fetched from Vault at `cluster/<KEY>`; hardcoded values pass through.
```zsh
vsource # loads .env in current directory
vsource .env.local # loads a specific file
```
`.env` format — leave secrets empty, vsource resolves them from Vault:
```bash
ANTHROPIC_API_KEY= # fetched from cluster/ANTHROPIC_API_KEY
AUTHENTIK_ARGOCD_CLIENT_ID= # fetched from cluster/AUTHENTIK_ARGOCD_CLIENT_ID
DEBUG=true # hardcoded, passed through as-is
```
### Typical workflow for a generated secret
```bash
# 1. Store immediately after generation (keeps secrets out of shell history)
talos put cluster/AUTHENTIK_FORGEJO_CLIENT_SECRET AUTHENTIK_FORGEJO_CLIENT_SECRET="<paste>"
# 2. Use via subshell when creating K8s secrets
kubectl create secret generic my-secret \
--from-literal=client-secret="$(talos get cluster/AUTHENTIK_FORGEJO_CLIENT_SECRET --key AUTHENTIK_FORGEJO_CLIENT_SECRET)"
# 3. Or load into shell via vsource for helmfile/env-driven tools
vsource .env && helmfile apply
```
### IAM Management (Federated OIDC, Phases 16 Complete)
**Status:** ✅ Fully deployed (2026-07-02). Single federated OIDC provider (`talos-federation`) handles all service auth.
**Quick reference:**
```bash
# View roles and capabilities
talos iam roles list && talos iam roles describe admin
# Service registry (Grafana, MinIO, Forgejo, etc.)
talos iam services list && talos iam services describe grafana
# Agents (admin-bot, ci-bot with auto-rotation)
talos iam agents list && talos iam agents rotate ci-bot
# Role bindings (user → role with TTL)
talos iam bindings grant [email protected] devops --expires 2026-12-31
talos iam bindings list
# Audit trail (90-day retention, 12 event types)
talos iam audit list && talos iam audit export --format json
# OIDC provider sync with Authentik
talos iam providers sync-authentik
```
**See `homelab/CLAUDE.md` § IAM Management for full reference** (roles, services, agents, bindings, audit, providers).
**Vault paths:** All IAM state stored under `cluster/iam/{federation,roles,services,agents,bindings}`.
### CI/CD Image Registry Authentication (Forgejo + Runner)
**After IAM Phase 6 changes:** All image push/pull operations via CI runner require JWT token authentication through Authentik → Vault.
**Push images to Forgejo registry:**
```bash
# 1. Get ci-bot JWT token (runner has this injected via ServiceAccount)
export REGISTRY_TOKEN=$(talos get cluster/iam/agents/ci-bot --key token)
# 2. Authenticate docker/podman to Forgejo registry
docker login forgejo.riotpiao.homelab.com \
--username ci-bot \
--password "$REGISTRY_TOKEN"
# 3. Tag and push image
docker tag myapp:latest forgejo.riotpiao.homelab.com/rock/myapp:latest
docker push forgejo.riotpiao.homelab.com/rock/myapp:latest
```
**Pull images in runner (automatic):**
```bash
# Inside .forgejo/workflows/*.yml, runner pulls via K8s ServiceAccount
# No explicit login needed — imagePullSecrets injected by runner pod
image: forgejo.riotpiao.homelab.com/rock/myapp:latest
```
**Runner pod setup:**
```bash
# ServiceAccount (in cicd namespace) has Vault JWT auth injected
kubectl get serviceaccount -n cicd forgejo-runner
kubectl describe sa forgejo-runner -n cicd
# ImagePullSecret auto-mounted from K8s secret:
kubectl get secret -n cicd | grep forgejo-registry
```
**Vault paths for credentials:**
```
cluster/iam/agents/ci-bot # JWT token for push authentication
cluster/iam/agents/admin-bot # Alternative admin agent (if needed)
```
---