Chrony indique que vous êtes synchronisé. La surveillance continue d’alerter « décalage d’horloge ». Kerberos refuse des tickets de façon aléatoire. Les négociations TLS échouent comme en 2012. Et à chaque redémarrage la machine « téléporte » l’horloge de quelques secondes (ou minutes) par rapport à la réalité.
C’est le mode de défaillance en gestion du temps qui fait perdre le plus d’heures aux ingénieurs : NTP fonctionne techniquement, et pourtant la dérive persiste. Le coupable n’est généralement pas un « NTP mauvais ». C’est la relation entre l’horloge système, l’horloge matérielle (RTC) et la manière dont chrony décide de corriger l’heure. Corrigez cette relation et le problème cesse d’être mystérieux.
Un modèle mental pratique : qui pilote le temps ?
La gestion du temps sous Linux est une relation à trois parties :
- Horloge système (heure du noyau) : ce que vos processus utilisent. C’est ce qui compte pour les logs, les certificats, les timeouts et les systèmes distribués.
- Horloge matérielle (RTC) : une petite horloge alimentée par batterie sur la carte mère. Elle est rudimentaire. Elle dérive. Elle survit aux coupures d’alimentation. Elle n’est pas automatiquement correcte.
- Synchroniseur : chrony (dans ce cas) décide comment influencer l’horloge système à partir des sources de temps et des règles (slew vs step, seuils, offsets, stabilité).
Le schéma de défaillance « NTP fonctionne mais la dérive persiste » est généralement l’un des suivants :
- Le RTC est incorrect, et vous le lisez au démarrage (ou après une mise en veille) et réinfectez l’horloge système avec une mauvaise heure.
- Chrony synchronise, mais il est contraint de slewer lentement tandis que l’horloge système est constamment tirée par autre chose (horloge de l’hôte VM, TSC buggy, un autre service de temps).
- Chrony se synchronise sur la mauvaise source (une source locale, un upstream instable, ou isolée par le réseau) et reste « content » alors que vous dérivez par rapport à l’heure vraie.
Les bugs temporels sont sournois parce que tout continue de « tourner ». C’est juste que ça tourne dans la mauvaise décennie. Un des rares signaux honnêtes est le delta entre les horloges au fil du temps.
Idée paraphrasée, attribuée : Werner Vogels a poussé l’état d’esprit de fiabilité : il faut s’attendre à des échecs et concevoir des systèmes pour les gérer.
La gestion du temps appartient à ce domaine : supposez que votre horloge sera erronée, puis contrôlez-la activement.
Guide de diagnostic rapide (vérifier 1er/2e/3e)
Si vous n’avez que 10 minutes avant que le canal d’incident ne s’enflamme, faites ceci dans l’ordre.
1er : Chrony est-il la seule chose qui pilote l’horloge système ?
Les conflits créent le symptôme classique : « chrony indique synchronisé, mais l’heure saute. » Cherchez des démons concurrents et des agents de synchronisation liés à la virtualisation.
2e : L’horloge système est-elle stable, et y a-t-il eu des steps ?
Les grands sauts impliquent des corrections par pas (ou des réinitialisations externes), pas une dérive. La dérive implique une fréquence stable mais erronée. La solution diffère.
3e : Le RTC vous empoisonne-t-il au démarrage/réveil ?
Si la machine est correcte après avoir tourné un moment mais incorrect juste après un redémarrage, suspectez d’abord le RTC et le paramètre UTC/localtime, pas vos serveurs NTP.
4e : La qualité de la source temporelle est-elle réelle ?
Chrony choisira volontiers une source « joignable » mais instable. Vous voulez faible jitter, faible dispersion et un stratum sensé (la plupart du temps).
5e : Décidez de la politique : slew-only ou autoriser les steps ?
Les systèmes de production ont souvent besoin de steps contrôlés au démarrage (ou après de longues coupures) et de slews en état stable. Configurez cela explicitement.
Faits intéressants et contexte historique (rapide, utile)
- NTP date du début des années 1980, conçu pour un monde où les réseaux étaient lents et les horloges bien pires qu’aujourd’hui.
- Linux distingue « temps » et « fréquence » : discipliner l’horloge signifie corriger à la fois l’offset courant et la vitesse à laquelle elle tourne.
- Les puces RTC ne sont pas des instruments de précision. Beaucoup sont des oscillateurs bon marché dont la dérive varie avec la température et l’âge.
- UTC vs localtime dans le RTC est une guerre culturelle : Linux utilise UTC par défaut ; Windows préfère historiquement localtime. Les machines à double démarrage en pâtissent.
- Les secondes intercalaires existent parce que la Terre est impolie : la rotation n’est pas parfaitement constante, donc le temps civil insère parfois une seconde.
- Chrony a été conçu pour mieux fonctionner sur des réseaux intermittents, comme les portables ou les systèmes qui ne peuvent pas maintenir une reachabilité NTP constante.
- La gestion du temps du noyau a changé significativement avec les CPU modernes : stabilité du TSC, invariant TSC et choix de clocksource affectent la dérive.
- La virtualisation a longtemps été un cauchemar temporel : les hyperviseurs anciens exposaient des compteurs de cycle instables, provoquant dérive ou sauts chez les invités.
- PPS (Pulse Per Second) via GPS peut fournir une discipline sous-microseconde dans une bonne configuration, ce qui rend le NTP sur WAN presque hasardeux en comparaison.
Outils et termes réellement nécessaires
Vous n’avez pas besoin d’un doctorat. Vous avez besoin des bons éclairages :
- Offset : à quel point votre horloge système est éloignée de la source en ce moment.
- Fréquence / skew : la vitesse à laquelle votre horloge tourne par rapport au temps réel ; chrony ajuste cela.
- Step : sauter l’heure immédiatement (utile au démarrage, mauvais pour certaines charges).
- Slew : accélérer ou ralentir lentement l’horloge jusqu’à correspondance (sûr pour la plupart des charges, lent si l’écart est important).
- RTC : l’horloge matérielle que vous lisez/écrivez via
hwclock. - Clocksource du noyau : ce que le noyau utilise pour compter le temps (TSC, HPET, ACPI PM timer, etc.). Un mauvais choix peut provoquer de la dérive.
Une petite blague, comme promis : quand votre horloge dérive, votre timeline post-mortem devient de l’art performance.
Tâches pratiques (commandes, sens des sorties, décisions)
Les règles ici sont strictes : chaque tâche inclut une commande exécutable, ce que la sortie signifie et la décision suivante. Faites-les dans l’ordre si vous n’êtes pas sûr.
Tâche 1 : Confirmez votre pile temporelle (systemd + chrony)
cr0x@server:~$ timedatectl
Local time: Mon 2025-12-30 11:12:03 UTC
Universal time: Mon 2025-12-30 11:12:03 UTC
RTC time: Mon 2025-12-30 11:10:41
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
Sens : « System clock synchronized: yes » est nécessaire mais pas suffisante. La ligne intéressante est RTC time et RTC in local TZ.
Décision : Si le RTC diffère de plus d’une seconde ou deux, prévoyez de corriger la discipline du RTC (tâches ultérieures). Si « RTC in local TZ: yes » sur un serveur, vous voudrez probablement passer à UTC sauf raison de double-démarrage.
Tâche 2 : Assurez-vous que chrony est bien le moteur NTP
cr0x@server:~$ systemctl status chrony --no-pager
● chrony.service - chrony, an NTP client/server
Loaded: loaded (/lib/systemd/system/chrony.service; enabled; preset: enabled)
Active: active (running) since Mon 2025-12-30 09:10:22 UTC; 2h 1min ago
Docs: man:chronyd(8)
man:chronyc(1)
Main PID: 712 (chronyd)
Tasks: 1 (limit: 38219)
Memory: 3.2M
CPU: 1.821s
CGroup: /system.slice/chrony.service
└─712 /usr/sbin/chronyd -F 1
Sens : Chronyd tourne. Le « -F 1 » indique qu’il utilise la correction de fréquence à partir des données de dérive tôt.
Décision : Si chrony n’est pas actif, corrigez cela en premier. S’il est actif, vérifiez les conflits ensuite.
Tâche 3 : Détecter les conflits de service temporel (timesyncd, ntpd, agents vendor)
cr0x@server:~$ systemctl list-units --type=service | egrep -i 'chrony|timesync|ntp|openntpd'
chrony.service loaded active running chrony, an NTP client/server
systemd-timesyncd.service loaded active running Network Time Synchronization
Sens : Vous avez systemd-timesyncd en cours en parallèle de chrony. C’est un duel classique au volant.
Décision : Désactivez timesyncd si chrony est l’autorité choisie.
cr0x@server:~$ sudo systemctl disable --now systemd-timesyncd.service
Removed "/etc/systemd/system/sysinit.target.wants/systemd-timesyncd.service".
Sens : timesyncd est arrêté et ne reviendra pas au démarrage.
Décision : Recontrôlez les symptômes de dérive après quelques heures ; si les sauts cessent, vous avez résolu le problème.
Tâche 4 : Vérifier la vue de chrony sur la santé de la sync (tracking)
cr0x@server:~$ chronyc tracking
Reference ID : 192.0.2.10 (ntp1.example.net)
Stratum : 3
Ref time (UTC) : Mon Dec 30 11:12:00 2025
System time : 0.000214567 seconds slow of NTP time
Last offset : -0.000180123 seconds
RMS offset : 0.000355901 seconds
Frequency : 18.421 ppm slow
Residual freq : -0.012 ppm
Skew : 0.098 ppm
Root delay : 0.012345678 seconds
Root dispersion : 0.001234567 seconds
Update interval : 64.0 seconds
Leap status : Normal
Sens : Le système est ~214 microsecondes en retard. C’est OK. Mais notez Frequency 18.421 ppm slow : votre horloge perdrait ~1,6 seconde par jour sans correction.
Décision : Si la fréquence est grande (par exemple >100 ppm) ou le skew énorme, suspectez un clocksource instable ou la virtualisation. Si les offsets sont faibles mais vos applications signalent un décalage, vous avez peut-être des événements de step/saut (Tâche 7/8).
Tâche 5 : Inspecter les sources et le comportement de sélection
cr0x@server:~$ chronyc sources -v
.-- Source mode '^' = server, '=' = peer, '#' = local clock.
/ .-- Source state '*' = current best, '+' = combined, '-' = not combined,
| / '?' = unreachable, 'x' = time may be in error, '~' = too variable.
|| .- xxxx [ yyyy ] +/- zzzz
|| Reachability register (octal) | xxxx = adjusted offset,
|| Log2(Polling interval) | yyyy = measured offset,
|| | zzzz = estimated error.
|| |
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* ntp1.example.net 2 6 377 21 -180us[ -220us] +/- 900us
^+ ntp2.example.net 2 6 377 19 +120us[ +80us] +/- 1100us
^- 203.0.113.44 3 6 377 17 +980us[ +950us] +/- 5500us
Sens : Vous avez une source préférée (^*) et une sauvegarde combinée (^+). La troisième source n’est pas combinée (^-), probablement à cause de marges d’erreur plus élevées.
Décision : Si la meilleure source a une erreur élevée (+/- dizaines de millisecondes), corrigez votre upstream ou le chemin réseau. Si les sources deviennent injoignables, votre dérive peut être due à de longues périodes sans synchronisation.
Tâche 6 : Vérifier que le noyau n’est pas submergé par des ajustements
cr0x@server:~$ chronyc activity
200 OK
1 sources online
0 sources offline
0 sources doing burst (return to online)
0 sources doing burst (return to offline)
0 sources with unknown address
Sens : Chrony voit une reachabilité stable. Bien.
Décision : Si des sources sont fréquemment hors ligne, corrigez le réseau/pare-feu avant de toucher aux réglages de chrony.
Tâche 7 : Trouver des preuves de steps (sauts temporels)
cr0x@server:~$ journalctl -u chrony --since "24 hours ago" --no-pager | egrep -i 'step|slew|makestep|System clock wrong'
Dec 30 09:10:22 server chronyd[712]: System clock wrong by -3.842311 seconds, adjustment started
Dec 30 09:10:22 server chronyd[712]: System clock was stepped by -3.842311 seconds
Sens : Chrony a stepé l’horloge au démarrage du service. C’est acceptable si c’est seulement au démarrage et dans un seuil attendu.
Décision : Si des steps se produisent en heures ouvrables, ajustez la politique makestep (plus loin), ou trouvez l’acteur externe forçant le step (outils VM, scripts manuels, lectures RTC erronées).
Tâche 8 : Vérifier la stabilité du clocksource (dérive au niveau matériel)
cr0x@server:~$ cat /sys/devices/system/clocksource/clocksource0/current_clocksource
tsc
cr0x@server:~$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource
tsc hpet acpi_pm
Sens : Vous êtes sur TSC. C’est généralement bon sur des CPU modernes avec TSC invariant. Sur certaines plateformes (ou certaines configurations VM) c’est problématique.
Décision : Si vous voyez des valeurs de fréquence sauvages dans chronyc tracking ou des sauts temporels corrélés avec des changements de fréquence CPU, testez un autre clocksource au prochain redémarrage via un paramètre du noyau (avec contrôle des changements).
Tâche 9 : Vérifier le RTC lui-même et le comparer à l’heure système
cr0x@server:~$ sudo hwclock --show
2025-12-30 11:10:41.123456+00:00
cr0x@server:~$ date -u
Mon Dec 30 11:12:07 UTC 2025
Sens : Le RTC a ~86 secondes de retard. Si vous redémarrez maintenant, vous risquez de démarrer avec un retard puis chrony corrigera.
Décision : Si le RTC est systématiquement en retard de dizaines de secondes ou de minutes, rendez explicite la discipline du RTC : soit écrire l’heure système dans le RTC à moments contrôlés, soit utiliser le suivi RTC de chrony pour compenser.
Tâche 10 : Confirmer si votre RTC est traité comme UTC ou localtime
cr0x@server:~$ timedatectl show -p RTCInLocalTZ -p Timezone -p LocalRTC
RTCInLocalTZ=no
Timezone=Etc/UTC
LocalRTC=no
Sens : Le RTC est en UTC. C’est la valeur par défaut sensée pour un serveur.
Décision : Si RTCInLocalTZ=yes et que vous ne faites pas de double-démarrage, changez cela (Tâche 11). Si vous faites du double-démarrage, décidez qui l’emporte et documentez-le.
Tâche 11 : Mettre le RTC en UTC (bonne pratique serveur typique)
cr0x@server:~$ sudo timedatectl set-local-rtc 0 --adjust-system-clock
Sens : L’OS traitera le RTC comme UTC à l’avenir et pourra ajuster l’horloge système pour conserver la cohérence de l’heure locale.
Décision : Faites cela pendant une fenêtre de maintenance si l’horloge système peut être stepée. Ensuite, écrivez une heure système correcte dans le RTC (Tâche 12) une fois que chrony est stable.
Tâche 12 : Écrire l’heure système corrigée dans le RTC (nettoyage unique)
cr0x@server:~$ chronyc waitsync 30
200 OK
cr0x@server:~$ sudo hwclock --systohc --utc
Sens : waitsync s’assure que chrony est synchronisé avant que vous n’exportiez l’heure dans le RTC. --systohc écrit l’heure système dans le RTC.
Décision : Si la dérive du RTC est extrême, vous pouvez répéter cela après un jour et mesurer le taux de dérive. Si la dérive est simplement « mauvaise normale », vous pouvez compenser avec la dérive de chrony et les comportements RTC au lieu d’écritures fréquentes.
Tâche 13 : Confirmer la politique step/slew de chrony (à expliciter)
cr0x@server:~$ grep -v '^\s*#' /etc/chrony/chrony.conf | sed '/^\s*$/d'
pool ntp.example.net iburst maxsources 4
driftfile /var/lib/chrony/chrony.drift
rtcsync
makestep 1.0 3
keyfile /etc/chrony/chrony.keys
leapsectz right/UTC
logdir /var/log/chrony
Sens : makestep 1.0 3 signifie : faire un step si l’offset > 1 seconde, mais seulement lors des 3 premières mises à jour. C’est une stratégie sensée « corriger au boot, puis slewer ». rtcsync maintient le RTC à peu près aligné.
Décision : Si vous ne voyez pas de makestep, vous pourriez slewer indéfiniment après une longue coupure, ce qui ressemble à une dérive persistante. Si vous voyez des steps très permissifs, vous pourriez provoquer des sauts en plein milieu de journée.
Tâche 14 : Rechercher les dégâts liés à suspend/reprise (portables, certains serveurs)
cr0x@server:~$ journalctl --since "7 days ago" --no-pager | egrep -i 'suspend|resume|PM: suspend|PM: resume'
Dec 29 18:44:02 server kernel: PM: suspend entry (deep)
Dec 29 19:12:19 server kernel: PM: suspend exit
Sens : Si c’est un portable ou un serveur avec une gestion d’alimentation agressive, la reprise peut causer des discontinuités temporelles selon la plateforme/firmware.
Décision : Si le skew augmente après une reprise, envisagez une politique de step plus stricte après la reprise (hook de redémarrage du service), ou désactivez la suspension profonde sur les systèmes qui doivent conserver l’heure strictement.
Tâche 15 : Vérifier qu’on ne change pas l’heure manuellement (oui, vraiment)
cr0x@server:~$ journalctl --since "48 hours ago" --no-pager | egrep -i 'set time|time has been changed|CLOCK_SET|adjtimex'
Dec 30 10:03:11 server systemd[1]: Time has been changed
Sens : Quelque chose a déclenché un changement d’heure. Cela peut être un step de chrony, un administrateur ou un autre agent.
Décision : Corrélez les horodatages avec les logs de chrony (Tâche 7). Si ce n’est pas chrony, traquez le coupable : gestion de configuration, outils d’hyperviseur ou scripts maison.
Ajustements chrony qui changent vraiment les résultats
Chrony est souvent « correct » par défaut. Mais « correct » n’est pas synonyme d’« ennuyeux », et l’ennui est ce que vous voulez pour le temps. Voici les boutons qui comptent quand la dérive persiste.
Makestep : contrôler quand le step est autorisé
Pourquoi c’est important : Si un serveur démarre avec 30 secondes d’erreur et que vous n’autorisez que le slew, il peut mettre longtemps à converger. Pendant ce temps, vous aurez des échecs d’authentification et des ordres de logs déroutants. Si vous autorisez le step à tout moment, certaines applications casseront quand l’heure recule.
Ce que je fais sur la plupart des serveurs Debian :
- Autoriser le step tôt après le démarrage seulement, avec un faible seuil.
- Après cela, corrections par slew uniquement.
Exemple de politique (déjà courante dans les defaults Debian-ish, mais vérifiez) :
cr0x@server:~$ sudo bash -lc 'printf "%s\n" "makestep 1.0 3" | tee /etc/chrony/conf.d/10-makestep.conf'
makestep 1.0 3
Sens : Step uniquement si l’offset dépasse une seconde et seulement durant les trois premières mises à jour.
Décision : Si vos offsets au démarrage dépassent régulièrement une seconde (RTC mauvais, longue coupure), corrigez le problème RTC plutôt que d’augmenter le seuil à quelque chose de paresseux comme 30 secondes.
rtcsync vs suivi de dérive RTC : savoir ce que vous achetez
rtcsync ordonne à chronyd de copier périodiquement l’heure système dans le RTC (via le mode noyau 11-minute). Cela aide à garder le RTC assez proche pour qu’un redémarrage ne démarre pas complètement faux.
Mais si votre RTC dérive énormément, écrire fréquemment ne répare pas l’oscillateur ; ça masque juste le symptôme jusqu’à la prochaine longue coupure d’alimentation. Si vous avez besoin de plus, considérez :
- Améliorer l’environnement RTC (mises à jour firmware, désactivation des fonctionnalités d’alimentation étranges).
- Utiliser une source de temps en amont stable (serveurs NTP locaux, PTP dans certains environnements).
- Pour des systèmes vraiment stricts, une référence locale (PPS, GPS) et une stratégie de holdover plus serrée.
Intervalle de poll et comportement burst : arrêtez d’être timide au démarrage
iburst est bon : il utilise des échantillons rapides au démarrage pour converger plus vite. Gardez-le pour les sources réseau. Si votre réseau est instable, vous devrez peut-être conserver plus de sources et éviter un point unique de défaillance temporelle.
Pour une ligne pool :
cr0x@server:~$ grep -R "^\s*pool\|^\s*server" /etc/chrony
/etc/chrony/chrony.conf:pool ntp.example.net iburst maxsources 4
Sens : Utilisation d’un pool (rotation DNS) avec jusqu’à 4 sources. C’est correct.
Décision : En production, préférez plusieurs sources internes stables si vous en avez ; sinon plusieurs sources externes avec des règles firewall sensées (UDP 123) et un DNS fiable.
Stratum local et « je serai ma propre horloge » : n’en faites pas
Chrony peut s’annoncer comme source de temps même sans upstream. Utile pour des labos isolés, dangereux partout ailleurs. Vous créerez un menteur confiant : un serveur qui dit aux autres « je suis l’heure » tout en dérivant.
Si vous voyez des directives de local stratum, faites une pause et demandez pourquoi. La plupart des environnements ne devraient pas le faire sauf s’il s’agit d’un fallback conçu consciemment.
Horloge matérielle et hwclock : rendez-la ennuyeuse
Le RTC n’est pas une horloge atomique. C’est une petite puce avec une batterie, souvent précise comme une montre et pas beaucoup plus. Pourtant nous la traitons comme une vérité sacrée au démarrage. C’est notre faute.
À quoi ressemble « le RTC est incorrect »
- L’heure est correcte après que le système ait tourné pendant des heures, puis incorrecte juste après un redémarrage.
- L’heure est décalée d’un montant constant après chaque perte d’alimentation.
- Les machines en double-démarrage affichent une erreur d’une heure exacte autour des changements DST (mismatch localtime/UTC).
Cessez d’écrire le RTC sans contrôle
Certaines équipes administratives exécutent des cron jobs comme « hwclock –systohc every minute ». Cela transforme les écritures RTC en rituel bruyant et augmente le risque d’écrire une mauvaise heure pendant un transitoire. Si vous allez écrire dans le RTC, faites-le après confirmation de la synchronisation, et pas constamment.
Mesurez le taux de dérive du RTC (pour choisir une politique)
Vous pouvez quantifier la dérive sans outils spéciaux. Faites ceci :
- Synchronisez l’heure système via chrony.
- Écrivez l’heure système dans le RTC une fois.
- Après 24 heures, comparez le RTC à l’heure système à nouveau (sans écrire).
Commandes pour l’étape de comparaison :
cr0x@server:~$ sudo hwclock --show
2025-12-31 11:11:12.000000+00:00
cr0x@server:~$ date -u
Tue Dec 31 11:12:07 UTC 2025
Sens : Le RTC a ~55 secondes de retard sur ~24h, ce qui est sévère. Ce n’est pas un problème de réglage chrony ; c’est un souci matériel/firmware ou une problématique de plateforme.
Décision : Pour ce niveau de dérive, comptez sur la discipline NTP et traitez le RTC comme « bootstrap au démarrage uniquement », tout en investiguant les mises à jour du BIOS, des problèmes de carte mère ou le remplacement matériel si c’est important.
Virtualisation et portables : usines à dérive
Sur du matériel bare metal avec des clocksources stables, chrony converge généralement et reste ennuyeux. Les VM et les portables ajoutent du chaos :
- Les agents de synchronisation du temps des VM peuvent stepper l’horloge du guest derrière le dos de chrony.
- Le scaling de fréquence CPU et les états de veille peuvent changer le comportement de l’oscillateur et la stabilité temporelle.
- La saturation de l’hôte peut retarder l’ordonnancement des vCPU, faisant paraître le temps « en retard », puis rattraper son retard.
Détecter une VM et vérifier les fonctions temporelles de l’hyperviseur
cr0x@server:~$ systemd-detect-virt
kvm
Sens : Vous êtes dans KVM. C’est généralement acceptable, mais vous devez vous assurer que le guest utilise des horloges paravirtualisées et qu’aucun outil concurrent de synchronisation ne steppe le temps.
Décision : Si vous exécutez des agents invités qui synchronisent l’heure, désactivez leur synchronisation temporelle ou configurez-les pour ne pas lutter contre chrony.
Vérifier l’état de discipline temporelle du noyau (état NTP du noyau)
cr0x@server:~$ timedatectl timesync-status
Server: 192.0.2.10 (ntp1.example.net)
Poll interval: 1min 4s (min: 32s; max 34min 8s)
Leap: normal
Version: 4
Stratum: 3
Reference: 9C00020A
Precision: 1us (-20)
Root distance: 1.652ms (max: 5s)
Offset: -214us
Delay: 1.233ms
Jitter: 211us
Sens : Même si chrony est le client réel, systemd peut toujours rapporter l’état de discipline NTP du noyau. Cela donne une autre vue de l’offset/jitter.
Décision : Si la root distance est énorme ou l’offset oscille, concentrez-vous d’abord sur la qualité des sources et l’ordonnancement en virtualisation.
Deuxième petite blague : si vous déboguez la dérive d’une VM à 3 h du matin, souvenez-vous que le guest n’est pas en retard — il vit dans un autre fuseau horaire appelé « contention de l’hôte ».
Trois mini-histoires d’entreprise (comment ça casse en vrai)
Mini-histoire 1 : L’incident causé par une fausse supposition
L’entreprise exploitait une flotte de nœuds API basés sur Debian derrière un load balancer. Tout semblait normal : latence faible, taux d’erreur faibles. Puis, lors d’une rotation de certificats, un petit pourcentage de nœuds a commencé à échouer aux appels TLS sortants avec « certificate not yet valid ». Les échecs n’étaient pas uniformes ; ils arrivaient par vagues.
L’ingénieur de garde a vérifié chrony et a vu qu’il était synchronisé. Cela semblait écarter la dérive. Ils ont escaladé vers le réseau et la PKI, parce que « NTP est OK ». Cette hypothèse était le piège : « synchronisé » était interprété comme « stable ».
Le vrai problème était au démarrage : le RTC était conservé en heure locale sur certains hôtes à cause d’un artefact d’image de test matériel pour double-démarrage. Au redémarrage, ces nœuds démarraient minutes de travers, puis chrony les remettait en ordre en quelques cycles de mise à jour. Entre le démarrage et la stabilisation, les fenêtres de validité TLS les frappaient.
La correction n’était pas exotique. Ils ont standardisé le RTC en UTC, désactivé le second service temporel qui se battait parfois avec chrony, et ajouté une porte de santé : les nœuds ne pouvaient pas rejoindre le pool du load balancer tant que chronyc waitsync n’avait pas réussi.
La leçon : « NTP synchronisé » est un état, pas une garantie. Traitez le temps comme toute autre dépendance. Vous ne mettez pas un nœud en service juste parce que le processus tourne.
Mini-histoire 2 : L’optimisation qui s’est retournée contre eux
Une équipe performance voulait des démarrages plus rapides et moins de bruit en arrière-plan. Ils ont remarqué que chrony faisait parfois un burst initial et un step au démarrage. Ça paraissait « désordonné ». Quelqu’un a décidé de retirer iburst et de désactiver complètement le step — slew-only, toujours. Ça semblait plus élégant. Le temps devrait être fluide, non ?
Ça a bien marché sur les nœuds sains. Puis un sous-ensemble de machines est resté un week-end dans une baie avec un switch top-of-rack mal configuré. Aucune reachabilité NTP pendant deux jours. Quand le réseau a été rétabli, les serveurs étaient décalés de dizaines de secondes.
La correction slew-only a fait qu’ils ont mis longtemps à converger. Pendant cette convergence, les traces distribuées ont été mélangées, des caches ont expiré trop tôt/tard, et un job batch dépendant de partitions temporelles a commencé à lire des chemins « futurs ». Les opérations ne pouvaient pas décider de ce qui s’était passé quand, ce qui est une misère particulière.
Ils ont restauré une politique makestep sensée : step uniquement tôt dans le processus de sync. Ils ont aussi ajouté de l’alerte sur « temps depuis la dernière sync » et « offset absolu courant », pas seulement « daemon en cours ».
Leçon d’optimisation : un temps fluide est bien, mais la correction est meilleure. Le step au démarrage n’est pas une faute morale ; c’est une correction contrôlée. Rendre cela explicite et borné.
Mini-histoire 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise
Une entreprise de type bancaire gérait un environnement mixte : bases de données bare metal, serveurs d’applications VM, et quelques appliances legacy. Leur architecture temporelle était sans glamour : deux serveurs NTP internes par datacenter, chacun avec plusieurs upstreams, et une gestion de configuration stricte pour s’assurer que chaque nœud utilisait chrony avec la même politique de base.
Un matin, un upstream a eu des problèmes provoquant des pics de jitter NTP. Beaucoup d’environnements auraient discrètement dégradé. Dans celui-ci, la sélection de sources de chrony et les bornes d’erreur maximale ont aidé, mais le vrai héros était la pratique ennuyeuse : ils avaient une vérification régulière qui comparait la sortie chronyc tracking sur un échantillon de nœuds et alertait sur les valeurs aberrantes de fréquence et de skew, pas seulement l’offset.
Ils ont repéré deux clusters VM où les retards d’ordonnancement de l’hôte faisaient dériver les invités plus que d’habitude. Ces invités ne semblaient pas « down ». Ils semblaient « un peu bizarres ». La détection d’outliers les a signalés avant que l’authentification commence à échouer.
La mitigation a été simple : pinner temporairement des ressources vCPU pour les pires et rééquilibrer les charges. Le correctif long terme a impliqué d’ajuster les paramètres temporels de l’hyperviseur et de s’assurer que les agents invités ne stepperaient pas les horloges.
Le point : la gestion du temps est un de ces domaines où les processus ennuyeux sont tout le jeu. Alarmez sur les bons indicateurs, imposez la cohérence, et le bizarre devient visible tôt.
Erreurs courantes : symptôme → cause racine → correctif
-
Symptôme : Chrony indique « System clock synchronized: yes » mais vos logs applicatifs montrent l’heure qui recule.
Cause racine : Step de l’horloge en runtime (chronymakesteptrop permissif, ou un autre agent qui steppe).
Fix : Restreindre le step au démarrage (makestep 1.0 3), désactiver les services concurrents de synchronisation, et investiguer les outils VM. -
Symptôme : L’heure est incorrecte juste après le redémarrage, puis se corrige lentement.
Cause racine : RTC incorrect ou traité en localtime alors qu’il devrait être en UTC.
Fix : Mettre le RTC en UTC (timedatectl set-local-rtc 0), puis après synchronisation chrony, écrire l’heure système dans le RTC (hwclock --systohc --utc). -
Symptôme : L’offset continue de croître malgré des sources « correctes ».
Cause racine : Clocksource instable ou ordonnancement en virtualisation provoquant une instabilité de fréquence ; chrony corrige constamment mais perd du terrain.
Fix : Valider le clocksource, mettre à jour le firmware, envisager un autre clocksource, et corriger la contention de l’hyperviseur. -
Symptôme : Chrony alterne fréquemment la meilleure source, avec
~« trop variable ».
Cause racine : Mauvaise qualité NTP upstream, chemin réseau asymétrique, ou problèmes de firewall/NAT.
Fix : Utiliser moins de sources mais meilleures ; préférer NTP interne ; assurer UDP 123 stable ; éviter le hairpin NAT pour le temps. -
Symptôme : La dérive arrive principalement après suspend/reprise.
Cause racine : Comportement firmware/clocksource durant la mise en veille ; discontinuités temporelles au réveil.
Fix : Resynchroniser immédiatement au réveil (redémarrer chrony ou forcer un burst), ou désactiver la veille profonde pour les systèmes à contraintes temporelles. -
Symptôme : Kerberos « clock skew too great » sporadiquement sur certains nœuds seulement.
Cause racine : Nœuds qui convergent lentement après des pannes à cause d’une politique slew-only, ou RTC qui empoisonne au démarrage.
Fix : Autoriser un step contrôlé tôt, mettre une porte de readiness surchronyc waitsync, corriger la discipline RTC. -
Symptôme : Après un changement de fuseau/DST, les horodatages sont décalés d’une heure exacte.
Cause racine : RTC réglé en localtime combiné aux transitions DST, ou conflits de double-démarrage.
Fix : Standardiser le RTC en UTC sur les hôtes Linux ; si double-démarrage, choisir une politique et l’appliquer de façon cohérente.
Listes de contrôle / plan pas à pas
Checklist A : Arrêter l’hémorragie (15–30 minutes)
- Confirmer que chrony tourne :
systemctl status chrony. - Désactiver les daemons concurrents de synchronisation temporelle : supprimer
systemd-timesyncdsi chrony est primaire. - Vérifier les steps récents :
journalctl -u chrony | egrep -i 'stepped|wrong by'. - Inspecter tracking et sources :
chronyc trackingetchronyc sources -v. - Si l’offset est grand et que vous êtes juste après le démarrage, autoriser un step contrôlé (configurer
makestep) et redémarrer chrony pendant une fenêtre de maintenance.
Checklist B : Rendre le comportement du RTC déterministe (1–2 heures)
- Décidez la politique RTC : UTC pour les serveurs sauf raison forte.
- Appliquez la politique :
timedatectl set-local-rtc 0 --adjust-system-clock. - Attendez la sync :
chronyc waitsync 30. - Écrivez l’heure système correcte dans le RTC une fois :
hwclock --systohc --utc. - Activez
rtcsyncdans chrony pour « garder le RTC suffisamment proche ».
Checklist C : Vérifier la stabilité dans le temps (24–72 heures suivantes)
- Enregistrez la base :
chronyc trackingfréquence/skew et différence RTC (hwclock --showvsdate -u). - Surveillez les événements de step dans les logs.
- Si la fréquence est extrême ou instable, investiguez le clocksource et la virtualisation.
- Alertez sur « temps depuis la dernière sync » et « offset absolu », pas seulement « chrony est actif ».
FAQ
1) Chrony indique synchronisé. Pourquoi ma supervision rapporte-t-elle encore une dérive ?
La supervision peut comparer contre une référence différente (un autre serveur NTP, un appliance de monitoring ou un skew au niveau applicatif). Vérifiez avec chronyc tracking et assurez-vous qu’aucun autre service ne change l’heure. Vérifiez aussi les événements de step dans journalctl.
2) Dois-je garder l’horloge matérielle en UTC ou en heure locale ?
UTC pour les serveurs. L’heure locale est surtout pour la commodité du double-démarrage avec Windows. UTC évite les bizarreries DST et réduit les incidents « exactement une heure de décalage ».
3) Est-ce sûr d’autoriser le step temporel ?
Oui, si vous le limitez. Autorisez le step tôt après le démarrage (ou après de longues périodes non synchronisées) via makestep. Évitez les steps en état stable pour les systèmes sensibles aux reculs d’heure.
4) Que signifie « Frequency 18 ppm slow » dans chronyc tracking ?
Votre horloge tourne lentement de 18 parties par million. C’est environ 1,6 seconde par jour sans correction. Chrony compense en ajustant la vitesse de l’horloge système.
5) Mon RTC diffère de l’heure système d’une minute. Est-ce normal ?
Non. Quelques secondes sur plusieurs jours peuvent arriver sur des RTC faibles. Une minute suggère un problème firmware/matériel, une mauvaise configuration (localtime/UTC), ou que le RTC n’est pas entretenu (pas de rtcsync et pas de politique de sync périodique).
6) Dois-je exécuter hwclock --systohc régulièrement ?
Généralement non. Utilisez rtcsync et laissez le système garder le RTC suffisamment proche. Faites une écriture unique après correction de la configuration, et n’ajoutez des écritures planifiées que si vous avez mesuré un besoin.
7) La virtualisation peut-elle causer une dérive même avec des sources NTP parfaites ?
Oui. Les retards d’ordonnancement des invités, les horloges virtuelles instables et les outils d’hyperviseur qui stepent le temps peuvent créer dérive ou sauts. Confirmez le type de virtualisation et retirez les mécanismes concurrents de synchronisation.
8) Quelle est la manière la plus rapide de prouver que le RTC est le problème ?
Comparez le RTC à l’heure système juste avant un redémarrage, redémarrez, puis comparez à nouveau immédiatement après le démarrage avant que chrony converge. Si l’heure après démarrage est incorrecte dans la même direction, le RTC empoisonne l’horloge système au démarrage.
9) Pourquoi la dérive s’aggrave-t-elle sous forte charge CPU ?
Sous forte charge, les invités VM peuvent être désordonnancés et « prendre du retard », puis rattraper. Sur du bare metal, la charge peut exposer des bizarreries du clocksource ou du firmware de gestion d’alimentation. Le symptôme est souvent un jitter accru et des estimations de fréquence instables.
10) Dois-je remplacer chrony par un autre client NTP ?
Pas en premier lieu. Chrony est généralement excellent sur Debian, surtout pour la connectivité intermittente et les réseaux modernes. La plupart des bugs « chrony dérive » sont en réalité de la mauvaise gestion du RTC, des conflits ou des problèmes de qualité upstream.
Conclusion : étapes suivantes pour arrêter la dérive
Quand NTP « fonctionne » mais que la dérive persiste, vous ne regardez pas un problème unique. Vous regardez un problème de gouvernance : qui est autorisé à régler l’heure, quand et sur quelle autorité.
- Choisissez une autorité temporelle unique sur l’hôte (chrony) et retirez les concurrents (timesyncd, agents vendor qui stepent l’heure).
- Rendez explicite la politique de step : step tôt, slew ensuite. Utilisez
makestepcomme il faut. - Corrigez le contrat RTC : mettez le RTC en UTC, écrivez l’heure correcte une fois après la sync et utilisez
rtcsyncpour le garder proche. - Validez le clocksource de la plateforme si la fréquence/le skew semblent instables, en particulier dans les VM.
- Opérationnalisez : gatez la mise en service des services sur la sync, et alarmez sur l’offset et la perte de sync — pas seulement « daemon actif ».
Si vous faites ces cinq choses, la gestion du temps sous Debian 13 devient ce qu’elle devrait être : invisible, ennuyeuse, et pas la raison pour laquelle votre pile d’authentification devient soudainement « mystérieusement instable ».