πΊοΈ Cluster Navigation Map¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β KUBERNETES CLUSTER β
β (192.168.30.51:6443) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββ
β β β
βΌ βΌ βΌ
βββββββββββββββββ βββββββββββββββββββ ββββββββββββββββββ
β my-apps/ β β kube-system/ β β flux-system/ β
β βββββββββββββββ β βββββββββββββββββ β ββββββββββββββββ β
β β β β β β
β βββββββββββββββββ΄βββ β βββββββββββββββ΄β β ββββββββββββ β
β β media/ β β β core/ β β β ... β β
β β ββββββββββββββ β β β ββββββββββββββ΄β β β β β
β β β jellyfin/ β β β β β β β β
β β β immich/ β β β β networking/ β β β β
β β β owncast/ β β β β ββββββββββββββββββΌββ β ββββββββββ β β
β β β lidarr/ β β β β β β β β β β β
β β β radarr/ β β β β β system/ β β β β β β
β β β ... β β β β β ββββββββββββββββββΌββ β β β β β
β β ββββββββββββββ β β β βββββββββββββββββββ β β β β β β
β ββββββββββββββββββββ΄βββ β β β β β β β β
β β system pods β β β β β β β
βββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββ΄ββββββββββββββββββ΄βββββ
β
βΌ
ββββββββββββββββββββββββββββ
β Apps are deployed via β
β Flux (GitOps) β
β β
β Source: β
β ~/Projects/truecharts/ β
β β
β Edit config β Commit β β
β Push β Flux auto-appliesβ
ββββββββββββββββββββββββββββ
Directory tree¶
GitOps repo (truecharts):
truecharts/
βββ clusters/main/
β βββ kubernetes/ # Flux manifests (core, system, my-apps, β¦)
β βββ talos/ # Talos machine config
β βββ clusterenv.yaml # Cluster vars (encrypt via clustertool)
βββ repositories/ # HelmRepository defs
βββ custom_images/ # Images built to GHCR
βββ .sops.yaml
βββ README.md # Points here for docs
Docs repo (nerd.dad):
nerd.dad/docs/homelab/
βββ guides/ # Cluster guides (this section)
βββ kubernetes/ # Service notes + runbooks
π― Quick Find: Commands by Goal¶
Goal: Find Jellyfin Data¶
# 1. Check what's running
kubectl get pods -n media
# 2. Find the data volume
kubectl get pvc -n media | grep jellyfin
# 3. Access files
kubectl exec -n media jellyfin-<pod> -- ls /config/
# 4. Check pod logs
kubectl logs -n media jellyfin-<pod>
Goal: Find Immich Data¶
Goal: Access Downloader Apps¶
Goal: View Dashboards¶
π External URLs¶
Your cluster exposes these services externally:
| Service | URL/Port | Namespace | Purpose |
|---|---|---|---|
| Jellyfin | jellyfin.hoth.systems | media | Media server |
| Immich | (configured via ingress) | immich | Photo library |
| OwnCast | (configured via ingress) | owncast | Radio host |
| Dashboards | (configured via ingress) | my-apps | Monitoring |
To find ingress URLs:
π οΈ Workflow Examples¶
Deploying a New App¶
# 1. Go to my-apps/<app-name>/
cd ~/Projects/truecharts/clusters/main/kubernetes/my-apps/
# 2. Create app directory
mkdir <app-name>
# 3. Create ks.yaml with app definition
# 4. Create app/kustomization.yaml
# 5. Create app/helm-release.yaml
# 6. Commit and push
git add my-apps/<app-name>/
git commit -m "Add <app-name> app"
git push
# 7. Flux will automatically deploy!
# 8. Monitor with:
kubectl get pods -n <namespace>
Finding Secrets¶
# List all secrets
kubectl get secrets -A
# Find secret for specific app
kubectl get secrets -n media | grep -i jellyfin
# View secret contents
kubectl get secret <secret-name> -n namespace -o yaml
π Architecture Overview¶
Components¶
- Talos 1.11.2 - Container-native Linux OS
- Kubernetes 1.35+ - Container orchestration
- Flux v2.7.2 - GitOps controller
- Helm - Chart/package manager
- TrueCharts - Helm charts library
- Longhorn - Distributed storage (for PVCs)
Storage¶
- PVCs claim from storage class
- Longhorn provides RWO/RWX storage
- 100Gi PVCs common for media
π¨ Visual Structure¶
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β FLUX GITOPS SYSTEM β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β [Git Repo] βββΊ [Flux Controller] βββΊ [K8s API] β
β β β β β
β βΌ βΌ βΌ β
β [Config Files] [Reconciliation] [Running Podsβ
β β
β Edit config β Commit β Push β Flux applies β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Security Notes¶
Secrets Access¶
- Never commit plain-text secrets
- Use SOPS for encryption
- age.agekey for decryption
- .sops.yaml for SOPS configuration
Never Do¶
kubectl applydirectly (breaks GitOps)- Manually edit cluster resources
- Commit secrets to repo
π File Formats¶
Kustomization (kustomization.yaml)¶
resources:
- app/helm-release.yaml
- app/kustomization.yaml
images:
- name: jellyfin
newName: ghcr.io/your-registry/jellyfin
newTag: latest
Helm Release (helm-release.yaml)¶
apiVersion: helm.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: jellyfin
namespace: media
spec:
values: {...}
helmParams:
createCRDs: false
π Flux Commands¶
# Check all releases
flux get helmrelease -A
# Watch reconciliation
flux watch helmrelease <name> -n <ns>
# Get events
kubectl get events -n flux-system
Maintained by: itzteajay
GitOps workflow: edit truecharts β commit β push β Flux applies
Docs: nerd.dad Homelab