Funk-lab/CLAUDE.md
alkatrazz 515933c949 docs: suppression LM Studio — cluster utilise llama-server ROCm
- CLAUDE.md : état mis à jour (2026-05-13), gpu-01 → llama-server,
  setup IA → endpoints réels (llama-server + LiteLLM), rôles Ansible
  à jour, suppression CLI LM Studio
- admin/lm_studio.md : marqué supprimé du cluster, lms CLI conservée
  pour téléchargement modèles uniquement, /opt/lmstudio disparu
- admin/nfs.md : section modèles mise à jour (plus de symlink lmstudio)
- admin/rocm.md : debug section → llama-server, section Vulkan supprimée
- admin/README.md : description lm_studio.md mise à jour

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 16:21:51 +02:00

7.3 KiB

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 / llama-server ROCm), 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-13) :

  • Hermes Agent opérationnel sur storage-01 (llama-server GPU via LiteLLM)
  • storage-01 installé — 192.168.10.1 (LAN cluster), 192.168.1.200 (WAN)
  • gpu-01 installé — llama-server GPU (:1234) + CPU (:1236/:1237) opérationnels
  • LiteLLM sur storage-01 — proxy multi-modèles + ask-agent
  • Cluster k8s Talos opérationnel (MetalLB + Traefik + wildcard DNS lab.local)
  • WOL compute nodes non configuré (BIOS) — allumage manuel requis

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 llama-server dédié (RX 6700XT, ROCm 7.x) — 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, llama_server, litellm, hermes_agent, hermes_user
├── 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

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 : common, gateway, dnsmasq, nfs_server, nfs_client, postgresql, qdrant, minio, rocm, llama_server, litellm, hermes_agent, hermes_user. Tous idempotents. Secrets via Ansible Vault.

talhelper (nœuds Talos)

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).

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. Toujours s'assurer que la variable est présente dans le service systemd llama-server :

HSA_OVERRIDE_GFX_VERSION=10.3.0

ROCm tourne directement sur l'hôte AlmaLinux (pas dans des conteneurs). L'inférence est assurée par llama-server (llama.cpp compilé ROCm 7.x).

CLI lms disponible sur gpu-01 uniquement pour télécharger des modèles (lms get <url-hf>, lms ls).


Deux setups IA

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

Composant Endpoint
Ollama http://127.0.0.1:11434
LM Studio (optionnel) http://127.0.0.1:1234/v1
Hermes Agent base_url: http://127.0.0.1:1234/v1 ou Ollama

Setup 2 — Cluster Funk (production)

Composant Endpoint
llama-server GPU (gpu-01) http://192.168.10.20:1234/v1
llama-server CPU system (gpu-01) http://192.168.10.20:1236/v1
llama-server CPU monitor (gpu-01) http://192.168.10.20:1237/v1
LiteLLM proxy (storage-01) http://127.0.0.1:4000/v1 (master_key: lm-studio)
Hermes Agent service systemd sur storage-01, via LiteLLM
# Vérifier l'état complet depuis le poste perso
funk-status

Conventions

  • Domaine : lab.local — wildcard DNS via dnsmasq sur storage-01
  • Ingress : <service>.lab.local → IP MetalLB de Traefik (192.168.10.200-230)
  • llama-server endpoint : http://192.168.10.20:1234/v1 (GPU) — accès via LiteLLM sur storage-01
  • 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) :

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