mirror of
https://github.com/Alkatrazz24/Funk-lab.git
synced 2026-07-08 06:24:42 +02:00
docs: réorganisation complète de admin/ en 4 domaines thématiques
Structure avant : 20 fichiers à plat dans admin/ — difficile à naviguer.
Structure après : 4 sous-répertoires thématiques + index clair.
Réorganisation :
admin/ops/ → cluster.md, ansible.md, systeme.md
admin/infra/ → reseau.md, nfs.md, dnsmasq.md, ssh.md
admin/k8s/ → talos.md, argocd.md, monitoring.md
admin/ia/ → llama_server.md, rocm.md, litellm.md, hermes.md
Suppressions :
- ask-agent.md : contenu fusionné dans ia/hermes.md (section ask-agent)
- lm_studio.md : obsolète (LM Studio remplacé par llama-server)
Mises à jour contenu :
- ia/hermes.md : fusion complète avec ask-agent.md (profils, skills,
SOUL.md, ask-agent CLI, dépannage) — doc unifiée sans redondance
- ops/cluster.md : section GitOps réduite à 2 lignes + lien argocd.md
- incidents.md : tableau de résumé en tête + 4 nouveaux incidents
(Grafana OOMKilled, AlertManager null receiver, llama-server 501,
nftables règle après drop)
- README.md : réécrit — navigation rapide + index par domaine
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d552abd2ef
commit
5bcf95b82e
19 changed files with 633 additions and 677 deletions
107
admin/ops/ansible.md
Normal file
107
admin/ops/ansible.md
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
# Ansible — Commandes d'administration
|
||||
|
||||
Toutes les commandes se lancent depuis la racine du repo (`lab-infra/`).
|
||||
Le venv est dans `.venv/`, le `Makefile` fournit les raccourcis.
|
||||
|
||||
---
|
||||
|
||||
## Raccourcis Makefile
|
||||
|
||||
```bash
|
||||
make ping # Vérifie que toutes les machines répondent
|
||||
make check # Dry-run complet (simule sans appliquer)
|
||||
make apply # Applique tous les playbooks (storage-01 + gpu-01)
|
||||
make apply-storage # Applique uniquement storage-01
|
||||
make apply-gpu # Applique uniquement gpu-01
|
||||
make install # Installe ansible-core + collections Galaxy
|
||||
make vault-encrypt # Chiffre group_vars/all/vault.yml
|
||||
make vault-edit # Édite le vault (déchiffre → édite → rechiffre)
|
||||
make vault-view # Affiche le contenu du vault déchiffré
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Commandes Ansible directes
|
||||
|
||||
### Cibler un rôle spécifique
|
||||
```bash
|
||||
cd ansible/
|
||||
# Via tag (si les rôles ont des tags)
|
||||
../.venv/bin/ansible-playbook playbooks/storage-01.yml --tags dnsmasq
|
||||
|
||||
# Via limite d'hôte
|
||||
../.venv/bin/ansible-playbook playbooks/site.yml -l gpu-01
|
||||
```
|
||||
|
||||
### Exécuter une commande ad-hoc sur une machine
|
||||
```bash
|
||||
cd ansible/
|
||||
../.venv/bin/ansible storage-01 -m shell -a "systemctl status dnsmasq"
|
||||
../.venv/bin/ansible all -m shell -a "uptime"
|
||||
../.venv/bin/ansible gpu_hosts -m shell -a "free -h"
|
||||
```
|
||||
|
||||
### Collecter les facts d'une machine (variables système détectées)
|
||||
```bash
|
||||
cd ansible/
|
||||
../.venv/bin/ansible storage-01 -m setup
|
||||
../.venv/bin/ansible storage-01 -m setup -a "filter=ansible_interfaces"
|
||||
../.venv/bin/ansible storage-01 -m setup -a "filter=ansible_default_ipv4"
|
||||
```
|
||||
|
||||
### Vérifier l'inventaire
|
||||
```bash
|
||||
cd ansible/
|
||||
../.venv/bin/ansible-inventory --list # JSON complet
|
||||
../.venv/bin/ansible-inventory --graph # Arbre des groupes/hôtes
|
||||
```
|
||||
|
||||
### Dry-run avec diff (voir exactement ce qui changerait)
|
||||
```bash
|
||||
cd ansible/
|
||||
../.venv/bin/ansible-playbook playbooks/storage-01.yml --check --diff
|
||||
```
|
||||
|
||||
### Débugger une variable
|
||||
```bash
|
||||
cd ansible/
|
||||
../.venv/bin/ansible storage-01 -m debug -a "var=lan_interface"
|
||||
../.venv/bin/ansible storage-01 -m debug -a "var=hostvars['storage-01']"
|
||||
```
|
||||
|
||||
### Augmenter la verbosité (debug complet)
|
||||
```bash
|
||||
cd ansible/
|
||||
../.venv/bin/ansible-playbook playbooks/storage-01.yml -v # output étendu
|
||||
../.venv/bin/ansible-playbook playbooks/storage-01.yml -vvv # connexions SSH incluses
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Vault Ansible
|
||||
|
||||
```bash
|
||||
# Chiffrer un fichier
|
||||
cd ansible/
|
||||
../.venv/bin/ansible-vault encrypt group_vars/all/vault.yml
|
||||
|
||||
# Chiffrer une valeur à la volée (copier-coller dans vault.yml)
|
||||
../.venv/bin/ansible-vault encrypt_string 'mon_mot_de_passe' --name 'vault_postgres_password'
|
||||
|
||||
# Déchiffrer temporairement pour voir
|
||||
../.venv/bin/ansible-vault view group_vars/all/vault.yml
|
||||
|
||||
# Changer le mot de passe vault
|
||||
../.venv/bin/ansible-vault rekey group_vars/all/vault.yml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Groupes d'hôtes disponibles
|
||||
|
||||
| Groupe | Machines |
|
||||
|---|---|
|
||||
| `all` | storage-01, gpu-01 |
|
||||
| `gateway` | storage-01 |
|
||||
| `gpu_hosts` | gpu-01 |
|
||||
| `almalinux` | storage-01, gpu-01 |
|
||||
161
admin/ops/cluster.md
Normal file
161
admin/ops/cluster.md
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
# Gestion du cluster Funk
|
||||
|
||||
Script central : `/usr/local/bin/funk-cluster` sur storage-01.
|
||||
Fonctions bash configurées dans `~/.bashrc` du poste perso.
|
||||
|
||||
---
|
||||
|
||||
## Commandes
|
||||
|
||||
```bash
|
||||
# Depuis le poste perso
|
||||
funk-status # État complet (storage-01 + gpu-01 + k8s)
|
||||
funk-start # Démarre gpu-01 (WOL) + tous les services
|
||||
funk-start --k8s # Idem + démarre le cluster k8s (compute-01/02/03)
|
||||
funk-stop # Arrête services + gpu-01 + storage-01
|
||||
funk-stop --k8s # Idem + éteint le cluster k8s avant
|
||||
```
|
||||
|
||||
> `funk-stop` éteint storage-01 en dernier — la connexion SSH se coupe, c'est normal.
|
||||
|
||||
---
|
||||
|
||||
## Procédures d'utilisation
|
||||
|
||||
### Allumer le homelab (sans k8s)
|
||||
|
||||
1. **Allumer storage-01 et gpu-01 manuellement** (bouton physique)
|
||||
2. Attendre ~30s que storage-01 boot
|
||||
3. Depuis le poste perso :
|
||||
```bash
|
||||
funk-start
|
||||
```
|
||||
4. Le script démarre les services et attend que gpu-01 soit prêt (~3 min pour les modèles LLM)
|
||||
5. Vérifier l'état :
|
||||
```bash
|
||||
funk-status
|
||||
```
|
||||
|
||||
### Allumer le homelab complet (avec k8s)
|
||||
|
||||
1. **Allumer storage-01 et gpu-01 manuellement**
|
||||
2. Lancer le démarrage :
|
||||
```bash
|
||||
funk-start --k8s
|
||||
```
|
||||
3. Le script envoie des paquets WOL aux compute nodes — **si WOL non configuré dans le BIOS, allumer compute-01/02/03 manuellement pendant l'attente ping** (~30s de fenêtre)
|
||||
4. Le script attend automatiquement que les nœuds k8s soient `Ready` (3 min max)
|
||||
|
||||
> WOL sur les compute nodes nécessite `Wake on LAN` activé dans le BIOS (Gigabyte : `Advanced → ACPI Settings`). Tant que ce n'est pas configuré, allumage manuel requis.
|
||||
|
||||
### Éteindre le homelab (sans k8s)
|
||||
|
||||
```bash
|
||||
funk-stop
|
||||
```
|
||||
|
||||
La connexion SSH se coupe à la fin (storage-01 s'éteint lui-même). C'est normal.
|
||||
|
||||
### Éteindre le homelab complet (avec k8s)
|
||||
|
||||
```bash
|
||||
funk-stop --k8s
|
||||
```
|
||||
|
||||
Ordre d'arrêt : hermes-agent + litellm → cordon+drain compute-02/03 → drain compute-01 → vérif NFS → talosctl shutdown → gpu-01 → qdrant + postgresql → storage-01.
|
||||
Ordre de démarrage : storage-01 déjà up → gpu-01 (WOL) → compute-01/02/03 (WOL) → uncordon → ArgoCD up → workloads.
|
||||
|
||||
---
|
||||
|
||||
## Ce que fait chaque commande
|
||||
|
||||
### `funk-status`
|
||||
|
||||
Vérifie dans l'ordre :
|
||||
- Services storage-01 : postgresql-16, qdrant, litellm, hermes-agent
|
||||
- Santé : PostgreSQL (connexion réelle), Qdrant (collections), LiteLLM (modèles), Hermes, NFS export
|
||||
- gpu-01 : ping, NFS /mnt/models, llama-server GPU (:1234), embeddings, llama-server CPU (:1236/:1237)
|
||||
- Cluster k8s : ping compute-01/02/03, kubectl get nodes Ready
|
||||
|
||||
### `funk-start [--k8s]`
|
||||
|
||||
1. Démarre postgresql-16, qdrant, litellm, hermes-agent sur storage-01
|
||||
2. Envoie un paquet Wake-on-LAN à gpu-01 si éteint, attend le ping + SSH
|
||||
3. Attend le montage NFS `/mnt/models` sur gpu-01
|
||||
4. Attend le chargement du modèle GPU (jusqu'à 4 min)
|
||||
5. Attend les modèles CPU (jusqu'à 2 min)
|
||||
6. `--k8s` :
|
||||
- Envoie WOL aux 3 nœuds, attend ping, attend nœuds Ready (3 min max)
|
||||
- **Uncordon** des nœuds s'ils sont `SchedulingDisabled` (état résiduel après `funk-stop --k8s`)
|
||||
- Attend qu'ArgoCD soit Running (signe que le GitOps redémarre les workloads)
|
||||
|
||||
### `funk-stop [--k8s]`
|
||||
|
||||
1. Arrête hermes-agent et litellm sur storage-01 (timeout 10s + SIGKILL si besoin)
|
||||
2. `--k8s` — arrêt propre du cluster en 6 étapes :
|
||||
- **Cordon** des 3 nœuds → plus aucun pod ne peut être replanifié
|
||||
- **Drain compute-02** → SIGTERM aux pods, 30s grace period, PVCs NFS démontés
|
||||
- **Drain compute-03** → idem (Prometheus, Grafana flushent leur WAL/SQLite)
|
||||
- **Drain compute-01** → ArgoCD, kube-state-metrics, etc.
|
||||
- **Vérification NFS** → confirme que plus aucune session NFS active depuis k8s
|
||||
- **talosctl shutdown** → halt propre (plus rien ne tourne, rien n'écrit)
|
||||
3. Éteint gpu-01 (`shutdown -h now` via SSH)
|
||||
4. Arrête qdrant et postgresql-16 sur storage-01
|
||||
5. Éteint storage-01 (`shutdown -h now`) — connexion SSH coupée
|
||||
|
||||
---
|
||||
|
||||
## GitOps
|
||||
|
||||
Modifier `k8s/` → `git push` → ArgoCD applique (~3 min).
|
||||
UI : http://argocd.lab.local — doc complète : [k8s/argocd.md](../k8s/argocd.md)
|
||||
|
||||
---
|
||||
|
||||
## Machines et MACs
|
||||
|
||||
| Machine | IP | MAC | Rôle |
|
||||
|---|---|---|---|
|
||||
| storage-01 | 192.168.10.1 / 192.168.1.200 | — | Passerelle + services IA |
|
||||
| gpu-01 | 192.168.10.20 | `a8:a1:59:72:a6:11` | LLM GPU + CPU |
|
||||
| compute-01 | 192.168.10.11 | `6c:4b:90:82:8e:47` | k8s control-plane |
|
||||
| compute-02 | 192.168.10.12 | `6c:4b:90:cf:7f:c5` | k8s worker |
|
||||
| compute-03 | 192.168.10.13 | `6c:4b:90:b6:49:20` | k8s worker |
|
||||
|
||||
---
|
||||
|
||||
## Fonctions bash (`~/.bashrc` poste perso)
|
||||
|
||||
```bash
|
||||
funk-start() { ssh storage-01 "sudo /usr/local/bin/funk-cluster start $*"; }
|
||||
funk-stop() { ssh storage-01 "sudo /usr/local/bin/funk-cluster stop $*"; }
|
||||
alias funk-status='ssh storage-01 "sudo /usr/local/bin/funk-cluster status"'
|
||||
alias funk-pull='ssh storage-01 "sudo -u ansible git -C /srv/data/lab pull"'
|
||||
```
|
||||
|
||||
Les fonctions bash transmettent les arguments — `funk-start --k8s` et `funk-stop --k8s` fonctionnent directement.
|
||||
|
||||
---
|
||||
|
||||
## Déploiement du script
|
||||
|
||||
Le script est versionné dans `ansible/roles/litellm/files/funk-cluster`.
|
||||
Pour le redéployer sur storage-01 :
|
||||
|
||||
```bash
|
||||
scp ansible/roles/litellm/files/funk-cluster s01:/tmp/
|
||||
ssh s01 "sudo cp /tmp/funk-cluster /usr/local/bin/funk-cluster && sudo chmod +x /usr/local/bin/funk-cluster"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Points d'attention
|
||||
|
||||
| Sujet | Détail |
|
||||
|---|---|
|
||||
| Ordre d'arrêt | Hermes/LiteLLM → cordon+drain k8s (optionnel) → gpu-01 → Qdrant/PG → storage-01 |
|
||||
| Ordre de démarrage | storage-01 (toujours déjà up) → gpu-01 → k8s (optionnel) |
|
||||
| WOL compute nodes | BIOS non configuré → allumer manuellement pendant l'attente ping de `funk-start --k8s` |
|
||||
| LiteLLM bloquant | `systemctl stop --timeout=10` + SIGKILL automatique si timeout |
|
||||
| talosctl path | `/home/ansible/.config/talos/config` requis explicitement (sudo change HOME) |
|
||||
| SSH coupée à l'arrêt | Normal — storage-01 s'éteint lui-même en fin de `funk-stop` |
|
||||
138
admin/ops/systeme.md
Normal file
138
admin/ops/systeme.md
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
# Système — AlmaLinux 9
|
||||
|
||||
Commandes générales applicables sur storage-01 et gpu-01.
|
||||
|
||||
---
|
||||
|
||||
## Services systemd
|
||||
|
||||
```bash
|
||||
# Statut d'un service
|
||||
sudo systemctl status <service>
|
||||
|
||||
# Démarrer / arrêter / redémarrer
|
||||
sudo systemctl start <service>
|
||||
sudo systemctl stop <service>
|
||||
sudo systemctl restart <service>
|
||||
sudo systemctl reload <service> # rechargement config sans coupure
|
||||
|
||||
# Activer / désactiver au démarrage
|
||||
sudo systemctl enable <service>
|
||||
sudo systemctl disable <service>
|
||||
|
||||
# Lister tous les services actifs
|
||||
sudo systemctl list-units --type=service --state=running
|
||||
```
|
||||
|
||||
### Services clés par machine
|
||||
|
||||
| Machine | Service | Rôle |
|
||||
|---|---|---|
|
||||
| storage-01 | `nftables` | Firewall + NAT masquerade cluster → WAN |
|
||||
| storage-01 | `dnsmasq` | DNS local lab.local |
|
||||
| storage-01 | `chronyd` | NTP |
|
||||
| storage-01 | `sshd` | SSH |
|
||||
| storage-01 | `hermes-agent` | Agent IA (gateway + cron) |
|
||||
| gpu-01 | `chronyd` | NTP |
|
||||
| gpu-01 | `sshd` | SSH |
|
||||
| gpu-01 | `llama-server` | Inférence GPU — Qwen3-8B via ROCm 7.x (port 1234) |
|
||||
| gpu-01 | `llama-server-system` | Inférence CPU — Qwen3-1.7B (port 1236, 14 threads) |
|
||||
| gpu-01 | `llama-server-monitor` | Inférence CPU — Qwen3-1.7B (port 1237, 14 threads) |
|
||||
|
||||
---
|
||||
|
||||
## Logs
|
||||
|
||||
```bash
|
||||
# Logs d'un service en temps réel
|
||||
sudo journalctl -u <service> -f
|
||||
|
||||
# Logs depuis X minutes
|
||||
sudo journalctl -u <service> --since '30 minutes ago'
|
||||
|
||||
# Logs kernel (erreurs matériel, OOM killer...)
|
||||
sudo journalctl -k
|
||||
|
||||
# Logs du démarrage
|
||||
sudo journalctl -b
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Ressources système
|
||||
|
||||
```bash
|
||||
# CPU / RAM / swap
|
||||
free -h
|
||||
top
|
||||
htop # plus lisible (installé via EPEL)
|
||||
|
||||
# Disques
|
||||
df -h
|
||||
lsblk
|
||||
|
||||
# Processus gourmands
|
||||
ps aux --sort=-%mem | head -10
|
||||
ps aux --sort=-%cpu | head -10
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Réseau (NetworkManager)
|
||||
|
||||
```bash
|
||||
# Lister les connexions
|
||||
nmcli con show
|
||||
|
||||
# Détails d'une interface (IP, DNS, gateway)
|
||||
nmcli dev show enp4s0
|
||||
|
||||
# Modifier le DNS d'une interface
|
||||
sudo nmcli con mod enp4s0 ipv4.dns '192.168.10.1'
|
||||
sudo nmcli con up enp4s0
|
||||
|
||||
# Voir le resolv.conf généré
|
||||
cat /etc/resolv.conf
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Mises à jour
|
||||
|
||||
```bash
|
||||
# Voir les mises à jour disponibles
|
||||
sudo dnf check-update
|
||||
|
||||
# Appliquer les mises à jour via Ansible (recommandé — reboot automatique si nouveau kernel)
|
||||
cd /mnt/nvme0n1/nvme0n1p3/Projets/lab/ansible
|
||||
../.venv/bin/ansible-playbook -i inventory.yml playbooks/site.yml --tags update
|
||||
|
||||
# Manuellement sur une machine
|
||||
sudo dnf update -y
|
||||
```
|
||||
|
||||
> **Attention post-reboot RAID5** : vérifier que dnsmasq est démarré
|
||||
> (`systemctl status dnsmasq`). Si `failed`, voir [infra/dnsmasq.md](../infra/dnsmasq.md).
|
||||
> Les `.pyc` Python peuvent être corrompus sur reboot non-propre —
|
||||
> symptôme : `bad marshal data` dans les logs d'une app Python.
|
||||
|
||||
---
|
||||
|
||||
## Infos système rapides
|
||||
|
||||
```bash
|
||||
# Version OS
|
||||
cat /etc/os-release
|
||||
|
||||
# Hostname
|
||||
hostname
|
||||
|
||||
# Uptime
|
||||
uptime
|
||||
|
||||
# Infos CPU
|
||||
lscpu | grep -E "Model name|Socket|Core|Thread"
|
||||
|
||||
# RAM totale
|
||||
free -h | head -2
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue