Tout indique « synchronisé ». Vos tableaux de bord sont verts. Pourtant vos journaux prétendent que le serveur effectue un voyage temporel lent : les négociations TLS foirent, Kerberos devient capricieux, les fenêtres de sauvegarde glissent et les traces distribuées ressemblent à de l’art moderne.
C’est le type d’échec qui rend les SRE méfiants envers la réalité elle-même : NTP « fonctionne », mais la dérive persiste. La solution n’est rarement « redémarrer chrony ». La solution consiste à comprendre quelle horloge ment, qui discipline qui, et ce que votre matériel (ou hyperviseur) fait en coulisses.
Ce que signifie réellement « NTP indique synchronisé mais la dérive persiste »
Quand les gens disent « NTP fonctionne », ils veulent généralement dire l’un de ces points :
- Le service est actif (chronyd fonctionne).
- Des sources sont joignables (certains serveurs apparaissent en ligne).
- L’horloge système n’est pas complètement à côté de la plaque au moment où ils vérifient.
Quand ils disent « la dérive persiste », ils veulent souvent dire autre chose :
- L’horloge est correcte juste après le démarrage mais erronée quelques heures plus tard.
- L’horloge est correcte, mais effectue des sauts vers l’avant/arrière de temps en temps.
- NTP rapporte synchronisé, pourtant les horodatages des applications divergent entre nœuds.
- L’horloge système est correcte, mais l’horloge matérielle (RTC) est fausse, donc chaque reboot repart d’une mauvaise date.
Le piège : NTP n’est pas une « fonction qui règle l’heure une fois pour toutes ». C’est un système de contrôle. Si la boucle de contrôle se bat contre un mauvais oscillateur, un clocksource défectueux, un assombrissement temporel du hyperviseur ou une politique qui interdit le stepping, vous aurez le statut « synchronisé » et ressentirez tout de même des symptômes de dérive.
Faits intéressants et contexte historique (pour cesser de lutter contre la physique)
- NTP est antérieur à l’Internet moderne. Les premiers travaux sur la spécification NTP ont commencé au début des années 1980 ; c’est plus ancien que la plupart des carrières « cloud-native ».
- Le temps Unix n’est pas monotone. L’horloge murale peut reculer ; le temps monotone est un compteur séparé utilisé pour mesurer des intervalles.
- Les secondes intercalaires ne sont pas théoriques. Elles ont été insérées des dizaines de fois depuis les années 1970, et la gestion varie selon les systèmes.
- Le RTC PC n’a jamais été conçu comme source de précision. C’est une horloge de commodité destinée à survivre aux cycles d’alimentation, pas à gagner des prix d’exactitude.
- Les oscillateurs quartz dérivent avec la température et l’âge. Les composants grand public dérivent couramment de plusieurs dizaines de ppm ; ce sont des secondes par jour, pas par mois.
- Certaines couches de virtualisation « aident » en forçant le temps du guest. Cela peut se battre avec chrony, produisant des offsets en dents de scie et des sauts « mystérieux ».
- Le choix du clocksource du noyau compte. Un TSC stable peut être excellent ; un TSC instable, c’est le chaos avec déni plausible.
- Chrony a été conçu pour des réseaux moches. Il gère mieux la connectivité intermittente et les variations de latence importantes que ntpd classique dans de nombreux cas.
Mode opératoire de diagnostic rapide
Quand une dérive temporelle est signalée, vous voulez rapidement identifier le goulot : est-ce l’entrée (mauvaises sources), la politique de contrôle (pas de stepping, seuils erronés), l’oscillateur (matériel/VM instable), ou le chemin de démarrage (RTC erronée) ? Faites cela dans l’ordre :
1) Confirmez quelle heure est incorrecte (horloge système vs RTC vs « heure app »)
- Vérifiez l’heure système, le fuseau horaire et l’état de synchronisation.
- Vérifiez l’heure du RTC et si elle est stockée en UTC.
- Vérifiez si la plainte concerne l’ordre des journaux, la validité TLS ou des timers monotones (causes différentes).
2) Regardez la vision de chrony sur la réalité
- Est-ce que chrony suit une source stable ?
- Est-il en train de rattraper lentement à cause de limites ?
- Effectue-t-il des sauts fréquents parce que les offsets deviennent énormes ?
3) Cherchez des sauts temporels et des conflits
- Messages du noyau au sujet de l’instabilité du clocksource.
- Outils VM / agent d’hôte forçant le temps du guest.
- Plusieurs démons de temps tournant simultanément.
4) Si c’est stable en fonctionnement mais erroné après un reboot : chemin RTC
- Configuration hwclock, décalage UTC/local, synchronisation périodique manquante.
- Pile de la batterie du RTC défaillante (oui, ça existe toujours).
Une citation qui mérite d’être collée près de votre front : idée paraphrasée de Gene Kranz : « Soyez dur et compétent. » Les bugs de conservation du temps requièrent ces deux qualités.
Modèle mental : trois horloges et quelques menteurs
Sur un système Debian 13, vous vous souciez de trois constructions temporelles :
- Horloge système (alias horloge murale) : ce que
dateaffiche ; utilisée pour les horodatages, la validité des certificats, cron, Kerberos, les logs. - Horloge monotone : utilisée pour mesurer les intervalles ; ne doit pas reculer ; les démons temporels peuvent ajuster sa vitesse indirectement, mais elle ne « saute » pas de la même façon.
- Horloge matérielle (RTC) : une horloge sur batterie sur la carte mère (ou équivalent virtuel). Utilisée au démarrage pour initialiser l’horloge système.
NTP/chrony discipline l’horloge système. Il ne corrige pas automatiquement votre RTC sauf si vous la synchronisez explicitement ou configurez un service pour le faire. Si votre RTC est erronée, vous redémarrerez avec une mauvaise heure, puis chrony passera du temps à la corriger—parfois lentement, parfois pas du tout si la politique interdit le stepping.
De plus : Debian peut exécuter systemd-timesyncd ou chrony (ou les deux, ce qui n’est pas une démonstration impressionnante). Choisissez-en un. Pour les serveurs, choisissez chrony. Il est plus transparent, plus configurable, et il vous dit ce qu’il pense se passer.
Blague #1 : Le temps est une illusion. Chrony est une illusion avec des journaux.
Tâches pratiques : commandes, sorties et décisions (12+)
Voici les tâches que j’exécute en production quand quelqu’un affirme « NTP est correct » alors que l’heure système ne l’est clairement pas. Chaque tâche inclut : la commande, une forme de sortie réaliste, et la décision suivante.
Task 1: Check the current state with timedatectl
cr0x@server:~$ timedatectl
Local time: Tue 2025-12-31 10:14:22 UTC
Universal time: Tue 2025-12-31 10:14:22 UTC
RTC time: Tue 2025-12-31 09:58:05
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
Ce que cela signifie : L’horloge système est synchronisée, mais le RTC a ~16 minutes de retard. C’est un piège au redémarrage.
Décision : Si c’est un vrai RTC matériel, prévoyez de synchroniser le RTC depuis l’horloge système une fois que chrony est stabilisé (et enquêter pourquoi le RTC dérive). Si c’est une VM, vérifiez les réglages de synchronisation hôte/guest.
Task 2: Verify which time sync service is active (avoid daemon fights)
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 Tue 2025-12-31 09:50:10 UTC; 24min ago
Docs: man:chronyd(8)
man:chronyc(1)
Process: 612 ExecStart=/usr/sbin/chronyd -F 1 (code=exited, status=0/SUCCESS)
Main PID: 640 (chronyd)
Tasks: 1
Memory: 3.2M
CPU: 120ms
CGroup: /system.slice/chrony.service
└─640 /usr/sbin/chronyd -F 1
cr0x@server:~$ systemctl status systemd-timesyncd --no-pager
● systemd-timesyncd.service - Network Time Synchronization
Loaded: loaded (/lib/systemd/system/systemd-timesyncd.service; disabled; preset: enabled)
Active: inactive (dead)
Ce que cela signifie : Bien : seul chrony est actif.
Décision : Si les deux sont actifs, désactivez systemd-timesyncd (ou supprimez chrony, mais ne le faites pas sur des serveurs sans raison).
Task 3: Get chrony’s tracking view (is it confident or guessing?)
cr0x@server:~$ chronyc tracking
Reference ID : 203.0.113.10 (ntp1.example.net)
Stratum : 3
Ref time (UTC) : Tue Dec 31 10:14:18 2025
System time : 0.000423812 seconds slow of NTP time
Last offset : -0.000221901 seconds
RMS offset : 0.000612554 seconds
Frequency : 24.731 ppm fast
Residual freq : -0.112 ppm
Skew : 0.931 ppm
Root delay : 0.022741 seconds
Root dispersion : 0.004921 seconds
Update interval : 64.2 seconds
Leap status : Normal
Ce que cela signifie : L’horloge système est effectivement correcte pour l’instant. La fréquence est à +24,7 ppm, ce qui n’est pas fou pour du matériel grand public, mais indique une dérive compensée par chrony.
Décision : Si des utilisateurs signalent encore une dérive, il s’agit probablement de redémarrages/RTC, de sauts périodiques ou d’un autre composant qui écrase le temps.
Task 4: Inspect sources quality (you can’t discipline against garbage)
cr0x@server:~$ chronyc sources -v
.-- Source mode '^' = server, '=' = peer, '#' = local clock.
/ .- Source state '*' = current best, '+' = combined, '-' = not combined,
| / 'x' = may be in error, '~' = too variable, '?' = unreachable.
|| .- 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 22 -221us[ -311us] +/- 8ms
^+ ntp2.example.net 2 6 377 21 -102us[ -190us] +/- 10ms
^- ntp3.example.net 3 6 377 20 +891us[ +830us] +/- 22ms
Ce que cela signifie : Reachabilité saine (377), plusieurs sources, petits offsets. Ce n’est pas votre problème.
Décision : Si vous voyez ? inaccessible ou ~ trop variable, corrigez le chemin réseau, le pare-feu, ou choisissez de meilleurs serveurs.
Task 5: Check for stepping events and big corrections
cr0x@server:~$ journalctl -u chrony --since "today" --no-pager
Dec 31 09:50:10 server chronyd[640]: chronyd version 4.5 starting (+CMDMON +NTP +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +ASYNCDNS +NTS)
Dec 31 09:50:11 server chronyd[640]: System clock was stepped by -963.241 seconds
Dec 31 09:50:11 server chronyd[640]: Selected source 203.0.113.10
Dec 31 09:52:15 server chronyd[640]: System clock TAI offset set to 37 seconds
Ce que cela signifie : Au démarrage, l’horloge avait presque 16 minutes de retard et a été ajustée d’un coup. Cela vient généralement d’un RTC défectueux ou d’un mauvais amorçage initial.
Décision : Corrigez le RTC, et assurez-vous que chrony est autorisé à effectuer des sauts tôt au démarrage (makestep), sinon les services démarrent avec une mauvaise heure et ne se rétablissent jamais complètement.
Task 6: Compare RTC vs system time directly
cr0x@server:~$ sudo hwclock --show
2025-12-31 09:58:15.123456+00:00
cr0x@server:~$ date -u
Tue Dec 31 10:14:31 UTC 2025
Ce que cela signifie : Le RTC est en retard. Si vous redémarrez maintenant, vous démarrerez dans le passé.
Décision : Si c’est un serveur physique, envisagez un problème de batterie/firmware du RTC. Si c’est une VM, ne traitez pas le RTC comme autorité et corrigez l’intégration hôte/guest.
Task 7: Check whether RTC is configured as UTC (it should be)
cr0x@server:~$ cat /etc/adjtime
0.000000 1767174612 0.000000
0
UTC
Ce que cela signifie : Le RTC est attendu en UTC. Bien.
Décision : Si vous voyez LOCAL ici sur un serveur, corrigez-le sauf si vous avez une raison précise de dual-boot.
Task 8: Identify clocksource and whether the kernel thinks it’s stable
cr0x@server:~$ cat /sys/devices/system/clocksource/clocksource0/current_clocksource
tsc
cr0x@server:~$ dmesg | grep -i clocksource | tail -n 8
[ 0.000000] tsc: Detected 2592.000 MHz processor
[ 0.120000] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x2557f2f71a, max_idle_ns: 440795309246 ns
[ 0.130000] clocksource: Switched to clocksource tsc
Ce que cela signifie : Utilisation du TSC. Sur du matériel moderne, cela peut être excellent. Sur certaines plateformes virtualisées ou avec gestion d’alimentation agressive, cela peut poser problème.
Décision : Si vous voyez des avertissements d’instabilité ou des sauts de temps fréquents, testez un autre clocksource (voir section ultérieure).
Task 9: Detect time jumps and “clock went backwards” at the application layer
cr0x@server:~$ journalctl -k --since "today" | grep -E "time.*(jump|backward)|clocksource.*unstable" --no-pager
Dec 31 10:02:44 server kernel: clocksource: timekeeping watchdog on CPU2: Marking clocksource 'tsc' as unstable because the skew is too large
Dec 31 10:02:44 server kernel: clocksource: Switched to clocksource hpet
Ce que cela signifie : Le noyau a détecté l’instabilité du TSC et a basculé de clocksource. C’est un indicateur fort pour « la dérive persiste ».
Décision : Corrigez les réglages BIOS/firmware, désactivez les C-states agressifs ou épinglez un clocksource stable. Sur les VM, corrigez les paramètres hôte/tsc.
Task 10: Ensure NTP packets are not being blocked or mangled
cr0x@server:~$ sudo ss -uapn | grep :123
UNCONN 0 0 0.0.0.0:123 0.0.0.0:* users:(("chronyd",pid=640,fd=5))
UNCONN 0 0 [::]:123 [::]:* users:(("chronyd",pid=640,fd=6))
cr0x@server:~$ sudo nft list ruleset | grep -n "dport 123" | head
127: udp dport 123 accept
Ce que cela signifie : chrony écoute ; le pare-feu autorise NTP.
Décision : Si aucune règle d’accept n’existe et que les sources sont inaccessibles, ajoutez une règle ou corrigez le pare-feu en amont.
Task 11: Verify the system clock discipline status (kernel PLL behavior)
cr0x@server:~$ timedatectl show-timesync --all
SystemNTPServers=
FallbackNTPServers=
ServerName=
ServerAddress=
RootDistanceMaxUSec=5s
PollIntervalMinUSec=32s
PollIntervalMaxUSec=34min 8s
Frequency=24731
Ce que cela signifie : Cette sortie est davantage pertinente pour systemd-timesyncd, mais elle peut montrer des valeurs de fréquence de discipline. Ne lui donnez pas plus d’importance si vous êtes sur chrony.
Décision : Utilisez les outils de chrony pour la vérité ; évitez de mélanger les interprétations entre démons.
Task 12: Check if chrony is allowed to step when needed (boot-time correctness)
cr0x@server:~$ grep -nE "^(makestep|rtcsync|driftfile|leapsectz)" /etc/chrony/chrony.conf
12:driftfile /var/lib/chrony/chrony.drift
18:makestep 1.0 3
22:rtcsync
26:leapsectz right/UTC
Ce que cela signifie : makestep 1.0 3 autorise le stepping si l’offset > 1 seconde, mais seulement pendant les 3 premières mises à jour. rtcsync copiera périodiquement l’heure système vers le RTC.
Décision : Si vous démarrez fortement décalé, augmentez temporairement la fenêtre de step (le compte) ou corrigez le RTC pour ne pas avoir besoin de telles mesures. Garder rtcsync est généralement correct sur du matériel physique.
Task 13: Validate driftfile updates (is chrony learning the oscillator?)
cr0x@server:~$ sudo ls -l /var/lib/chrony/chrony.drift
-rw-r--r-- 1 _chrony _chrony 18 Dec 31 10:14 /var/lib/chrony/chrony.drift
cr0x@server:~$ sudo cat /var/lib/chrony/chrony.drift
24.731 0.931
Ce que cela signifie : Chrony a mesuré un offset de fréquence (~24.7 ppm) et une erreur estimée. Si cela ne se met jamais à jour, quelque chose cloche (permissions, FS en lecture seule, contraintes de conteneur).
Décision : Corrigez la persistance ; sans apprentissage de la dérive, vous réapprendrez à chaque boot et mettrez plus de temps à converger.
Task 14: Confirm nothing else is force-setting time (VM tools, scripts)
cr0x@server:~$ ps aux | egrep -i "(ntpd|timesyncd|openntpd|ptp4l|phc2sys)" | grep -v egrep
root 640 0.0 0.1 81200 3520 ? Ssl 09:50 0:00 /usr/sbin/chronyd -F 1
Ce que cela signifie : Seul chronyd apparaît dans la liste évidente.
Décision : Si vous trouvez plusieurs démons de temps, choisissez-en un et désactivez les autres. Si vous êtes sur une VM, vérifiez les agents guest séparément (voir la section virtualisation).
Ajustements chrony qui changent la donne
Les valeurs par défaut de chrony sont raisonnables, mais « raisonnable » suppose que votre RTC n’est pas catastrophique et que votre plateforme ne saute pas le temps au hasard. Quand la dérive persiste, vous ajustez pour deux objectifs :
- Démarrer avec l’heure correcte rapidement afin que les services dépendants ne démarrent pas à une mauvaise date.
- Rester stable même lorsque les sources sont bruyantes ou que la connectivité est intermittente.
1) Autoriser le stepping tôt, mais pas pour toujours : makestep
Le stepping est un saut soudain. Le slewing est un ajustement de vitesse graduel. Le stepping est ce que vous voulez au démarrage quand vous avez plusieurs minutes de décalage ; le slewing est ce que vous voulez en fonctionnement normal quand l’écart est de l’ordre de millisecondes.
Un réglage typique pour un serveur :
cr0x@server:~$ sudo grep -n "^makestep" /etc/chrony/chrony.conf
18:makestep 1.0 3
Conseil : Si votre RTC est parfois erroné de dizaines de secondes, mettez quelque chose comme makestep 1.0 10 temporairement pendant que vous corrigez la discipline du RTC. Ne laissez pas des politiques « step quand nécessaire » permanentes sur des bases de données sensibles à la latence, sauf si vous aimez déboguer des horodatages transactionnels bizarres.
2) Rendre persistant l’apprentissage de l’oscillateur : driftfile doit être inscriptible
Chrony peut compenser une horloge constamment rapide/lente s’il peut apprendre et stocker l’offset de fréquence. Cet apprentissage vit dans le driftfile.
Si vous utilisez des images immuables ou un rootfs en lecture seule, assurez-vous que /var/lib/chrony est persistant. Sinon, vous aurez de longues fenêtres de convergence après chaque redémarrage.
3) Synchroniser le RTC depuis l’heure système (serveurs physiques) : rtcsync
rtcsync active la copie périodique de l’heure système vers le RTC. Cela ne rend pas votre RTC une source de précision. Cela rend le prochain démarrage moins embarrassant.
Sur du bare metal, je recommande généralement rtcsync. Sur certaines VM, le « RTC » est une abstraction et le synchroniser peut être inutile ou contre-productif si l’hyperviseur le gère aussi.
4) Contrôler la fréquence des mises à jour et la sensibilité réseau
Si vos sources NTP sont sur un WAN instable, chrony s’en sortira, mais vos offsets seront plus bruyants. Vous pouvez améliorer la stabilité en choisissant des serveurs plus proches, ou en réduisant la dépendance à une seule source.
Quand quelqu’un propose « simplement sonder plus souvent », souvenez-vous : sonder plus fréquemment peut augmenter la sensibilité au bruit et la charge. Cela peut aussi déranger les serveurs NTP en amont si vous êtes un sondage enthousiaste.
5) Utiliser de bonnes sources, pas « n’importe quoi qui se résout »
Pour les réseaux d’entreprise, pointez chrony vers :
- vos serveurs stratum-1/2 internes (s’ils sont bien gérés),
- ou un service NTP fournisseur bien géré,
- ou des appliances réseau locales avec GPS/PTP en support (selon le cas).
Et configurez toujours plusieurs sources. Une source unique est un point unique d’auto-tromperie.
Horloge matérielle (RTC) et hwclock : rendez-la ennuyeuse
La plupart des cas « la dérive persiste » ne sont pas réellement des pannes NTP. Ce sont des échecs du cycle de vie du RTC : la machine démarre avec une mauvaise heure, puis NTP la corrige, puis quelqu’un redémarre et reproche NTP. Vous ne chassez pas une dérive ; vous chassez une boucle de réinitialisation vers un état mauvais.
Le RTC devrait être en UTC, presque toujours
Sur les serveurs Linux, conservez le RTC en UTC. Le système d’exploitation peut appliquer les fuseaux horaires ; le RTC ne devrait pas. Les règles de fuseau évoluent. UTC non. Ce n’est pas idéologie ; c’est de la limitation des dégâts.
Écrire l’heure système dans le RTC après synchronisation (quand approprié)
Si chrony fournit une bonne heure, mettez à jour le RTC :
cr0x@server:~$ sudo hwclock --systohc --utc
Ce que cela signifie : Le RTC est défini depuis l’heure système actuelle, stockée en UTC.
Décision : Faites cela sur du bare metal une fois que vous avez confirmé que chrony est stable. Si votre RTC dérive rapidement, attendez-vous à répéter et à enquêter sur le matériel.
Lire le RTC dans l’heure système (principalement pour les scénarios de récupération)
cr0x@server:~$ sudo hwclock --hctosys --utc
Ce que cela signifie : Vous réglez l’heure système depuis le RTC. C’est typiquement utilisé très tôt au démarrage par le système d’exploitation de toute façon.
Décision : N’utilisez pas cela pour « corriger » un système en marche déjà discipliné par NTP sauf si vous forcez volontairement une intervention pour la réponse à incident.
Quand la dérive du RTC est vraiment matérielle
Sur des serveurs physiques, une dérive persistante du RTC peut être due à :
- Une pile/accu du RTC défaillante (classique, ennuyeux, réel).
- Bugs de firmware autour des mises à jour du RTC.
- Oscillations environnementales de température en déploiements en périphérie.
- Un périphérique RTC simplement mauvais.
Pour un serveur de datacenter, un RTC qui dérive rapidement est souvent une situation de « remplacer la pièce », pas de « tuner chrony davantage ».
Clocksource noyau, TSC et pourquoi « stable » est conditionnel
Si votre horloge système saute, chrony semblera coupable parce que c’est le gestionnaire de temps visible. Mais le clocksource noyau est le moteur sous le capot. Si celui-ci est instable, vous pouvez observer :
- offsets chrony en dents de scie ou ne convergeant jamais,
- journaux noyau au sujet des watchdog du clocksource,
- applications signalant « l’horloge a reculé »,
- guests VM dérivant en corrélation avec la charge hôte ou les migrations.
Vérifier les clocksources disponibles
cr0x@server:~$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource
tsc hpet acpi_pm
Ce que cela signifie : Plusieurs clocksources existent ; le noyau en choisit une. Le TSC est généralement le plus rapide et le meilleur lorsqu’il est invariant/stable.
Décision : Si le noyau signale que le TSC est instable, envisagez d’épinglez à une autre source comme mitigation pendant que vous corrigez le firmware/les paramètres VM.
Épingler un clocksource (mitigation, pas un style de vie)
Comme test, vous pouvez définir un paramètre noyau au démarrage (via GRUB) comme clocksource=hpet ou similaire. C’est spécifique à l’environnement et doit être testé. L’objectif n’est pas « HPET pour toujours ». L’objectif est « arrêter les sauts temporels pendant qu’on corrige la plateforme ».
Blague #2 : Le TSC est comme la feuille de temps d’un stagiaire — précis si supervisé, créatif si laissé seul.
Pièges de la virtualisation : quand l’hôte manipule le temps du guest
Sur les VM, « l’horloge matérielle » est ce que l’hyperviseur émule. Cela peut être stable, ou « assez proche » jusqu’à une migration à chaud, une surcharge hôte, ou une suspension/reprise.
Mode d’échec classique VM : deux maîtres
Vous exécutez chrony dans le guest, tandis que l’hyperviseur (ou l’agent guest) force périodiquement l’heure du guest. Cela crée un conflit :
- chrony slew lentement, essayant de rester stable,
- l’hyperviseur effectue des steps abrupts, « pour aider »,
- les applications voient des sauts d’heure vers l’avant/l’arrière,
- chrony journalise des événements de stepping et se fait blâmer.
Détecter les agents guest courants
Par exemple, sur certaines plateformes vous pourriez voir qemu-guest-agent ou similaire :
cr0x@server:~$ systemctl status qemu-guest-agent --no-pager
● qemu-guest-agent.service - QEMU Guest Agent
Loaded: loaded (/lib/systemd/system/qemu-guest-agent.service; enabled; preset: enabled)
Active: active (running) since Tue 2025-12-31 09:49:58 UTC; 25min ago
Main PID: 510 (qemu-ga)
Tasks: 1
Memory: 2.8M
CPU: 52ms
CGroup: /system.slice/qemu-guest-agent.service
└─510 /usr/sbin/qemu-ga
Ce que cela signifie : L’agent guest tourne. Cela ne garantit pas qu’il fixe l’heure, mais c’est un suspect.
Décision : Vérifiez la politique de l’hyperviseur : laissez soit le guest gérer le temps via chrony, soit faites gérer le temps par l’hôte et désactivez la synchronisation guest. Le contrôle mixte est l’endroit où la santé mentale disparaît.
Migration à chaud et rapports de « dérive soudaine »
Si la dérive apparaît après des migrations, vérifiez :
- les réglages de stabilité TSC de l’hôte,
- le modèle CPU de la VM et l’exposition d’un TSC invariant,
- la santé NTP de l’hôte (si l’hôte est faux, les guests héritent des bizarreries).
Dans des flottes VM d’entreprise, corrigez le temps au niveau hôte d’abord. Les guests sont des consommateurs en aval.
Trois mini-histoires du monde corporate (anonymisées)
Incident causé par une mauvaise hypothèse : « Synchronisé » signifie correct après reboot
Une entreprise de taille moyenne exploitait une couche de journalisation basée sur Debian sur bare metal. La surveillance vérifiait chronyc tracking toutes les heures et alertait si l’offset de l’heure système dépassait un seuil. Cela n’arrivait jamais. Tout le monde était rassuré.
Puis est arrivé une fenêtre de maintenance. Ils ont redémarré la moitié de la flotte pour appliquer des mises à jour du noyau. Immédiatement, le retard d’ingestion a grimpé et une partie des logs est arrivée hors d’ordre. L’astreinant a vu « System clock synchronized: yes » et a supposé que le problème venait d’ailleurs.
Le problème réel était banal : dérive du RTC. Avant le redémarrage, chrony avait discipliné l’heure système, donc la surveillance avait l’air parfaite. Après le redémarrage, les services ont démarré avec une mauvaise heure, ont écrit un lot d’enregistrements mal horodatés, et seulement ensuite chrony a effectué le step pour remettre l’heure. Les « dommages » étaient déjà commis.
La correction n’était pas exotique. Ils ont activé rtcsync, vérifié que le RTC était en UTC, et ajouté une garde au démarrage : les services requis pour une heure correcte ne démarraient qu’après que chrony ait indiqué la synchronisation. Ils ont aussi modifié leur monitoring pour comparer explicitement RTC vs horloge système une fois par jour. La leçon a été retenue parce qu’elle était embarrassante de la manière la plus simple.
Optimisation qui a mal tourné : éviter agressivement le stepping sur des nœuds sensibles à la latence
Une autre organisation avait une règle stricte : « Ne jamais stepper le temps ; uniquement slewing. » La rationale semblait professionnelle : le stepping peut perturber les bases de données et l’ordre. Ils ont configuré chrony pour ne jamais stepper après le démarrage et mis un seuil très bas au début.
Ça a bien marché jusqu’à ce qu’ils déplacent une partie de la flotte dans un segment réseau bruyant. Les paquets NTP arrivaient avec des délais variables, et les offsets montaient parfois au-dessus d’une seconde durant des coupures brèves. Chrony a fait ce qu’on lui demandait—seulement le slewing—mais le slewing à la vitesse maximale du noyau prenait beaucoup de temps pour corriger des offsets de plusieurs secondes.
Les applications n’ont pas planté. Elles ont fait quelque chose de plus subtil : des tokens d’auth ont expiré « trop tôt », les tâches planifiées ont dérivé, et la coordination inter-nœuds a été incohérente. Comme le temps ne stepait pas, les incidents étaient plus difficiles à remarquer. Cela ressemblait à des flakinesss aléatoires entre systèmes sans rapport.
Ils ont finalement adopté une politique plus réaliste : autoriser le stepping uniquement pendant les N premières mises à jour après le démarrage (makestep), et corriger le jitter réseau sous-jacent. La règle « ne jamais stepper » est devenue « stepper seulement quand l’alternative est des heures d’erreur ». C’est moins pur, plus efficace.
Pratique ennuyeuse mais correcte qui a sauvé la mise : verrouiller le démarrage sur la syncro temporelle
Une plateforme de paiements (régulée, auditée et allergique aux surprises) avait une règle opérationnelle peu sexy : les systèmes qui signent des tokens ou négocient Kerberos ne démarrent pas tant que la synchronisation temporelle n’est pas confirmée. Pas d’exceptions, pas de « ça ira probablement ».
Ils l’ont implémenté avec l’ordonnancement systemd : chrony démarre tôt ; l’unité applicative a un ExecStartPre qui boucle sur chronyc tracking jusqu’à ce que le leap status soit normal et que le système soit synchronisé. Ils ont aussi ajouté une unité « sanity time » qui refuse de démarrer si l’horloge est complètement hors plage.
Cela les a sauvés lors d’un incident réseau data center où la reachabilité NTP était temporairement rompue au démarrage pour un sous-ensemble d’hôtes. Sans verrouillage, ces machines seraient sorties avec une heure RTC obsolète et auraient commencé à émettre des tokens avec des timestamps invalides. Avec le verrouillage, elles ont simplement attendu. Le démarrage était plus lent ; la cohérence est restée intacte.
C’était ennuyeux. C’était correct. Ça a évité un incident qui aurait été imputé à « le réseau », « Linux » ou « Mercure rétrograde », selon qui écrivait le postmortem.
Erreurs fréquentes : symptômes → cause racine → correction
1) « timedatectl indique synchronized, mais l’heure reste fausse après reboot »
Symptôme : Immédiatement après le démarrage, l’heure est décalée de minutes ; plus tard, tout semble correct.
Cause racine : Le RTC est faux et le démarrage initialise l’heure système depuis le RTC. NTP corrige ensuite.
Correction : Assurez-vous que le RTC est en UTC (/etc/adjtime), activez rtcsync dans chrony, exécutez hwclock --systohc --utc après synchronisation, vérifiez la batterie/firmware du RTC.
2) « chrony montre des sources joignables, mais les offsets ne convergent jamais »
Symptôme : chronyc sources montre de la reach, mais le RMS offset dans tracking reste élevé ; la fréquence oscille.
Cause racine : Chemin réseau bruyant, routage asymétrique, ou serveurs amont mauvais ; parfois un firewall/NAT local qui manipule UDP.
Correction : Utilisez des sources plus proches/meilleures, confirmez le chemin UDP/123, évitez un polling trop agressif, envisagez des serveurs stratum internes.
3) « L’horloge saute en arrière/en avant parfois ; les apps loguent ‘time went backwards’ »
Symptôme : Journaux noyau ou applicatifs mentionnent des sauts en arrière ; chrony journalise des steps hors fenêtres prévues.
Cause racine : Instabilité du clocksource noyau, hyperviseur forçant le temps, ou plusieurs démons de temps en conflit.
Correction : Vérifiez dmesg pour des messages de watchdog clocksource, assurez-vous d’un seul mécanisme de synchronisation, ajustez les paramètres VM, mitigez en sélectionnant un clocksource stable.
4) « Tout va bien jusqu’à la migration de la VM »
Symptôme : Pics d’offset corrélés aux migrations ou à la maintenance hôte.
Cause racine : L’hôte a une heure erronée ou expose un TSC instable ; le guest voit des discontinuités.
Correction : Corrigez NTP/PTP de l’hôte d’abord, assurez une exposition CPU/TSC cohérente, évitez les conflits d’agents guest.
5) « Chrony effectue de gros steps à chaque démarrage »
Symptôme : Le journal de chrony montre un grand step à chaque boot.
Cause racine : RTC non mis à jour, driftfile non persistant, ou le système démarre longtemps sans réseau et les services s’appuient sur une mauvaise valeur seed.
Correction : Activez rtcsync, assurez la persistance du driftfile, verrouillez le démarrage des services critiques jusqu’à la synchronisation.
6) « Le temps dérive lentement même si chrony tourne »
Symptôme : Sur des heures, l’offset croît et chrony n’arrive pas à le maintenir dans les bornes.
Cause racine : Le noyau refuse de discipliner assez vite à cause de limites de configuration, ou le clocksource est instable, ou les sources NTP sont incohérentes.
Correction : Vérifiez la fréquence et le skew mesurés par chrony ; confirmez les sources ; contrôlez l’instabilité du clocksource ; envisagez PTP si vous avez besoin de bornes plus strictes que ce que NTP peut fournir dans votre environnement.
Listes de vérification / plan pas-à-pas
Étapes pas-à-pas : corriger « NTP indique synchronisé mais la dérive persiste » sur Debian 13
-
Choisissez un seul démon de temps.
Utilisez chrony sur les serveurs ; désactivez systemd-timesyncd si présent.
cr0x@server:~$ sudo systemctl disable --now systemd-timesyncd Removed "/etc/systemd/system/sysinit.target.wants/systemd-timesyncd.service".Décision : Si désactiver timesyncd casse quelque chose, vous aviez des dépendances cachées. Corrigez-les, ne réactivez pas des duels de démons.
-
Confirmez que chrony a des sources stables.
cr0x@server:~$ chronyc sources -v ...^* ntp1.example.net ...Décision : Si vous ne pouvez atteindre aucune source, réparez le réseau/pare-feu avant de toucher au réglage de chrony.
-
Autorisez le stepping tôt au démarrage.
Dans
/etc/chrony/chrony.conf, assurez-vous d’avoir quelque chose comme :cr0x@server:~$ sudo grep -n "^makestep" /etc/chrony/chrony.conf 18:makestep 1.0 3Décision : Si les offsets sont souvent > 1s au démarrage, augmentez temporairement le nombre pendant que vous corrigez le RTC.
-
Rendez persistant l’apprentissage de la dérive.
cr0x@server:~$ sudo stat /var/lib/chrony/chrony.drift File: /var/lib/chrony/chrony.drift Size: 18 Blocks: 8 IO Block: 4096 regular file Access: (0644/-rw-r--r--) Uid: ( 109/_chrony) Gid: ( 116/_chrony) Access: 2025-12-31 10:14:18.000000000 +0000 Modify: 2025-12-31 10:14:18.000000000 +0000 Change: 2025-12-31 10:14:18.000000000 +0000Décision : Si il ne se met pas à jour, corrigez les permissions ou la persistance (surtout pour les images/containers).
-
Corrigez le RTC : UTC et synchronisé.
cr0x@server:~$ cat /etc/adjtime 0.000000 1767174612 0.000000 0 UTCcr0x@server:~$ sudo hwclock --systohc --utcDécision : Si le RTC continue de dériver rapidement sur du bare metal, traitez-le comme un problème matériel/firmware, pas comme un exercice de tuning NTP.
-
Traquez les sauts temporels : clocksource et conflits VM.
cr0x@server:~$ journalctl -k --since "today" | grep -i clocksource --no-pager | tail Dec 31 10:02:44 server kernel: clocksource: Switched to clocksource hpetDécision : Si vous voyez de l’instabilité, corrigez les paramètres plateforme (BIOS/hôte) et envisagez d’épinglez un clocksource comme mitigation.
-
Verrouillez le démarrage des services critiques sur la synchronisation temporelle.
Pour les systèmes qui signent des tokens, font de l’auth ou coordonnent des transactions distribuées, ne les démarrez pas avant que la syncro soit atteinte. C’est ennuyeux et correct.
Checklist opérationnelle pour la sécurité continue
- Surveillez quotidiennement le delta RTC vs horloge système sur du bare metal.
- Alertes sur les événements de stepping chrony en dehors de la fenêtre de démarrage prévue.
- Gardez au moins trois sources NTP, idéalement dans des domaines de panne différents.
- Enregistrez si un nœud est VM ou bare metal ; les modes de panne temporelle diffèrent.
- Pendant les migrations VM, corrélez avec les pics d’offset pour prouver la causalité.
FAQ
1) Si System clock synchronized: yes, comment le temps peut-il encore être « faux » ?
Parce que « synchronisé » est un état à un instant donné et se réfère souvent seulement à l’horloge système. Votre RTC peut toujours être erroné (problème au redémarrage), ou vous pouvez avoir des sauts intermittents dus au clocksource/hyperviseur.
2) Dois-je utiliser systemd-timesyncd ou chrony sur Debian 13 ?
Pour les serveurs : chrony. Il est plus diagnostiquable et configurable. Pour des postes minimalistes ou petits appliances : timesyncd peut suffire. Ne faites pas tourner les deux.
3) Quelle est la différence opérationnelle entre stepping et slewing ?
Le stepping modifie instantanément l’heure murale. Le slewing modifie la vitesse pour que l’horloge converge graduellement. Stepez au démarrage si vous êtes fortement décalé. Slew en fonctionnement normal pour éviter de perturber les applications.
4) Est-il sûr d’activer rtcsync ?
Sur des serveurs bare metal, oui, généralement. Cela réduit les surprises au redémarrage. Sur certaines VM, cela peut être sans effet, et l’hyperviseur peut gérer la sémantique du RTC de toute façon.
5) Mon RTC est réglé en heure locale. Est-ce vraiment un problème ?
Pour les serveurs, oui. Les changements DST et les mises à jour des règles de fuseau provoquent des problèmes. Utilisez UTC sauf si vous avez une exigence spécifique de dual-boot.
6) Pourquoi mon horloge dérive davantage sous charge ?
La charge lourde peut révéler des problèmes de clocksource, des délais d’ordonnancement VM et du jitter réseau. Chrony peut gérer beaucoup, mais si le clocksource sous-jacent est instable ou si les paquets NTP sont retardés de façon imprévisible, les offsets deviennent bruyants.
7) Puis-je corriger une dérive persistante en sondant NTP plus fréquemment ?
Parfois cela aide un peu ; souvent cela amplifie juste le bruit. De meilleures sources et un clocksource stable valent mieux qu’un sondage agressif. Si vous avez besoin de bornes plus strictes, envisagez PTP dans un environnement qui le supporte.
8) Pourquoi je vois de grands steps au démarrage même avec chrony configuré ?
Parce que la seed initiale du temps (RTC) est très éloignée ou que le driftfile n’est pas persistant. Chrony ne peut corriger qu’après démarrage et connexion aux sources ; tout ce qui démarre avant peut voir une mauvaise heure.
9) Comment savoir si un hyperviseur écrase le temps ?
Cherchez des sauts temporels corrélés aux migrations ou événements hôte, et vérifiez la présence d’agents guest ou de paramètres de plateforme qui « sync time ». En pratique, décidez : temps géré par l’hôte ou le guest, pas les deux.
10) Quelle précision attendre de NTP sur un LAN typique ?
Souvent des millisecondes, parfois mieux. Sur WAN ou réseaux bruyants, des dizaines de millisecondes voire plus. Si vous exigez une coordination sub-millisecondes ou microsecondes, vous entrez dans le domaine PTP et avez besoin d’un support matériel.
Prochaines actions à entreprendre réellement
- Mesurez les bonnes choses : suivez l’offset système (
chronyc tracking) et le delta RTC (hwclock --showvsdate -u) séparément. - Éliminez les conflits : assurez-vous qu’un seul mécanisme de synchronisation temporelle contrôle chaque nœud (et définissez si l’hôte ou le guest possède le temps dans les environnements VM).
- Sécurisez le démarrage : configurez
makesteppour correction précoce et verrouillez le démarrage des services sensibles jusqu’à ce que la syncro soit réelle. - Rendez le RTC ennuyeux : gardez-le en UTC, activez
rtcsyncsur bare metal et remplacez les batteries RTC défaillantes sans drame. - Enquêtez immédiatement sur les avertissements de clocksource : si le noyau marque un clocksource comme instable, traitez cela comme une erreur matérielle à horodater.
Si vous faites ces cinq choses, « NTP indique synchronisé mais la dérive persiste » cesse d’être une histoire de fantômes et devient une simple tâche de checklist. La production aime l’ennui. La conservation du temps devrait être activement ennuyeuse.