Funk-lab/archive/Funk/HOMELAB.md
ALI YESILKAYA c023ab0e58
docs: passe de cohérence documentaire (STT, Ghostfolio, embeddings, Qdrant) (#15)
Aligne la documentation sur l'état réel du cluster au 2026-06-18 :

- Qdrant : crash-loop résolu le 17/06 (statut « HS / EN COURS » corrigé dans
  CLAUDE.md, README, admin/ia/rag.md, admin/incidents.md, admin/ia/stt.md).
  Précision : collection funk-docs supprimée lors de la réparation → re-ingest
  RAG encore à faire (pas de surévaluation du statut).
- STT (assistant vocal « Jarvis ») : ajouté partout (était déployé mais non documenté).
- Ghostfolio : ajouté partout (était déployé mais non documenté).
- Embeddings dédiés nomic-embed-text :1238 : marqués opérationnels (roadmap
  README disait encore « TODO »).
- llama-server : ×3 → ×4 (instance embeddings) ; gap IaC précisé (embeddings géré
  par le rôle, seules les 2 instances CPU restent manuelles).
- Structure k8s/ corrigée dans CLAUDE.md : ajout stt/ + ghostfolio/, suppression
  des sous-dossiers traefik/ + metallb/ inexistants (installés via helm au bootstrap).
- Namespaces et liste des secrets Vault (vault_pg_ghostfolio_password) complétés.
- admin/README.md : index complété (~10 docs manquants : email, n8n, open-webui,
  ghostfolio, k9s, stt, rag, hermes-voice/souls/auto-improve, alertmanager-webhook).
- Funk/ (conception d'origine : LM Studio + agents Goose, obsolète) déplacé sous
  archive/ avec bandeau « obsolète » + archive/README.md (historique git préservé).


Claude-Session: https://claude.ai/code/session_017Qjq5jHiqNepnobJpHYpCa

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-18 11:16:34 +02:00

35 KiB
Raw Blame History

Homelab IA — Architecture et plan de déploiement

⚠️ DOCUMENT OBSOLÈTE — ARCHIVE HISTORIQUE

Ceci est la conception d'origine du homelab (pré-Funk-lab). Il décrit des choix abandonnés : inférence via LM Studio (remplacée par llama-server / ROCm) et agents Goose (remplacés par Hermes Agent). Ce document ne fait plus foi.

👉 Référence à jour : CLAUDE.md et la base de connaissance admin/. Conservé pour mémoire uniquement — voir archive/README.md.

Document de référence consolidé pour le déploiement d'un homelab IA combinant un cluster Kubernetes (Talos) pour les services applicatifs et deux hôtes Linux dédiés pour l'inférence LLM (LM Studio) et l'agent autonome (Hermes Agent). Stack IaC complète : Ansible + talhelper + ArgoCD, GitOps de bout en bout. À utiliser comme contexte pour Claude Code.


1. Objectifs

  • Faire tourner Hermes Agent (Nous Research) comme agent autonome auto-amélioré, alimenté par LM Studio comme serveur d'inférence local.
  • Apprendre Kubernetes en environnement réaliste (cluster multi-nœuds, GitOps) pour les services applicatifs (Open WebUI, n8n, monitoring...).
  • Apprendre Talos Linux (OS immuable, API-only, pensé pour Kubernetes).
  • Maximiser l'utilisation du GPU AMD RX 6700XT pour l'inférence LLM.
  • Tout gérer en Infrastructure as Code (versionné dans Git).

2. Priorités (par ordre)

  1. Facilité d'administration
  2. Apprentissage / montée en compétences
  3. Performance brute (utiliser le 6700XT au max)
  4. Haute disponibilité / résilience

3. Vision long terme

  • Cible : ~10 machines à 2-3 ans, mix Talos (cluster k8s) + AlmaLinux (services natifs)
  • Tout doit être reproductible depuis Git (réinstall complète possible en quelques heures)
  • BlueBanquise reste une option à reconsidérer si on dépasse 25+ hôtes Linux classiques ou si on ajoute du HPC/Slurm

4. Inventaire matériel

Machine CPU RAM Stockage Réseau Rôle
storage-01 AMD Ryzen 3 3200G (Zen+, 2019) 32 GB DDR4 1× SSD OS + 4×1 TB RAID5 (2.7 TB exploitables) 1× Gigabit Hors cluster — passerelle + admin + stockage + Hermes Agent
compute-01 AMD A10-9700E (Excavator, 2016) 16 GB DDR3 SSD SATA 1× Gigabit (r8169) k8s control-plane (Talos)
compute-02 AMD A10-9700E 8 GB DDR3 SSD SATA 1× Gigabit (r8169) k8s worker (Talos)
compute-03 AMD A10-9700E 8 GB DDR3 SSD SATA 1× Gigabit (r8169) k8s worker (Talos)
gpu-01 AMD Ryzen 9 5950X (16 cœurs) 32 GB DDR4 NVMe 1 TB 1× Gigabit Hors cluster — hôte LM Studio dédié — RX 6700XT 12 GB
switch Netgear GS308EV4 (8 ports Gigabit, managé Plus, VLAN 802.1Q) Switch principal

Validation Talos déjà effectuée : compute-01 boote correctement avec Talos v1.13.0 en mode maintenance, IP DHCP obtenue, chipset r8169 reconnu nativement.


5. Architecture réseau

5.1. Topologie physique

   Internet
       │
   ┌───────────┐
   │  Freebox  │ 192.168.1.254 (gateway + DHCP LAN domestique)
   └─────┬─────┘
         │
         │ VLAN 1 (port 1)
         │
   ┌─────┴────────────────────────────────────────┐
   │         Switch Netgear GS308EV4              │
   │  P1  P2  P3  P4  P5  P6  P7  P8             │
   │  V1  V1  V10 V10 V10 V10 V10 V1             │
   └──┬───┬───┬───┬───┬───┬───┬───┬──────────────┘
      │   │   │   │   │   │   │   └── PC perso (192.168.1.x)
      │   │   │   │   │   │   └────── storage-01 NIC2 (192.168.10.1) ← LAN cluster
      │   │   │   │   │   └────────── compute-03 (.10.13)
      │   │   │   │   └────────────── compute-02 (.10.12)
      │   │   │   └────────────────── compute-01 (.10.11)
      │   │   └────────────────────── gpu-01 (.10.20)
      │   └────────────────────────── storage-01 NIC1 (192.168.1.200) ← WAN
      └────────────────────────────── Freebox

   ┌──────────────────────────────┐
   │  storage-01 (AlmaLinux 9.7)  │
   │   - NIC1 (port 2) : 192.168.1.200   ← WAN / LAN domestique
   │   - NIC2 (port 7) : 192.168.10.1   ← LAN cluster + gateway + NAT
   └─────┬────────────────────────┘
         │ (routage + NAT entre les deux interfaces)
         │
    ┌────┴────┬──────────┬──────────┐
    │         │          │          │
 compute-01 compute-02 compute-03 gpu-01
 .10.11    .10.12     .10.13     .10.20
 (Talos)   (Talos)    (Talos)    (AlmaLinux + LM Studio)

5.2. Vue logique des composants IA

┌──────────────────────────────────────────────────────────────────────┐
│                      Cluster Kubernetes (Talos)                      │
│                  3 nœuds : compute-01/02/03                          │
│                                                                      │
│   • Open WebUI          • Traefik (ingress)                          │
│   • LiteLLM (proxy)     • MetalLB (LB L2)                            │
│   • n8n (workflows)     • cert-manager                               │
│   • Prometheus/Grafana  • ArgoCD (GitOps)                            │
└──────────────────┬─────────────────────────┬─────────────────────────┘
                   │                         │
                   │ NFS / S3 / DB           │ HTTP /v1/chat/completions
                   ▼                         ▼
┌──────────────────────────────┐   ┌──────────────────────────────────┐
│  storage-01 (AlmaLinux 9.7)  │   │  gpu-01 (AlmaLinux 9.7)          │
│  192.168.10.1  HORS CLUSTER  │   │  192.168.10.20  HORS CLUSTER     │
│                              │   │                                  │
│  Données :                   │   │  • LM Studio (mode serveur)      │
│  • NFS (/srv/nfs/k8s)        │   │    écoute sur :1234              │
│  • PostgreSQL                │   │  • API OpenAI-compatible         │
│  • Qdrant (vectoriel)        │   │  • RX 6700XT via ROCm/Vulkan     │
│  • MinIO (S3)                │   │  • CLI `lms` pour pilotage       │
│                              │   │                                  │
│  Agent IA :                  │   │                                  │
│  • Hermes Agent ★            │◄──┤  Hermes appelle LM Studio        │
│    (service systemd)         │   │  via http://192.168.10.20:1234   │
│                              │   │                                  │
│  Infra :                     │   │                                  │
│  • Passerelle / NAT          │   │                                  │
│  • dnsmasq (lab.local)       │   │                                  │
│  • Bastion admin             │   │                                  │
└──────────────────────────────┘   └──────────────────────────────────┘

5.3. Plan d'adressage IP

LAN domestique (existant, géré par la Freebox) — 192.168.1.0/24

IP Hôte Notes
192.168.1.254 Freebox Gateway internet + DHCP
192.168.1.10 Machine 9950x3d (poste perso) Déjà occupé
192.168.1.200 storage-01 (interface WAN cluster) IP statique réservée

LAN cluster (nouveau, isolé) — 192.168.10.0/24

IP Hostname Rôle
192.168.10.1 storage-01 Gateway + admin + stockage + Hermes Agent (hors cluster k8s)
192.168.10.11 compute-01 k8s control-plane (Talos, 16 GB)
192.168.10.12 compute-02 k8s worker (Talos, 8 GB)
192.168.10.13 compute-03 k8s worker (Talos, 8 GB)
192.168.10.20 gpu-01 Hôte LM Studio dédié (AlmaLinux, hors cluster k8s)
192.168.10.200-230 (pool) MetalLB — IP virtuelles des services k8s exposés

Ports applicatifs notables

Hôte Port Service Notes
gpu-01 1234 LM Studio API (OpenAI-compatible) http://192.168.10.20:1234/v1
storage-01 22 SSH (bastion + cible Ansible)
storage-01 53 dnsmasq Résolution *.lab.local
storage-01 2049 NFS Export /srv/nfs/k8s
storage-01 5432 PostgreSQL
storage-01 6333 Qdrant HTTP
storage-01 9000 MinIO S3
storage-01 9001 MinIO Console
MetalLB 80/443 Traefik Tous les Ingress du cluster
MetalLB 8080 ArgoCD UI argocd.lab.local

Réseaux internes Kubernetes (ne pas modifier sauf raison spécifique)

  • Pods (Flannel) : 10.42.0.0/16
  • Services : 10.43.0.0/16

5.4. Câblage du switch GS308EV4

Tous les ports en mode Access (pas de trunk). storage-01 utilise deux NICs physiques — une par VLAN.

Port Connecté à VLAN Mode
1 Freebox 1 - Default Access
2 storage-01 NIC1 (WAN, 192.168.1.200) 1 - Default Access
3 gpu-01 (192.168.10.20) 10 - cluster-funk Access
4 compute-01 (192.168.10.11) 10 - cluster-funk Access
5 compute-02 (192.168.10.12) 10 - cluster-funk Access
6 compute-03 (192.168.10.13) 10 - cluster-funk Access
7 storage-01 NIC2 (LAN cluster, 192.168.10.1) 10 - cluster-funk Access
8 PC perso (192.168.1.x) 1 - Default Access

Avantage vs trunk : pas de subinterface eno1.10 à configurer — deux interfaces physiques classiques dans NetworkManager. Plus simple, moins de risque d'erreur au démarrage.

5.5. Route statique sur la Freebox

À configurer dans Paramètres Freebox > Mode avancé > Configuration de routage :

Réseau de destination : 192.168.10.0
Masque                : 255.255.255.0
Passerelle            : 192.168.1.200

Cela permet à toutes les machines du LAN domestique de joindre directement le LAN cluster.


6. Choix d'OS

Machine OS Justification
storage-01 AlmaLinux 9.7 minimal Stack RHEL maîtrisée, stabilité, support sécurité jusqu'en 2032, doc abondante NFS/nftables/MinIO/Postgres
compute-01 Talos Linux v1.13+ Choix d'apprentissage assumé, validation matérielle OK
compute-02 Talos Linux v1.13+ idem
compute-03 Talos Linux v1.13+ idem
gpu-01 AlmaLinux 9.7 minimal Cohérence RHEL avec storage-01, ROCm via repo officiel AMD pour RHEL 9

Note sur AlmaLinux + ROCm pour gpu-01 : la majorité de la doc communautaire ROCm + RX 6700XT vise Ubuntu. Sur AlmaLinux 9, utiliser le repo officiel AMD pour RHEL 9 (https://repo.radeon.com/rocm/). Adapter les commandes dnf au lieu d'apt. En cas de blocage ROCm, Vulkan reste un fallback fonctionnel pour LM Studio.


7. Architecture applicative

7.1. Topologie cluster Kubernetes

  • Control-plane : single (compute-01 uniquement)
  • Workers : compute-02, compute-03
  • storage-01 et gpu-01 sont HORS du cluster

7.2. Découpage des responsabilités

gpu-01 — Hôte d'inférence LLM (hors cluster)

  • LM Studio en mode serveur headless
  • API OpenAI-compatible exposée sur :1234

storage-01 — Bastion admin + données + agent (hors cluster)

  • Passerelle réseau (NAT, routage VLAN)
  • Bastion : talosctl, kubectl, helm, argocd CLI, ansible
  • Services données : NFS, PostgreSQL, Qdrant, MinIO
  • Hermes Agent en service systemd
  • dnsmasq pour la résolution *.lab.local

Cluster Kubernetes (Talos, 3 nœuds)

  • Couche infra : MetalLB, Traefik, cert-manager, Longhorn, nfs-subdir-external-provisioner
  • Couche observabilité : kube-prometheus-stack, Loki
  • Couche applicative IA : Open WebUI, LiteLLM, n8n
  • GitOps via ArgoCD

7.3. Flux principal Hermes ↔ LM Studio

Utilisateur → CLI Hermes / Telegram / autre interface
              (sur storage-01)
                    │
                    ▼
         Hermes Agent (skills, mémoire, tools)
              [storage-01 :daemon systemd]
                    │
                    │ HTTP POST /v1/chat/completions
                    ▼
         LM Studio (modèle chargé en VRAM 6700XT)
              [gpu-01 :1234]
                    │
                    │ Réponse streaming
                    ▼
         Hermes Agent (parsing tool calls, exécution)
                    │
                    ▼
              Utilisateur

7.4. Deux setups IA — poste perso vs cluster Funk

Setup 1 — Poste perso (9950X3D) — dev local

Matériel : Ryzen 9 9950X3D · 32 GB DDR5 · RX 9070 XT 16 GB VRAM

Composant Config
LM Studio http://127.0.0.1:1234/v1 (bind localhost par défaut)
Ollama http://127.0.0.1:11434 (aussi installé)
Hermes Agent config base_url: http://127.0.0.1:1234/v1
Goose agents Funk/Funk-infra/agents/ → pointent sur http://localhost:1234/v1

Démarrage LM Studio :

# Charger le modèle avec un context suffisant (système Hermes ≈ 15 000 tokens)
lms load <modele> --context-length 16384
lms server start --port 1234

Config Hermes (~/.hermes/config.yaml) :

model:
  default: <nom-modele>
  provider: lmstudio
  base_url: http://127.0.0.1:1234/v1
  context_length: 16384

Goose agents :

cd Funk/Funk-infra/agents/<nom-agent>
goose session --config goose-config.yaml
Agent Goose Modèle cible Usage
global qwen2.5-14b Raisonnement général
infra qwen2.5-coder-14b k8s, Talos, Helm, ArgoCD
sysadmin qwen2.5-7b Admin système, diagnostics
monitoring llama3.2-3b Logs, métriques
data qwen2.5-14b Analyse de données

Setup 2 — Cluster Funk (production)

Matériel GPU : gpu-01, Ryzen 9 5950X · 32 GB DDR4 · RX 6700XT 12 GB VRAM

Composant Config
LM Studio http://192.168.10.20:1234/v1 (bind 0.0.0.0)
Hermes Agent service systemd sur storage-01
Hermes base_url http://192.168.10.20:1234/v1

Démarrage LM Studio sur gpu-01 :

HSA_OVERRIDE_GFX_VERSION=10.3.0 lms load <modele> --context-length 16384
lms server start --port 1234 --host 0.0.0.0

Config Hermes sur storage-01 (~/.hermes/config.yaml) :

model:
  default: <nom-modele>
  provider: lmstudio
  base_url: http://192.168.10.20:1234/v1
  context_length: 16384

Différence clé avec setup 1 : HSA_OVERRIDE_GFX_VERSION=10.3.0 obligatoire pour la RX 6700XT (gfx1031 non officiellement supporté par ROCm). Sur la RX 9070 XT du poste perso, cette variable n'est pas nécessaire.


8. Stack IaC / Automatisation

8.1. Principe : un seul repo Git, trois flux de déploiement

Toute l'infrastructure est gérée en GitOps depuis un repo Git unique. Trois outils se partagent les responsabilités selon la cible :

┌──────────────────────────────────────────────────────────────────┐
│  Repo Git du lab (sur poste admin + remote Gitea/GitHub privé)   │
│                                                                  │
│  lab-infra/                                                      │
│  ├── ansible/              ← gère storage-01 + gpu-01            │
│  │   ├── inventory.yml                                           │
│  │   ├── playbooks/                                              │
│  │   ├── roles/                                                  │
│  │   └── group_vars/                                             │
│  ├── talos/                ← configs Talos via talhelper         │
│  │   ├── talconfig.yaml                                          │
│  │   ├── talsecret.sops.yaml                                     │
│  │   └── clusterconfig/    (généré par talhelper)                │
│  ├── k8s/                  ← manifests / Helm values             │
│  │   ├── apps/             ← apps déployées par ArgoCD           │
│  │   ├── infra/            ← MetalLB, Traefik, cert-manager...   │
│  │   └── argocd-bootstrap/ ← Application of Applications         │
│  └── docs/                                                       │
│      └── HOMELAB.md        ← ce document                         │
└────────┬─────────────────────────┬────────────────────┬──────────┘
         │                         │                    │
         │ ansible-playbook        │ talosctl           │ git push
         │ (push manuel SSH)       │ apply-config       │ → ArgoCD
         │                         │ (push manuel)      │   pull auto
         ▼                         ▼                    ▼
   storage-01,           compute-01/02/03         Workloads dans
   gpu-01                (Talos)                  le cluster k8s
   (AlmaLinux)

8.2. Outil 1 — Ansible (vanilla) pour les hôtes Linux classiques

Cible : storage-01 et gpu-01 (et futures machines AlmaLinux/Debian).

Choix : Ansible vanilla, rôles écrits from scratch. Pas de framework type BlueBanquise — surdimensionné pour 5-10 hôtes Linux à terme. À reconsidérer si on dépasse 25+ hôtes ou si on ajoute du HPC/Slurm.

Structure des rôles prévus :

ansible/
├── ansible.cfg
├── inventory.yml
├── group_vars/
│   ├── all.yml                  # variables communes (DNS, NTP, users)
│   ├── gateway.yml              # variables passerelle
│   └── gpu_hosts.yml            # variables hôtes GPU
├── host_vars/
│   ├── storage-01.yml
│   └── gpu-01.yml
├── playbooks/
│   ├── site.yml                 # playbook racine
│   ├── storage-01.yml
│   └── gpu-01.yml
└── roles/
    ├── common/                  # paquets de base, sshd, sudoers, motd
    ├── gateway/                 # NetworkManager VLAN, IP forwarding, nftables, NAT
    ├── dnsmasq/                 # DNS local *.lab.local
    ├── nfs_server/              # NFS server + exports
    ├── postgresql/              # Postgres + DB init
    ├── qdrant/                  # Qdrant via Podman
    ├── minio/                   # MinIO via Podman
    ├── rocm/                    # repo AMD + drivers + HSA_OVERRIDE
    ├── lm_studio/               # install + service systemd
    └── hermes_agent/            # install + config + systemd unit

Inventaire :

# ansible/inventory.yml
all:
  children:
    gateway:
      hosts:
        storage-01:
          ansible_host: 192.168.10.1
    gpu_hosts:
      hosts:
        gpu-01:
          ansible_host: 192.168.10.20
    almalinux:
      children:
        gateway:
        gpu_hosts:

Lancement type :

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 # cibler 1 rôle

Bonnes pratiques :

  • Tous les rôles idempotents (peuvent être ré-exécutés sans casse).
  • Variables sensibles dans Ansible Vault (mot de passe Postgres, clés API).
  • Un playbook = une machine ou un groupe, pas de "playbook fourre-tout".
  • Tags systématiques pour cibler un rôle spécifique.

8.3. Outil 2 — talhelper pour les nœuds Talos

Cible : compute-01, compute-02, compute-03.

Pourquoi talhelper : talosctl gen config brut produit des configs longues et difficiles à maintenir. talhelper lit un seul fichier talconfig.yaml clair et génère les configs YAML par nœud, avec gestion des secrets (chiffrement SOPS) et patches par nœud.

Structure :

talos/
├── talconfig.yaml          # config déclarative (lue par talhelper)
├── talsecret.sops.yaml     # secrets chiffrés (token bootstrap, certs CA)
├── talenv.yaml             # version Talos, version k8s
├── patches/                # patches YAML par nœud ou groupe
│   ├── compute-01.yaml
│   └── all-controlplane.yaml
└── clusterconfig/          # généré : ne PAS commit (au .gitignore)
    ├── lab-compute-01.yaml
    ├── lab-compute-02.yaml
    └── lab-compute-03.yaml

Workflow :

cd talos/

# 1. Éditer talconfig.yaml (ajout d'un nœud, changement de version k8s, etc.)
vim talconfig.yaml

# 2. Régénérer les configs nœud
talhelper genconfig

# 3. Appliquer sur un nœud spécifique
talhelper gencommand apply --node compute-02 | bash

# 4. Bootstrap (uniquement la première fois, sur le control-plane)
talhelper gencommand bootstrap --node compute-01 | bash

# 5. Récupérer le kubeconfig
talhelper gencommand kubeconfig | bash

Avantage GitOps : le talconfig.yaml est ta source de vérité. N'importe qui (toi dans 6 mois) peut lire ce fichier et comprendre l'état du cluster Talos sans avoir à inspecter les nœuds.

8.4. Outil 3 — ArgoCD pour les workloads Kubernetes

Cible : tout ce qui tourne dans le cluster k8s (apps + infra k8s).

Principe : ArgoCD surveille en continu un dossier Git et garantit que l'état réel du cluster correspond à ce qui est déclaré dans Git.

Pattern recommandé : "App of Apps"

k8s/
├── argocd-bootstrap/                # bootstrap ArgoCD lui-même
│   └── argocd-install.yaml
├── apps-of-apps/
│   └── root.yaml                    # une Application qui pointe sur apps/
├── infra/                           # déployé d'abord
│   ├── metallb/
│   │   ├── application.yaml
│   │   └── values.yaml
│   ├── traefik/
│   ├── cert-manager/
│   ├── longhorn/
│   └── nfs-provisioner/
└── apps/                            # déployé ensuite
    ├── litellm/
    │   ├── application.yaml
    │   ├── deployment.yaml
    │   ├── service.yaml
    │   └── ingress.yaml
    ├── open-webui/
    ├── n8n/
    ├── monitoring/                  # kube-prometheus-stack
    └── external-services/           # ExternalName vers storage-01
        ├── postgresql-external.yaml
        ├── qdrant-external.yaml
        └── lm-studio-external.yaml  # ExternalName vers gpu-01:1234

Workflow d'utilisation :

# 1. Modifier un manifest
vim k8s/apps/open-webui/deployment.yaml

# 2. Commit + push
git add k8s/apps/open-webui/
git commit -m "open-webui: bump to v0.4.0, add OIDC config"
git push

# 3. ArgoCD détecte le changement (poll par défaut toutes les 3 min)
#    → applique automatiquement dans le cluster
#    → visible dans l'UI argocd.lab.local

Bénéfices :

  • Source de vérité unique (Git)
  • Historique complet via git log
  • Rollback en git revert + push
  • Recréation totale du cluster en cas de désastre : install Talos via talhelper, install ArgoCD via le bootstrap, ArgoCD redéploie tout le reste tout seul

8.5. Récapitulatif des responsabilités

Outil Cible Mode de déploiement Stockage source
Ansible Hôtes Linux classiques (storage-01, gpu-01, futures Alma) Push manuel (ansible-playbook) lab-infra/ansible/
talhelper Nœuds Talos (compute-01/02/03) Push manuel (talosctl apply-config) lab-infra/talos/
ArgoCD Workloads Kubernetes (apps + infra k8s) Pull automatique depuis Git lab-infra/k8s/

8.6. Repo Git : où l'héberger ?

Court terme : repo local sur ton poste + remote sur GitHub (privé) ou GitLab (privé) → simple et fiable.

Moyen terme (recommandé) : héberger un Gitea ou Forgejo sur storage-01 (rôle Ansible dédié) + miroir GitHub pour backup. Avantages :

  • Indépendance totale (pas besoin d'Internet pour déployer)
  • Apprentissage de l'auto-hébergement Git
  • ArgoCD pointe sur git.lab.local/admin/lab-infra.git

8.7. Gestion des secrets

Pas de secrets en clair dans Git, jamais. Trois mécanismes selon la couche :

  • Ansible : Ansible Vault pour les secrets (ansible-vault encrypt_string)
  • Talos : SOPS + age (intégré nativement à talhelper)
  • Kubernetes : Sealed Secrets (Bitnami) ou External Secrets Operator pointant sur un Vault — pour démarrer, Sealed Secrets est plus simple

9. Feuille de route par phases

Chaque phase est validable indépendamment. Ne passer à la suivante que quand la précédente fonctionne.

Phase 0 — Préparation

  • Validation matérielle Talos sur 1 ThinkCentre (compute-01) effectué
  • Vérifier que tous les ThinkCentre ont des SSD SATA opérationnels
  • Préparer 1 clé USB pour Talos + 1 clé USB pour AlmaLinux
  • Initialiser le repo Git lab-infra/ sur le poste admin

Phase 1 — Infra réseau (storage-01 manuel + bootstrap Ansible)

  • Installation AlmaLinux sur storage-01
  • Configuration IP de base — storage-01 joignable (192.168.10.1 LAN cluster)
  • IP WAN storage-01 fixée à 192.168.1.200
  • Configuration VLAN sur le GS308EV4 — tous ports Access, storage-01 sur deux NICs physiques
  • Initialiser lab-infra/ansible/ avec inventory + rôle common + rôle gateway
  • Premier ansible-playbook qui configure VLAN/nftables/NAT/IP forwarding
  • Route statique sur la Freebox
  • Rôle dnsmasq pour résolution *.lab.local
  • Validation : ping bidirectionnel LAN domestique ↔ LAN cluster

Phase 2 — Hôte gpu-01 + LM Studio (Ansible)

  • Installation AlmaLinux sur gpu-01 — ping OK depuis storage-01
  • Ajout de gpu-01 à l'inventaire Ansible
  • Rôle rocm : repo AMD + drivers + HSA_OVERRIDE_GFX_VERSION=10.3.0
  • Validation ROCm : rocminfo doit lister la RX 6700XT
  • Rôle lm_studio : install + service systemd avec bind 0.0.0.0:1234
  • Téléchargement d'un modèle test (Hermes 4, Qwen 2.5 7B...)
  • Validation : curl http://192.168.10.20:1234/v1/models depuis storage-01

Phase 3 — Hermes Agent sur storage-01 (Ansible)

  • Rôle hermes_agent : install via script officiel
  • Configuration provider custom endpoint (LM Studio gpu-01)
  • Premier hermes chat interactif
  • (Optionnel) Service systemd pour daemon background
  • Données persistantes (~/.hermes/) sur le RAID5

Phase 4 — Stack données sur storage-01 (Ansible)

  • Rôle nfs_server : export /srv/nfs/k8s vers 192.168.10.0/24
  • Rôle postgresql : install + DB init
  • Rôle qdrant : Podman + service systemd
  • Rôle minio : Podman + service systemd
  • Validation : tous les services accessibles depuis le LAN cluster

Phase 5 — Cluster Talos (talhelper)

  • Génération image Talos via factory.talos.dev (extensions iscsi-tools)
  • Init lab-infra/talos/ avec talconfig.yaml (3 nœuds)
  • talhelper genconfig
  • Apply sur compute-01 (control-plane) puis bootstrap etcd
  • Apply sur compute-02 et compute-03 (workers)
  • Validation : kubectl get nodes montre 3 nœuds Ready

Phase 6 — Bootstrap ArgoCD + infra k8s (GitOps)

  • Install ArgoCD manuel via Helm (une seule fois, l'install ArgoCD reste manuelle)
  • Init lab-infra/k8s/ avec App of Apps pattern
  • Création des Applications ArgoCD pour : MetalLB, Traefik, cert-manager
  • Validation : pod nginx test exposé via Ingress, accessible depuis le LAN

Phase 7 — Stockage k8s (ArgoCD)

  • Application ArgoCD : nfs-subdir-external-provisioner pointant sur storage-01
  • Application ArgoCD : Longhorn (avec iscsi-tools extension Talos)
  • Validation : 1 PVC NFS + 1 PVC Longhorn créés et montés

Phase 8 — Apps IA (ArgoCD)

  • Applications ArgoCD : ExternalName vers Postgres, Qdrant, LM Studio
  • Application ArgoCD : LiteLLM (proxy vers LM Studio)
  • Application ArgoCD : Open WebUI (front, pointe sur LiteLLM)
  • Application ArgoCD : n8n
  • Application ArgoCD : kube-prometheus-stack + Loki
  • Validation finale : workflow n8n → Open WebUI → LiteLLM → LM Studio

Phase 9 — Optionnel : Gitea local + miroir

  • Rôle Ansible gitea sur storage-01
  • Migration du repo lab-infra vers Gitea local
  • Reconfiguration ArgoCD pour pointer sur git.lab.local
  • Miroir push vers GitHub privé (sauvegarde)

10. Points d'attention spécifiques

10.1. RX 6700XT et ROCm sur AlmaLinux 9

  • gfx1031 non officiellement supporté par ROCm
  • Variable obligatoire : HSA_OVERRIDE_GFX_VERSION=10.3.0
  • ROCm s'exécute directement sur l'OS hôte (gpu-01), pas dans des conteneurs
  • Fallback Vulkan possible dans LM Studio si ROCm coince
  • Doc ROCm pour RHEL 9 : https://rocm.docs.amd.com/projects/install-on-linux/

10.2. LM Studio en mode serveur

  • Par défaut LM Studio bind sur 127.0.0.1 → inaccessible depuis le réseau
  • Forcer 0.0.0.0 via CLI : lms server start --port 1234 --host 0.0.0.0
  • LM Studio CLI : lms ls, lms load <model>, lms unload, lms server status

10.3. Hermes Agent

  • Daemon : possible via systemd unit
  • Mémoire/skills stockés dans ~/.hermes/à mettre sur le RAID5
  • Variables .env dans ~/.hermes/.env

10.4. RAM serrée sur ThinkCentre 8 GB

  • Réserver système+kubelet : system-reserved=cpu=500m,memory=1Gi, kube-reserved=cpu=500m,memory=1Gi
  • Toujours définir resources.requests/limits sur les pods
  • Sinon risque OOM-killer sur le nœud entier

10.5. Single control-plane

  • Si compute-01 tombe, plus de kubectl apply mais les workloads continuent
  • Snapshots etcd réguliers : talosctl etcd snapshot vers storage-01 (cron Ansible)

10.6. RAID5 sur storage-01

  • 4×1 TB = 2.7 TB exploitables
  • Sauvegarder : configs k8s (Git), bases de données (dump périodique vers MinIO ou NAS externe), mémoire/skills Hermes (~/.hermes/)
  • Pas les modèles LM Studio (re-téléchargeables)

10.7. Sécurité passerelle = bastion admin

  • storage-01 cumule passerelle + bastion + Hermes + données → SPOF assumé
  • gpu-01 sans rôle réseau critique : si tombe, perte inférence uniquement

10.8. Bootstrap : ce qui reste manuel

GitOps ne peut pas faire le bootstrap absolu. Restent toujours manuels :

  • Installation OS sur chaque machine (AlmaLinux ou Talos depuis USB)
  • Configuration IP/SSH minimale pour qu'Ansible puisse se connecter
  • Premier déploiement ArgoCD via Helm
  • Tout le reste est ensuite géré par Ansible / talhelper / ArgoCD

11. Outils à installer sur storage-01 (bastion admin)

# Outils Kubernetes / Talos
- talosctl   (admin Talos)
- talhelper  (génération configs Talos)
- kubectl    (admin Kubernetes)
- helm       (charts)
- argocd CLI
- k9s        (TUI Kubernetes)

# Outils IaC
- ansible-core
- sops + age (secrets Talos)

# Outils IA
- hermes     (Hermes Agent)
- curl/jq    (debug API LM Studio)

# Outils système
- nftables, dnsmasq, nfs-utils, postgresql-server, podman
- minio, qdrant (binaires ou conteneurs Podman)

# Optionnel
- gitea ou forgejo (Git local)
- restic ou borgbackup (sauvegardes)

Tous installés via les rôles Ansible — pas de installation manuelle au-delà du bootstrap initial.


12. Conventions et nommage

  • Hostnames : storage-01, compute-01, compute-02, compute-03, gpu-01
  • Domaine local : lab.local
  • Services exposés via cluster : <service>.lab.local → IP MetalLB de Traefik
  • Endpoint LM Studio : http://192.168.10.20:1234/v1 (ou lms.lab.local)
  • Namespaces k8s :
    • argocd (ArgoCD lui-même)
    • infra (MetalLB, Traefik, cert-manager, monitoring)
    • storage (Longhorn, NFS provisioner)
    • external (ExternalName vers services storage-01/gpu-01)
    • ai (Open WebUI, LiteLLM)
    • workflows (n8n)
  • Git :
    • Branches : main (= prod), feature/* (changements en cours)
    • Commits : conventional commits (feat:, fix:, chore:, docs:)

13. État actuel (2026-05-09)

  • Architecture validée
  • Test Talos sur compute-01 effectué (boot OK, IP DHCP, talosctl répond)
  • Stack IaC choisie : Ansible vanilla + talhelper + ArgoCD
  • Hermes Agent configuré sur le poste perso (Setup 1 — 9950X3D + LM Studio local)
  • AlmaLinux installé sur storage-01 — ping OK (192.168.1.200 WAN, 192.168.10.1 LAN cluster)
  • AlmaLinux installé sur gpu-01 — ping OK depuis storage-01 (192.168.10.20)
  • Connectivité LAN cluster (VLAN 10) : storage-01 ↔ gpu-01 fonctionnelle
  • Phase 1 en cours : Ansible + rôles + dnsmasq + NAT à configurer
  • Phase 2 en cours : ROCm + LM Studio sur gpu-01 à installer
  • Ansible pas encore exécuté (repo lab-infra/ à initialiser)
  • VLAN switch GS308EV4 à confirmer / finaliser
  • Route statique Freebox à configurer
  • Aucun cluster k8s monté
  • LM Studio pas encore installé sur gpu-01
  • Hermes Agent pas encore installé sur storage-01

14. Annexes — Liens utiles

Infrastructure

Kubernetes / GitOps

IaC

IA