Supervision avec Munin#

Pourquoi#

Les chiffres instantanés (chronyc tracking) confirment que le serveur fonctionne maintenant. Mais la vraie validation d’un Stratum 1 se fait sur la durée : la dérive de fréquence suit-elle un cycle jour/nuit lié à la température ? Le taux d’horodatage matériel se dégrade-t-il avec la charge ? Munin construit des graphes RRD historiques (jour/semaine/mois) qui rendent ces tendances visibles d’un coup d’œil, impossible à obtenir avec une commande instantanée.

Pourquoi Munin plutôt que Prometheus#

Prometheus est aujourd’hui l’outil de supervision le plus répandu, la question mérite donc une réponse argumentée. Quatre raisons ont fait pencher la balance vers Munin sur ce serveur précis :

  • Le profil d’écriture. Munin stocke en RRD : des fichiers de taille fixe, écrits une fois toutes les 5 minutes, sans aucune croissance. Prometheus écrit en continu (base de séries temporelles avec journal WAL) : exactement le profil d’écriture que le chapitre Système de fichiers cherche à éliminer pour préserver la carte SD.
  • Aucun démon permanent. Ici, la supervision n’existe qu’une fois toutes les 5 minutes, confinée sur le cœur 0 en priorité minimale (taskset -c 0 nice -n 19 ionice -c 3, chapitre Télémétrie publique). Prometheus est un processus résident qui consomme CPU et RAM en permanence, sur une machine dont tout l’objet est la stabilité d’ordonnancement à la microseconde.
  • La surface d’attaque. Le modèle Prometheus repose sur un exporter qui écoute sur un port HTTP, un service réseau de plus à durcir et à filtrer. Munin, configuré comme ici, produit des PNG statiques servis par le nginx déjà durci : aucun port supplémentaire exposé.
  • Le besoin réel. Un seul hôte, une poignée de graphes, un rafraîchissement de 5 minutes aligné sur la page publique. Pas de flotte, pas d’alerting exigé, pas de requêtes ad hoc. Prometheus brille précisément là où ce projet n’a pas de besoin.

En contrepartie, Munin ne fait ni résolution fine (5 minutes, contre une quinzaine de secondes de scrape typique), ni langage de requête (PromQL), ni alerting intégré.

Ce choix reste un choix personnel, cohérent avec les contraintes de ce serveur, pas une vérité générale : un lecteur à l’aise avec Prometheus peut tout à fait l’utiliser. La voie propre serait alors d’héberger Prometheus sur une autre machine (le réseau d’administration) et de n’exposer sur le Pi qu’un exporter minimal restreint à ce réseau : le stockage et le calcul quittent le serveur de temps, seule la lecture des métriques reste.

Comment#

Plugins de métrologie#

apt install -y munin munin-node

# Plugin chrony fourni par le paquet
ln -sf /usr/share/munin/plugins/chrony /etc/munin/plugins/chrony

# Plugin communautaire chrony_status (munin-contrib)
curl -fsSL https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/chrony/chrony_status \
    -o /usr/share/munin/plugins/chrony_status
chmod +x /usr/share/munin/plugins/chrony_status
ln -sf /usr/share/munin/plugins/chrony_status /etc/munin/plugins/chrony_status

Plugin maison : offset PHC filtré par médiane#

cat > /usr/share/munin/plugins/ptp_offset <<'EOF'
#!/bin/sh
# Offset entre l'horloge matérielle PTP (/dev/ptp0) et CLOCK_REALTIME

if [ "$1" = "config" ]; then
    echo "graph_title PHC to System Clock Offset"
    echo "graph_vlabel offset (ns)"
    echo "graph_category time"
    echo "offset.label PHC Offset"
    echo "offset.type GAUGE"
    echo "offset.draw LINE2"
    exit 0
fi

