Funk-lab/admin/install/storage-01.md
Hermes Bot 00e53fc0b8 docs(hermes): sections état vérifié — inspection cluster 2026-06-05
Ajout d'une section '## État vérifié' à chaque doc admin/ basée
sur l'inspection read-only du cluster (systemctl, kubectl, nft, etc.).
Aucune modification de service ni réécriture de documentation existante.

Co-Authored-By: Hermes <hermes@funk.lab>
2026-06-05 12:32:57 +02:00

23 KiB

Installation storage-01

Guide d'installation complet de storage-01 — de l'ISO AlmaLinux à la stack IA complète (Hermes + LiteLLM + Qdrant + PostgreSQL). Écrit après installation réelle.


Sommaire

  1. Rôle et architecture
  2. Installation AlmaLinux 9.7 (base OS)
  3. Configuration réseau initiale (manuelle)
  4. Préparer le poste perso pour Ansible
  5. Cloner le repo et initialiser Ansible
  6. Configurer le vault Ansible (secrets)
  7. Jouer le playbook — phase par phase
  8. Vérifications post-install
  9. Pièges et incidents rencontrés

1. Rôle et architecture

storage-01 est la machine centrale du lab. Elle n'est pas dans le cluster Kubernetes — elle est la fondation sur laquelle tout le reste repose.

Ce qu'elle fait

Fonction Détail
Passerelle NAT Forward LAN cluster → internet, LAN domestique → LAN cluster
DHCP + DNS dnsmasq pour le LAN cluster (192.168.10.0/24) et le wildcard *.lab.local
Stockage RAID5 4 disques SATA 1 TB → 2,7 TB utiles, montés sur /srv/data
NFS Exports vers gpu-01 et le cluster k8s (/srv/data/nfs/k8s, /srv/data/models)
Hermes Agent Agent IA autonome avec mémoire vectorielle
LiteLLM Proxy Routage LLM : Qwen local (gpu-01) ↔ Claude API (Anthropic)
Qdrant Base vectorielle pour la mémoire de Hermes (hermes_memory)
PostgreSQL 16 Bases pour Hermes et LiteLLM

Interfaces réseau

Interface IP Rôle
enp4s0 192.168.1.200 WAN — vers Freebox (LAN domestique 192.168.1.0/24)
enp6s0f3u2c2 192.168.10.1 LAN cluster (192.168.10.0/24) — carte USB-Ethernet

enp6s0f3u2c2 est une carte USB-Ethernet branchée en permanence — les noms d'interface sont contre-intuitifs.

RAID5

4 disques SATA 1 TB (Seagate/WD) assemblés en RAID5 software Linux (md0 ou md127).

  • Capacité utile : ~2,7 TB
  • Tolérance : 1 disque mort
  • Point de montage : /srv/data
  • ⚠️ sdb a généré des erreurs I/O après une coupure de courant — surveiller avec smartctl

2. Installation AlmaLinux 9.7 (base OS)

Télécharger l'ISO

AlmaLinux 9.7 minimal (pas de desktop) : https://repo.almalinux.org/almalinux/9/isos/x86_64/

Flasher sur clé USB :

sudo dd if=AlmaLinux-9.7-x86_64-minimal.iso of=/dev/sdX bs=4M status=progress conv=fsync

Paramètres d'installation (Anaconda)

Dans l'installeur graphique Anaconda :

Langue / clavier : Français ou English — peu importe, Ansible configure le reste.

Disque système : sélectionner le NVMe interne uniquement.

  • Ne pas sélectionner les disques SATA (RAID5) — ils sont gérés manuellement.
  • Partitionnement automatique convient (LVM sur NVMe).

Réseau : configurer uniquement l'interface WAN (enp4s0) pendant l'install :

  • IP statique : 192.168.1.200/24
  • Gateway : 192.168.1.254 (Freebox)
  • DNS : 1.1.1.1
  • Hostname : storage-01

L'interface LAN (enp6s0f3u2c2) sera configurée par Ansible.

Utilisateurs :

  • Root : définir un mot de passe temporaire (sera désactivé par Ansible)
  • Créer un premier utilisateur ansible (ou laisser Ansible le créer — dans ce cas se connecter en root pour la première exécution)

Premier boot

