mirror of
https://github.com/Alkatrazz24/Funk-lab.git
synced 2026-07-08 05:34:43 +02:00
207 lines
7.5 KiB
Markdown
207 lines
7.5 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Présentation du projet
|
|
|
|
**Funk** — homelab IA composé d'un cluster Kubernetes (Talos) pour les services applicatifs, d'un hôte d'inférence LLM dédié (gpu-01 / LM Studio), et d'un agent autonome (Hermes Agent) sur storage-01. Stack IaC complète : Ansible + talhelper + ArgoCD.
|
|
|
|
Référence complète : `Funk/Funk-infra/HOMELAB.md`
|
|
|
|
**État actuel (2026-05-09)** :
|
|
- ✅ Hermes Agent opérationnel sur le poste perso (LM Studio local `127.0.0.1:1234`)
|
|
- ✅ storage-01 installé — `192.168.10.1` (LAN cluster), `192.168.1.200` (WAN)
|
|
- ✅ gpu-01 installé — ping OK depuis storage-01 (`192.168.10.20`)
|
|
- ⏳ Phase 1/2 en cours — Ansible, ROCm, LM Studio, dnsmasq, NAT restent à faire
|
|
- ❌ Repo `lab-infra/` à initialiser, aucun cluster k8s monté
|
|
|
|
---
|
|
|
|
## Architecture des machines
|
|
|
|
| Machine | IP | OS | Rôle |
|
|
|---|---|---|---|
|
|
| storage-01 | 192.168.10.1 | AlmaLinux 9.7 | Passerelle + bastion admin + données + Hermes Agent — **hors cluster** |
|
|
| compute-01 | 192.168.10.11 | Talos v1.13+ | k8s control-plane |
|
|
| compute-02 | 192.168.10.12 | Talos v1.13+ | k8s worker |
|
|
| compute-03 | 192.168.10.13 | Talos v1.13+ | k8s worker |
|
|
| gpu-01 | 192.168.10.20 | AlmaLinux 9.7 | LM Studio dédié (RX 6700XT) — **hors cluster** |
|
|
|
|
**Points clés d'architecture :**
|
|
- `storage-01` et `gpu-01` sont **hors du cluster k8s** — ils sont consommés via des `ExternalName` services ou `Endpoints` manuels
|
|
- Le cluster n'a que 3 nœuds (compute-01/02/03), pas de GPU dans k8s
|
|
- Single control-plane assumé : si compute-01 tombe, `kubectl apply` ne fonctionne plus mais les workloads continuent
|
|
|
|
---
|
|
|
|
## Structure du repo lab-infra (cible)
|
|
|
|
```
|
|
lab-infra/
|
|
├── ansible/ # gère storage-01 + gpu-01 (AlmaLinux)
|
|
│ ├── inventory.yml
|
|
│ ├── playbooks/site.yml
|
|
│ ├── group_vars/
|
|
│ └── roles/ # common, gateway, dnsmasq, nfs_server, postgresql,
|
|
│ # qdrant, minio, rocm, lm_studio, hermes_agent
|
|
├── talos/ # nœuds Talos via talhelper
|
|
│ ├── talconfig.yaml # source de vérité (lue par talhelper)
|
|
│ ├── talsecret.sops.yaml
|
|
│ ├── talenv.yaml
|
|
│ ├── patches/
|
|
│ └── clusterconfig/ # généré → au .gitignore, ne pas committer
|
|
└── k8s/ # workloads k8s (ArgoCD)
|
|
├── argocd-bootstrap/
|
|
├── apps-of-apps/root.yaml
|
|
├── infra/ # metallb, traefik, cert-manager, longhorn, nfs-provisioner
|
|
└── apps/ # litellm, open-webui, n8n, monitoring,
|
|
# external-services (ExternalName vers storage-01/gpu-01)
|
|
```
|
|
|
|
---
|
|
|
|
## Stack IaC — trois outils, trois cibles
|
|
|
|
| Outil | Cible | Déclenchement |
|
|
|---|---|---|
|
|
| **Ansible** | storage-01, gpu-01 (AlmaLinux) | Push manuel : `ansible-playbook` |
|
|
| **talhelper** | compute-01/02/03 (Talos) | Push manuel : `talosctl apply-config` |
|
|
| **ArgoCD** | Workloads k8s | Pull automatique depuis Git |
|
|
|
|
### Ansible
|
|
|
|
```bash
|
|
cd ansible/
|
|
ansible-playbook -i inventory.yml playbooks/site.yml --check # dry-run
|
|
ansible-playbook -i inventory.yml playbooks/site.yml # apply
|
|
ansible-playbook -i inventory.yml playbooks/site.yml --tags rocm # un rôle
|
|
```
|
|
|
|
Rôles prévus : `common`, `gateway`, `dnsmasq`, `nfs_server`, `postgresql`, `qdrant`, `minio`, `rocm`, `lm_studio`, `hermes_agent`. Tous idempotents. Secrets via Ansible Vault.
|
|
|
|
### talhelper (nœuds Talos)
|
|
|
|
```bash
|
|
cd talos/
|
|
talhelper genconfig # régénérer configs nœuds
|
|
talhelper gencommand apply --node compute-02 | bash # appliquer sur un nœud
|
|
talhelper gencommand bootstrap --node compute-01 | bash # bootstrap (1ère fois seulement)
|
|
talhelper gencommand kubeconfig | bash # récupérer kubeconfig
|
|
```
|
|
|
|
`talos/clusterconfig/` est généré — ne pas committer (mettre au `.gitignore`).
|
|
|
|
### ArgoCD (workloads k8s)
|
|
|
|
Pattern "App of Apps" : modifier un manifest → `git commit` + `git push` → ArgoCD applique automatiquement (poll toutes les ~3 min).
|
|
|
|
```bash
|
|
vim k8s/apps/open-webui/deployment.yaml
|
|
git add k8s/apps/open-webui/
|
|
git commit -m "open-webui: bump to v0.4.0"
|
|
git push
|
|
```
|
|
|
|
---
|
|
|
|
## Réseaux internes Kubernetes
|
|
|
|
- CNI (Flannel) — Pods : `10.42.0.0/16`
|
|
- Services : `10.43.0.0/16`
|
|
- MetalLB pool (IP virtuelles Traefik/services) : `192.168.10.200-230`
|
|
|
|
---
|
|
|
|
## Contrainte GPU critique
|
|
|
|
La RX 6700XT (gfx1031) n'est **pas officiellement supportée** par ROCm. Sur gpu-01, toujours s'assurer que la variable est présente dans l'environnement LM Studio / le service systemd :
|
|
|
|
```
|
|
HSA_OVERRIDE_GFX_VERSION=10.3.0
|
|
```
|
|
|
|
ROCm tourne directement sur l'hôte AlmaLinux (pas dans des conteneurs). Fallback : Vulkan dans LM Studio si ROCm coince.
|
|
|
|
LM Studio bind sur `127.0.0.1` par défaut → pour l'exposer au réseau :
|
|
```bash
|
|
lms server start --port 1234 --bind 0.0.0.0
|
|
```
|
|
|
|
CLI LM Studio utile : `lms ls`, `lms load <model>`, `lms unload`, `lms server status`
|
|
|
|
---
|
|
|
|
## Deux setups IA
|
|
|
|
### Setup 1 — Poste perso (9950X3D) — dev local
|
|
|
|
| Composant | Endpoint |
|
|
|---|---|
|
|
| LM Studio | `http://127.0.0.1:1234/v1` |
|
|
| Ollama | `http://127.0.0.1:11434` |
|
|
| Hermes Agent | `base_url: http://127.0.0.1:1234/v1` |
|
|
|
|
```bash
|
|
# Prérequis : modèle chargé avec context suffisant (system prompt Hermes ≈ 15 000 tokens)
|
|
lms load <modele> --context-length 16384
|
|
lms server start --port 1234
|
|
```
|
|
|
|
Agents Goose dans `Funk/Funk-infra/agents/` — pointent tous sur `http://localhost:1234/v1` :
|
|
```bash
|
|
cd Funk/Funk-infra/agents/<nom-agent>
|
|
goose session --config goose-config.yaml
|
|
```
|
|
|
|
### Setup 2 — Cluster Funk (production)
|
|
|
|
| Composant | Endpoint |
|
|
|---|---|
|
|
| LM Studio (gpu-01) | `http://192.168.10.20:1234/v1` |
|
|
| Hermes Agent | service systemd sur storage-01, pointe sur gpu-01 |
|
|
|
|
```bash
|
|
# Sur gpu-01 — HSA_OVERRIDE requis pour RX 6700XT (gfx1031)
|
|
HSA_OVERRIDE_GFX_VERSION=10.3.0 lms load <modele> --context-length 16384
|
|
lms server start --port 1234 --bind 0.0.0.0
|
|
```
|
|
|
|
Détail complet des deux setups : `Funk/Funk-infra/HOMELAB.md` § 7.4
|
|
|
|
---
|
|
|
|
## Conventions
|
|
|
|
- **Domaine** : `lab.local` — wildcard DNS via dnsmasq sur storage-01
|
|
- **Ingress** : `<service>.lab.local` → IP MetalLB de Traefik (`192.168.10.200-230`)
|
|
- **LM Studio endpoint** : `http://192.168.10.20:1234/v1`
|
|
- **Namespaces k8s** : `argocd`, `infra`, `storage`, `external`, `ai`, `workflows`
|
|
- **Git** : branches `main` (prod) / `feature/*` — commits en conventional commits (`feat:`, `fix:`, `chore:`, `docs:`)
|
|
- **Secrets** : Ansible Vault (Ansible), SOPS+age (Talos via talhelper), Sealed Secrets (k8s)
|
|
|
|
## Opérations cluster importantes
|
|
|
|
**etcd backup** (single control-plane → critique) :
|
|
```bash
|
|
talosctl etcd snapshot /path/to/backup.db --nodes compute-01
|
|
```
|
|
À planifier en cron Ansible vers le RAID5 de storage-01.
|
|
|
|
**Hermes Agent** — données persistantes dans `~/.hermes/` → doit résider sur le RAID5, pas sur le SSD OS.
|
|
|
|
**Ce qui reste toujours manuel** (GitOps ne peut pas bootstrapper lui-même) :
|
|
- Installation OS depuis USB (AlmaLinux ou Talos)
|
|
- Configuration IP/SSH minimale pour le premier Ansible
|
|
- Premier déploiement ArgoCD via Helm
|
|
|
|
---
|
|
|
|
## RAM serrée sur compute-02/03 (8 GB)
|
|
|
|
Toujours définir `resources.requests` et `resources.limits` sur les pods déployés sur ces nœuds — sans quoi l'OOM-killer peut tuer kubelet.
|
|
|
|
Réservations à configurer dans talhelper :
|
|
```
|
|
system-reserved: cpu=500m,memory=1Gi
|
|
kube-reserved: cpu=500m,memory=1Gi
|
|
```
|