PHC_OFFSET=$(/usr/local/sbin/phc-offset-median /dev/ptp0 5)
[ -z "$PHC_OFFSET" ] && PHC_OFFSET="U"
echo "offset.value $PHC_OFFSET"
EOF
chmod +x /usr/share/munin/plugins/ptp_offset
ln -sf /usr/share/munin/plugins/ptp_offset /etc/munin/plugins/ptp_offset

mkdir -p /etc/munin/plugin-conf.d/
cat > /etc/munin/plugin-conf.d/ptp_offset.conf <<'EOF'
[ptp_offset]
user root
EOF

Ce plugin délègue à un script partagé (phc-offset-median) qui répète la lecture 5 fois avec une priorité temps réel et retient la médiane, voir le chapitre PHC pour la justification complète : une lecture unique est vulnérable à des pics d’ordonnancement ponctuels qui produiraient un graphe en dents de scie trompeur.

Configuration Munin#

cat > /etc/munin/munin.conf <<'EOF'
htmldir /var/time
graph_strategy cron
html_strategy disabled
graph_data_size custom 35d
timeout_fetch_all_nodes 240

[time.example.org]
    address 127.0.0.1
    use_node_name yes
EOF

graph_strategy cron régénère les graphes PNG sur le rythme du cron Munin plutôt qu’à la demande (CGI), cohérent avec la philosophie de régénération périodique déjà vue au chapitre Télémétrie publique. html_strategy disabled supprime purement et simplement la génération des pages HTML natives de Munin : ce projet sert sa propre page statique (chapitre précédent) et ne consomme que les PNG, générer en plus des pages HTML inutilisées gaspillerait du CPU et de l’espace sur le tmpfs /var/time à chaque cycle. timeout_fetch_all_nodes 240 (4 minutes) laisse une marge sous le cycle de 5 minutes du cron Munin : si la récupération des métriques dépassait ce délai, elle serait interrompue avant de chevaucher le cycle suivant, plutôt que de laisser deux exécutions s’accumuler.

Erreurs à éviter#

Un plugin sans bit exécutable est ignoré silencieusement, pas d’erreur, pas de log, juste une absence de graphe. Après chaque création ou copie d’un plugin Munin, chmod +x n’est pas optionnel. C’est l’erreur la plus fréquente lors de l’ajout d’un plugin maison ou téléchargé.

  • Tester un plugin avec le mauvais utilisateur. munin-node tourne en root par défaut sur Debian et descend chaque plugin vers l’utilisateur spécifié dans plugin-conf.d/ (souvent munin, parfois root pour les plugins qui ont besoin de privilèges élevés comme ptp_offset). Un test manuel sudo -u munin /usr/share/munin/plugins/ptp_offset peut échouer alors même que le plugin fonctionne correctement via munin-node, ce n’est pas un bug, juste un contexte de privilèges différent. Pour un test fidèle à la réalité, invoquer le plugin en sudo simple (root), ou vérifier explicitement le user= défini dans sa config.
  • Chercher munin-plugins-extra sur une distribution récente. Ce paquet a été fusionné dans munin-node sur les versions récentes de Debian, vérifier avec apt-cache search avant de supposer qu’il manque.
  • Dimensionner graph_data_size sans réfléchir à la rétention réelle souhaitée. Une seule RRA (Round Robin Archive) à résolution fixe (ici 5 minutes sur 35 jours) suffit pour les vues jour/semaine/mois, mais ne couvre pas une vue annuelle avec une résolution fine, un compromis assumé plutôt qu’un oubli, cohérent avec la philosophie “logs volatiles” du reste du projet (chapitre Système de fichiers).

Vérifier#

# Exécution manuelle d'un plugin, tel que munin-node le ferait
sudo /usr/share/munin/plugins/ptp_offset
# Doit retourner "offset.value <nombre>", pas "offset.value U"

# Test de la configuration déclarée par le plugin
sudo /usr/share/munin/plugins/ptp_offset config

munin-run chrony
# Doit retourner des valeurs numériques pour chaque métrique déclarée

# Génération manuelle des graphes (au lieu d'attendre le cron)
munin-cron --force-root
ls -la /var/time/*.png | head