Après l'installation, vérifier que la machine est joignable depuis le poste perso :

ping 192.168.1.200
ssh root@192.168.1.200

3. Configuration réseau initiale (manuelle)

Avant de lancer Ansible, il faut que storage-01 soit SSH-accessible et que les deux interfaces réseau soient opérationnelles. Ces opérations sont faites une seule fois depuis la console ou root SSH.

Configurer l'interface LAN (USB-Ethernet)

# Se connecter en root
ssh root@192.168.1.200

# Identifier la carte USB-Ethernet (généralement enp6s0f3u2c2 ou similaire)
nmcli device status
ip link show

# Créer la connexion NetworkManager
nmcli connection add type ethernet \
  ifname enp6s0f3u2c2 \
  con-name lan-cluster \
  ipv4.method manual \
  ipv4.addresses 192.168.10.1/24 \
  ipv4.never-default yes \
  connection.autoconnect yes

nmcli connection up lan-cluster

Vérifier :

ip addr show enp6s0f3u2c2
# → inet 192.168.10.1/24

Activer l'IP forwarding

echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.d/99-forwarding.conf
sysctl -p /etc/sysctl.d/99-forwarding.conf

Ansible gère aussi l'IP forwarding, mais l'activer maintenant permet aux nœuds Talos de sortir sur internet dès que dnsmasq et nftables seront en place.

Ajouter gpu-01 dans /etc/hosts (si gpu-01 sera installé avant dnsmasq)

echo '192.168.10.20 gpu-01' >> /etc/hosts

4. Préparer le poste perso pour Ansible

