# Funk Lab > Homelab IA — Kubernetes (Talos) + GPU AMD + Agent autonome (Hermes) ![Funk Lab](docs/funk-lab.jpg) ## Vue d'ensemble **Funk** est un homelab orienté IA composé de 5 machines physiques : - un nœud de stockage/passerelle qui héberge tous les services de données et l'agent IA - un nœud GPU dédié à l'inférence LLM local (AMD RX 6700XT) - trois nœuds qui forment un cluster Kubernetes (Talos Linux) L'ensemble est géré en Infrastructure-as-Code : **Ansible** pour les hôtes AlmaLinux, **talhelper** pour Talos, **ArgoCD** pour les workloads Kubernetes. --- ## Architecture ``` Internet │ [ Freebox ] │ ┌────────────────┐ │ storage-01 │ AlmaLinux 9.7 │ 192.168.10.1 │ Gateway + NAT + DNS │ │ NFS · PostgreSQL │ │ Qdrant · LiteLLM · Hermes └───────┬────────┘ │ LAN cluster (192.168.10.0/24) ┌───────────┼───────────┐ │ │ │ [ compute-01 ] [ compute-02 ] [ compute-03 ] Talos Linux 192.168.10.11 192.168.10.12 192.168.10.13 Kubernetes control-plane worker worker ┌───────────┘ │ [ gpu-01 ] AlmaLinux 9.7 192.168.10.20 llama-server (ROCm) AMD RX 6700XT 12GB ``` --- ## Stack IA ``` ┌─────────────────────────────────────┐ │ Hermes Agent (storage-01) │ │ │ │ profil funk-ai (Qwen3-8B GPU) │ │ │ ask-agent system/monitor │ │ ▼ │ │ profil system (Qwen3-1.7B CPU) │ │ profil monitor (Qwen3-1.7B CPU) │ │ profil brain (Claude Sonnet API) │ └──────────────┬──────────────────────┘ │ LiteLLM Proxy :4000 │ ┌────────────────────┼────────────────────┐ │ │ │ qwen3-8b GPU qwen3-1.7b CPU Claude API gpu-01 :1234 :1236 system / :1237 monitor Anthropic ``` | Composant | Rôle | Hôte | |---|---|---| | **llama-server** (×4) | Inférence GPU (:1234) + 2× CPU isolés (:1236/:1237) + embeddings dédiés nomic-embed-text (:1238) — ROCm 7.x | gpu-01 | | **LiteLLM** | Proxy API — routing local/cloud transparent | storage-01 | | **Hermes Agent** | Agent IA multi-profils avec mémoire vectorielle | storage-01 | | **ask-agent** | Délégation inter-agents (system / monitor / brain) | storage-01 | | **STT** | Assistant vocal « Jarvis » — client `stt` (poste) + STT-server in-cluster | k8s (`ai`) | | **Qdrant** | Base vectorielle — RAG (`funk-docs`) + mémoire STT (`stt-memory`) | storage-01 | | **PostgreSQL 16** | Persistance Hermes, LiteLLM, n8n, Open WebUI, Ghostfolio | storage-01 | ### Profils Hermes | Profil | Modèle | Usage | |---|---|---| | `funk-ai` | Qwen3-8B GPU (~35 tok/s) | Agent principal — par défaut | | `system` | Qwen3-1.7B CPU (~21 tok/s) | Calculs rapides, formatage, résumés | | `monitor` | Qwen3-1.7B CPU (~21 tok/s) | Analyse logs, métriques, santé système | | `brain` | Claude Sonnet 4.6 (API) | Raisonnement complexe, architecture | --- ## Infrastructure ### Machines | Machine | IP | OS | RAM | Rôle | |---|---|---|---|---| | storage-01 | 192.168.10.1 | AlmaLinux 9.7 | 32 GB | Gateway · NFS · Services IA | | gpu-01 | 192.168.10.20 | AlmaLinux 9.7 | 32 GB | Inférence LLM (RX 6700XT) | | compute-01 | 192.168.10.11 | Talos v1.13 | 16 GB | k8s control-plane | | compute-02 | 192.168.10.12 | Talos v1.13 | 8 GB | k8s worker | | compute-03 | 192.168.10.13 | Talos v1.13 | 8 GB | k8s worker | ### Stockage - NVMe système (`/home/data`, ~845 GB XFS) — bind-monté sur `/srv/data` depuis 2026-05-29 - RAID5 logiciel (`md0`) — 4 × 1 TB SATA, actif mais plus monté (sdb ATA errors + sdd retiré) - Point de montage `/srv/data` — héberge modèles LLM, bases de données, données Hermes --- ## Organisation du repo ``` ├── ansible/ # Gestion storage-01 + gpu-01 (AlmaLinux) │ ├── inventory.yml │ ├── playbooks/ │ │ ├── storage-01.yml │ │ └── gpu-01.yml │ ├── group_vars/ # Variables globales + vault chiffré │ ├── host_vars/ # Variables par machine │ └── roles/ │ ├── common # Paquets, sécurité, NTP │ ├── gateway # nftables + NAT │ ├── dnsmasq # DNS local (lab.local) │ ├── nfs_server # Exports NFS (modèles, k8s) │ ├── nfs_client # Montages NFS sur gpu-01 │ ├── rocm # Stack GPU AMD (ROCm 7.x) │ ├── llama_server # Inférence LLM + embeddings │ ├── litellm # Proxy LLM + script ask-agent │ ├── hermes_agent # Agent IA autonome │ ├── hermes_user # User hermes + SSH partagé entre hosts │ ├── rag # RAG : scripts rag-ingest/rag-query + skill Hermes │ ├── alertmanager_webhook # Pont AlertManager → ask-agent │ ├── postfix_relay # SMTP sortant via Gmail │ ├── node_exporter # Métriques Prometheus │ ├── minio # ⚠️ placeholder vide — service non déployé │ ├── postgresql # Base de données │ ├── qdrant # Base vectorielle │ └── hermes_auto_improve # Worker analyse doc + trigger server :9095 ├── hermes-skills/ # Skills Hermes versionnés │ ├── funk/ │ │ ├── agent-delegation/ # Délégation ask-agent (system/monitor/brain) │ │ └── rag-docs/ # Usage de rag-query │ └── souls/ # Prompts système par profil (funk-ai, system, monitor, brain) ├── tools/ # Sources des outils déployés │ ├── hermes-auto-improve/ # auto-improve.py + trigger-server.py │ └── hermes-voice/ # Client vocal Hermes (CLI faster-whisper + Piper) ├── stt/ # Assistant vocal « Jarvis » — client `stt` (pipx) + STT-server (conteneur) ├── admin/ # Base de connaissance (indexée dans le RAG) ├── progress/ # Journaux de session (référencés par PROGRESS.md) ├── archive/ # Documents historiques obsolètes (conception d'origine) — ne fait pas foi ├── talos/ # Cluster Kubernetes (talhelper) └── k8s/ # Workloads ArgoCD ├── infra/ # monitoring, nfs-provisioner (Traefik + MetalLB via helm au bootstrap) └── apps/ # Open WebUI, n8n, STT, Ghostfolio, external-services ``` --- ## Démarrage rapide ### Pré-requis ```bash pip install ansible ansible-galaxy collection install ansible.posix community.general community.postgresql ``` ### Déployer storage-01 ```bash cd ansible/ ansible-playbook -i inventory.yml playbooks/storage-01.yml ``` ### Déployer gpu-01 ```bash ansible-playbook -i inventory.yml playbooks/gpu-01.yml ``` ### Déployer un rôle spécifique ```bash ansible-playbook -i inventory.yml playbooks/storage-01.yml --tags litellm ansible-playbook -i inventory.yml playbooks/gpu-01.yml --tags llama_server ``` ### Gestion du cluster ```bash funk-start # Allume gpu-01 (WOL) + démarre tous les services funk-start --k8s # Idem + démarre les nœuds k8s funk-stop # Arrêt propre funk-stop --k8s # Arrêt propre + éteint k8s avant funk-status # État de tous les services (13 checks) ``` > Détail complet des procédures : [admin/ops/cluster.md](admin/ops/cluster.md) --- ## Secrets Les secrets sont gérés via **Ansible Vault** (chiffrement AES256). ```bash # Chiffrer le vault ansible-vault encrypt ansible/group_vars/all/vault.yml # Editer les secrets ansible-vault edit ansible/group_vars/all/vault.yml ``` Variables stockées dans le vault : `vault_anthropic_api_key`, `vault_pg_hermes_password`, `vault_pg_litellm_password`, `vault_pg_n8n_password`, `vault_pg_openwebui_password`, `vault_pg_ghostfolio_password`, `vault_postfix_relay_password`, `vault_n8n_api_key`. --- ## Contrainte GPU La RX 6700XT (gfx1031) n'est pas officiellement supportée par ROCm. La variable suivante est obligatoire dans tous les services GPU : ``` HSA_OVERRIDE_GFX_VERSION=10.3.0 ``` Elle est gérée automatiquement par le rôle Ansible `llama_server`. --- ## Roadmap - [x] Ansible — storage-01 (gateway, NFS, PostgreSQL, Qdrant, LiteLLM, Hermes, postfix, AlertManager webhook) - [x] Ansible — gpu-01 (ROCm, llama-server : GPU :1234 + embeddings :1238 via le rôle ; 2× CPU manuels) - [x] Stack IA opérationnelle (Hermes multi-profils + Qwen3 + Claude API) - [x] Délégation inter-agents (`ask-agent` + skill `agent-delegation`) - [x] RAG opérationnel — Qdrant 339 chunks, `rag-query` / `rag-ingest` - [x] User `hermes` avec SSH partagé entre storage-01 et gpu-01 - [x] Cluster Kubernetes opérationnel (Talos v1.13 + talhelper) - [x] MetalLB + Traefik + wildcard DNS `lab.local` - [x] Monitoring complet (kube-prometheus-stack + AlertManager → Hermes + n8n) - [x] Open WebUI (`openwebui.lab.local`, namespace `ai`) - [x] n8n (`n8n.lab.local`, namespace `ai`, 3 workflows actifs) - [x] Email sortant — Postfix relay → Gmail SMTP - [x] hermes-auto-improve — analyse quotidienne de la doc par Hermes (n8n 22h → PR `hermes/daily-work`) - [x] Ghostfolio — suivi de portefeuille (`ghostfolio.lab.local`, PostgreSQL s01 + Redis) - [x] STT — assistant vocal « Jarvis » (client `stt` + STT-server in-cluster, mémoire Qdrant `stt-memory`) - [x] Modèle d'embedding dédié — nomic-embed-text sur gpu-01 `:1238` (utilisé par la mémoire STT) - [x] Réparer Qdrant — crash-loop résolu 2026-06-17 (collection `funk-docs` supprimée → à re-ingérer) - [ ] Re-ingérer le RAG (`rag-ingest`) et le basculer sur l'embedding dédié `:1238` - [ ] WOL compute nodes (configuration BIOS) - [ ] Route statique Freebox