Tout Ansible se lance depuis le poste perso (ou storage-01 une fois qu'il est opérationnel — voir section suivante).

Installer Python et créer le venv

# Python 3 doit être disponible
python3 --version

# Créer le venv à la racine du repo
cd /mnt/nvme0n1/nvme0n1p3/Projets/lab
python3 -m venv .venv
source .venv/bin/activate

# Installer ansible-core
pip install -r requirements.txt
# ansible-core>=2.17,<2.18

Installer les collections Ansible

.venv/bin/ansible-galaxy collection install -r ansible/requirements.yml

Générer une clé SSH pour Ansible

# Si pas encore de clé ed25519
ssh-keygen -t ed25519 -C "ansible@poste-perso" -f ~/.ssh/id_ed25519

# Copier la clé publique vers storage-01
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@192.168.1.200

Ansible utilisera le compte ansible (créé par le rôle common) — mais pour la première exécution, il se connecte en root.

Configurer ~/.ssh/config

Host s01
    HostName 192.168.1.200
    User ansible
    IdentityFile ~/.ssh/id_ed25519

Host g01
    HostName 192.168.10.20
    User ansible
    ProxyJump s01
    IdentityFile ~/.ssh/id_ed25519
    StrictHostKeyChecking no

5. Cloner le repo et initialiser Ansible

git clone git@github.com:Alkatrazz24/Funk-lab.git
cd Funk-lab

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
.venv/bin/ansible-galaxy collection install -r ansible/requirements.yml

Structure Ansible du repo

ansible/
├── inventory.yml                  # hosts + groupes
├── playbooks/
│   ├── site.yml                   # import storage-01.yml + gpu-01.yml
│   ├── storage-01.yml             # playbook storage-01
│   └── gpu-01.yml                 # playbook gpu-01
├── group_vars/
│   ├── all/
│   │   ├── vars.yml               # variables globales (dns_domain, cluster_network...)
│   │   └── vault.yml              # secrets chiffrés (Ansible Vault)
│   └── gateway/
│       └── vars.yml               # interfaces réseau storage-01
├── host_vars/
│   ├── storage-01/
│   │   └── vars.yml               # RAID uuid, NFS exports, chemins services
│   └── gpu-01/
│       └── vars.yml               # modèle llama-server, montages NFS
└── roles/
    ├── common/                    # hostname, timezone, EPEL, user ansible, SSH hardenin
    ├── gateway/                   # nftables + NAT + IP forwarding
    ├── dnsmasq/                   # DNS lab.local + DHCP cluster
    ├── nfs_server/                # RAID5 fstab + exports NFS
    ├── postgresql/                # PostgreSQL 16 sur RAID5
    ├── qdrant/                    # Qdrant vectordb sur RAID5
    ├── litellm/                   # LiteLLM proxy + hermes-switch
    ├── hermes_agent/              # Hermes Agent + Dashboard
    ├── rocm/                      # ROCm AMD pour gpu-01
    ├── llama_server/              # llama-server sur gpu-01
    └── nfs_client/                # montages NFS automatiques (gpu-01)

Variables globales (group_vars/all/vars.yml)

dns_domain: lab.local
ntp_servers:
  - 0.fr.pool.ntp.org
  - 1.fr.pool.ntp.org
cluster_network: 192.168.10.0/24
wan_gateway: 192.168.1.254

Variables gateway (group_vars/gateway/vars.yml)

wan_interface: enp4s0          # NIC PCIe — vers Freebox
lan_interface: enp6s0f3u2c2    # NIC USB — vers LAN cluster
wan_ip: 192.168.1.200
lan_ip: 192.168.10.1

Variables storage-01 (host_vars/storage-01/vars.yml)

ansible_host: 192.168.1.200
raid_uuid: "3add8360-fa01-47eb-8aa1-0e84bacbbc15"
raid_mount: /srv/data
nfs_exports:
  - path: /srv/data/nfs/k8s
    network: "{{ cluster_network }}"
    options: "rw,sync,no_subtree_check,no_root_squash"
  - path: /srv/data/models
    network: "{{ cluster_network }}"
    options: "rw,sync,no_subtree_check,no_root_squash"
hermes_data_dir: /srv/data/hermes
postgres_data_dir: /srv/data/postgres
qdrant_data_dir: /srv/data/qdrant

6. Configurer le vault Ansible (secrets)

Le vault contient les mots de passe et l'API key Anthropic. Il est chiffré dans git.

Fichier mot de passe vault

# Créer le fichier de mot de passe (ne jamais le committer — dans .gitignore)
echo "ton-mot-de-passe-vault" > .vault_pass
chmod 600 .vault_pass

ansible.cfg pointe automatiquement dessus :

[defaults]
vault_password_file = .vault_pass

Créer le vault avec les secrets

cd ansible/
../.venv/bin/ansible-vault create group_vars/all/vault.yml

Contenu du vault :

vault_anthropic_api_key: "sk-ant-..."
vault_pg_hermes_password: "mot-de-passe-fort"
vault_pg_litellm_password: "mot-de-passe-fort"

Pour modifier plus tard :

make vault-edit
# ou
cd ansible && ../.venv/bin/ansible-vault edit group_vars/all/vault.yml

7. Jouer le playbook — phase par phase

Il est recommandé d'appliquer les rôles dans l'ordre ci-dessous, par petits blocs, pour valider chaque couche avant de passer à la suivante.

Test de connectivité

make ping
# ou
cd ansible && ../.venv/bin/ansible all -m ping

Sortie attendue :

storage-01 | SUCCESS => {"ping": "pong"}

gpu-01 échouera si pas encore installé — normal.

Phase 1 — Base OS

cd ansible && ../.venv/bin/ansible-playbook playbooks/storage-01.yml --tags common

Le rôle common fait :

  • Hostname → storage-01
  • Timezone → Europe/Paris
  • EPEL activé
  • dnf update -y (tous les packages à jour)
  • Packages de base : vim, curl, wget, git, htop, tmux, rsync, lsof, net-tools, bind-utils
  • Création user ansible avec sudo NOPASSWD
  • Clé SSH publique du poste perso déposée dans ~/.ssh/authorized_keys
  • SSH durci : PermitRootLogin no, PasswordAuthentication no, X11Forwarding no

Après cette étape, les connexions root ne fonctionnent plus — utiliser ssh s01.

Phase 2 — Passerelle (nftables + NAT)

cd ansible && ../.venv/bin/ansible-playbook playbooks/storage-01.yml --tags gateway

Le rôle gateway fait :

  • Déploie /etc/nftables.conf depuis le template (flush + rebuild complet)
  • Active IP forwarding (sysctl net.ipv4.ip_forward=1)
  • Active et redémarre nftables

Vérifier que le NAT fonctionne depuis le LAN cluster :

# Depuis une machine du cluster (si déjà installée)
ssh 192.168.10.11 "curl -s https://ifconfig.me"

Phase 3 — DNS + DHCP (dnsmasq)

cd ansible && ../.venv/bin/ansible-playbook playbooks/storage-01.yml --tags dnsmasq

Le rôle dnsmasq fait :

  • Installe dnsmasq
  • Déploie la config depuis template : DNS lab.local, DHCP 192.168.10.50-99, baux statiques MACs
  • Wildcard *.lab.local → 192.168.10.200 (Traefik)
  • Override systemd : dnsmasq attend que l'interface USB-Ethernet soit prête avant de démarrer

Tester depuis le poste perso :

dig @192.168.10.1 storage-01.lab.local +short
# → 192.168.10.1

dig @192.168.10.1 test.lab.local +short
# → 192.168.10.200 (wildcard)

Sans l'override systemd, dnsmasq démarre avant que enp6s0f3u2c2 (USB-Ethernet) soit disponible → bind(): Address not available → service en échec au boot.

Phase 4 — NFS + RAID5

cd ansible && ../.venv/bin/ansible-playbook playbooks/storage-01.yml --tags nfs_server

Le rôle nfs_server fait :

  • Installe nfs-utils et mdadm
  • Persiste la config RAID dans /etc/mdadm.conf (pour survie aux reboots)
  • Ajoute /srv/data dans /etc/fstab avec _netdev 0 0
  • Crée les répertoires d'export (/srv/data/nfs/k8s, /srv/data/models)
  • Déploie /etc/exports et recharge nfs-server

Vérifier :

ssh s01 "cat /proc/mdstat"          # RAID doit être [4/4] [UUUU]
ssh s01 "sudo exportfs -v"          # doit lister les deux exports
ssh s01 "df -h /srv/data"           # doit afficher ~2.7 TB

UUID du RAID : récupérer avec sudo blkid | grep md sur storage-01 et mettre à jour host_vars/storage-01/vars.yml avant de jouer ce rôle.

Phase 5 — PostgreSQL 16

cd ansible && ../.venv/bin/ansible-playbook playbooks/storage-01.yml --tags postgresql

Le rôle postgresql fait :

  • Installe le repo officiel PGDG (EL9)
  • Désactive le module AppStream par défaut (dnf module disable postgresql)
  • Installe postgresql16-server et python3-psycopg2
  • Crée /srv/data/postgres sur le RAID5 et le configure comme PGDATA
  • Override systemd pour pointer sur le bon PGDATA
  • initdb si la base n'existe pas encore
  • Crée les bases hermes et litellm et leurs users avec les mots de passe du vault

Vérifier :

ssh s01 "sudo -u postgres psql -c '\l'"
# doit lister : hermes, litellm, postgres, template0, template1

Phase 6 — Qdrant

cd ansible && ../.venv/bin/ansible-playbook playbooks/storage-01.yml --tags qdrant

Le rôle qdrant fait :

  • Télécharge le binaire Qdrant (release GitHub)
  • Crée un user système qdrant
  • Configure le stockage dans /srv/data/qdrant
  • Déploie qdrant.service (bind 0.0.0.0:6333, gRPC 6334)
  • Active et démarre le service

Vérifier :

ssh s01 "curl -s http://localhost:6333/healthz"
# → {"result":"ok","status":"ok","time":0.00...}

Phase 7 — LiteLLM Proxy

cd ansible && ../.venv/bin/ansible-playbook playbooks/storage-01.yml --tags litellm

Le rôle litellm fait :

  • Installe litellm via pip dans un venv dédié
  • Déploie /etc/litellm/config.yaml avec les modèles (Qwen local + Claude)
  • Configure master_key: lm-studio (aligné avec LM_API_KEY=lm-studio dans Hermes)
  • Déploie litellm.service (bind 127.0.0.1:4000 — jamais exposé sur le réseau)
  • Déploie le script hermes-switch dans /usr/local/bin/

Config LiteLLM (résumé) :

model_list:
  - model_name: hermes-default
    litellm_params:
      model: openai/qwen3-8b
      api_base: http://192.168.10.20:1234/v1
      api_key: lm-studio

  - model_name: claude-sonnet-4-6
    litellm_params:
      model: anthropic/claude-sonnet-4-6
      api_key: "{{ vault_anthropic_api_key }}"

general_settings:
  master_key: lm-studio

Vérifier :

ssh s01 "curl -s http://localhost:4000/health -H 'Authorization: Bearer lm-studio'"

Phase 8 — Hermes Agent

cd ansible && ../.venv/bin/ansible-playbook playbooks/storage-01.yml --tags hermes_agent

Le rôle hermes_agent fait :

  • Crée un user système hermes avec home sur le RAID5 (/srv/data/hermes)
  • Installe Hermes via son installer officiel dans /opt/hermes
  • Crée le venv Python (/srv/data/hermes/hermes-agent/venv/) avec qdrant-client
  • Déploie ~hermes/.config/hermes/config.yaml :
    • model.provider: lmstudio
    • model.base_url: http://127.0.0.1:4000/v1
    • model.name: hermes-default
  • Déploie hermes-agent.service et hermes-dashboard.service
  • Déploie /usr/local/bin/hermes-tui (wrapper pour TUI interactif)
  • Permissions /opt/hermes711 (traversable, non listable)

Vérifier :

ssh s01 "sudo systemctl status hermes-agent hermes-dashboard"

Dashboard accessible depuis le poste perso (restreint à 192.168.1.10) :

http://192.168.1.200:9119

TUI interactif (doit être lancé sous le compte hermes) :

ssh storage-01
sudo -i -u hermes
cd /srv/data/hermes
hermes --tui

8. Vérifications post-install

Checklist complète

# 1. Réseau
ping 192.168.10.20                              # gpu-01 joignable
ssh g01 "curl -s https://ifconfig.me"          # NAT fonctionnel
dig @192.168.10.1 storage-01.lab.local +short  # DNS lab.local

# 2. RAID
ssh s01 "cat /proc/mdstat"                     # [4/4] [UUUU]
ssh s01 "df -h /srv/data"                      # ~2.7 TB monté

# 3. NFS
ssh s01 "sudo exportfs -v"                     # exports actifs

# 4. PostgreSQL
ssh s01 "sudo -u postgres psql -c '\l'"        # bases hermes + litellm présentes

# 5. Qdrant
ssh s01 "curl -s http://localhost:6333/healthz" | python3 -m json.tool

# 6. LiteLLM
ssh s01 "curl -s http://localhost:4000/health -H 'Authorization: Bearer lm-studio'"

# 7. Hermes
ssh s01 "sudo systemctl is-active hermes-agent hermes-dashboard"

# 8. funk-cluster (script de gestion global)
ssh s01 "sudo /usr/local/bin/funk-cluster status"

Services actifs attendus

ssh s01 "sudo systemctl list-units --type=service --state=running | grep -E 'dnsmasq|nfs|postgres|qdrant|litellm|hermes|nftables'"

9. Pièges et incidents rencontrés


dnsmasq ne démarre pas au boot — "Address not available"

Symptôme : systemctl status dnsmasqbind(): Address not available. Storage-01 rebooté → dnsmasq en failed, plus de DHCP pour le cluster.

Cause : dnsmasq tentait de binder sur 192.168.10.1 (enp6s0f3u2c2, USB-Ethernet) avant que cette interface soit disponible. L'USB-Ethernet est détectée plus tard que les NIC PCIe dans la séquence de boot.

Fix : Un override systemd dans /etc/systemd/system/dnsmasq.service.d/wait-lan.conf :

[Unit]
After=network-online.target sys-subsystem-net-devices-enp6s0f3u2c2.device
Wants=network-online.target sys-subsystem-net-devices-enp6s0f3u2c2.device

Géré par le rôle Ansible dnsmasq — ne pas modifier manuellement.


Boucle fsck au boot après coupure de courant

Symptôme : Boot bloqué sur emergency mode, impossible de saisir le mot de passe root (messages d'erreur défilants), le RAID /dev/md0 ne monte plus.

Cause : Coupure de courant → corruption du filesystem XFS sur almalinux-root (NVMe). systemd tentait de monter /srv/data (RAID5) avant que le RAID soit assemblé, créant une boucle bloquante.

Résolution (procédure complète dans admin/incidents.md) :

  1. Shell via GRUB (init=/bin/bash dans la ligne kernel)
  2. lvm vgchange -ay pour activer le LVM
  3. xfs_repair /dev/mapper/almalinux-root (pas fsck — XFS a son propre outil)
  4. Commenter /srv/data dans /etc/fstab temporairement pour booter
  5. Après boot : corriger fstab → ajouter _netdev 0 0 pour /srv/data

Fix permanent dans fstab :

UUID=3add8360-... /srv/data ext4 defaults,noatime,nodiratime,_netdev 0 0
  • _netdev : attend que les périphériques soient prêts (RAID assemblé) avant de monter
  • 0 0 : désactive le fsck automatique au boot (le RAID a sa propre intégrité)

Géré par le rôle Ansible nfs_server. Vérifier que ces options sont bien présentes.


hermes --tui "gateway error" si lancé sous le mauvais compte

Symptôme : hermes --tui lancé depuis le compte ansible retourne des "gateway error" en boucle. TUI inutilisable.

Cause : Hermes charge sa configuration depuis $HERMES_HOME, qui doit pointer vers /srv/data/hermes. Lancé sous ansible, les variables d'environnement ne sont pas correctes et hermes cherche sa config dans ~ansible/.config/hermes/ qui n'existe pas.

Fix : Toujours lancer le TUI sous le compte hermes :

ssh storage-01
sudo -i -u hermes
cd /srv/data/hermes
hermes --tui

Ou via le wrapper /usr/local/bin/hermes-tui qui gère automatiquement l'environnement.


qdrant-client : méthode search() supprimée en v1.14+

Symptôme : Scripts Python Hermes qui appellent Qdrant échouent avec AttributeError: 'AsyncQdrantClient' object has no attribute 'search'.

Cause : qdrant-client v1.14+ a supprimé la méthode search(). Elle est remplacée par query_points().

Fix : Mettre à jour les scripts pour utiliser query_points(). Le rôle Ansible hermes_agent installe la version compatible — ne pas faire pip install qdrant-client manuellement sans vérifier la version.


LM_API_KEY absent → Hermes ne peut pas appeler LiteLLM

Symptôme : Hermes démarre mais toutes les requêtes vers LiteLLM échouent avec 401.

Cause : Hermes utilise LM_API_KEY comme Bearer token. LiteLLM attend master_key. Les deux doivent avoir la même valeur. Si LM_API_KEY n'est pas défini dans l'environnement du service systemd, Hermes envoie un token vide ou incorrect.

Fix : Le service hermes-agent.service doit avoir dans sa section [Service] :

Environment=LM_API_KEY=lm-studio

La valeur lm-studio est une valeur magique alignée avec master_key: lm-studio dans la config LiteLLM. Géré par le rôle Ansible.


hermes -z ne fonctionne pas depuis n'importe où

Symptôme : hermes -z "question" depuis /home/ansible → erreur de chemin, Hermes ne trouve pas son .git.

Cause : Hermes remonte l'arborescence à la recherche d'un .git pour localiser sa config de projet. Si lancé depuis un répertoire sans .git en amont, il échoue.

Fix : Toujours lancer depuis /srv/data/hermes :

cd /srv/data/hermes && hermes -z "ta question"

Résumé des points d'attention

Sujet Règle
dnsmasq au boot Override systemd obligatoire pour USB-Ethernet
fstab /srv/data _netdev 0 0 — jamais 0 2
TUI Hermes Toujours sous le compte hermes, depuis /srv/data/hermes
hermes -z Toujours depuis /srv/data/hermes
LM_API_KEY Doit valoir lm-studio (= master_key LiteLLM)
qdrant-client Utiliser query_points() pas search() (supprimé en v1.14+)
RAID sdb Surveiller régulièrement avec smartctl -a /dev/sdb
UUID RAID Vérifier host_vars/storage-01/vars.yml avant de jouer nfs_server
Vault .vault_pass ne doit jamais être commité — dans .gitignore

État vérifié — 2026-06-05

  • Services : tous actifs (aucun unité échoué)
  • OS : AlmaLinux 9.7, kernel 5.14.0-687.5.3.el9_8.x86_64
  • Stockage : /srv/data (2.7T) monté, /home (845G), /boot (960M)
  • Mémoire : 29Gi totale, 2.5Gi utilisée
  • Divergences : Aucune divergence notée entre la documentation et l'état réel
  • Éléments opérationnels : Aucun pod crashé rapporté, export NFS non vérifié dans les commandes actuelles