systemdの時間同期に関するUnit
この記事はUMITRON Advent Calendar 2021 5日目の記事です。
まえがき
弊社ではプロダクトの一部にRaspberry Piを利用しています。またシステムの要件として時刻が重要となるのですが、Raspberry PiにはRTCモジュールが付属しておらず一度シャットダウンしたのち起動し直すとシステムの時刻が最後にシャットダウンした時刻から始まります。アプリケーションを正しい時刻のシステム上で動かすには、Raspberry Piがインターネットに繋がりNTPによる時間の同期を待つ必要があります。
昔はこの時間の同期を待つのに自前でプログラムを書く必要がありましたが、最近はsystemdパッケージに時間同期を待つtargetがバンドルされています。この記事ではこのsystemdによる時間同期に関する情報をまとめます。
本編
time-sync.target
と言うtargetがあります。これは名前を見ると時間の同期を待つtargetに見えますが、デフォルトでは待ってくれません。デフォルトではこれは時間同期を担当するsystemd-timesyncd, ntpd, chrony などのプログラムが起動したらreachするtargetとなっており、時間の同期は待ってくれません。
この問題を解決するために systemd-time-wait-sync.service
というserviceがsystemd v239から導入されました。このserviceをenableすると time-sync.target
が時間の同期を待つようになります。
systemd-time-wait-sync.service
は基本的に systemd-timesyncd が時間同期を完了し、 systemd-timesyncd がnotifyすることで同期を検知します。よって、時間同期にはsystemd-timesyncdを利用することが推奨されます。このsystemd-timesyncdがnotifyする以外にもLinux kernelが司る時間同期フラグによる時間同期検知も試行しますが、こちらは信頼性のあるものではなくntpdやchrony場合によっては期待通りに動かない場合があります。詳細については以下を参照ください。
- https://manpages.debian.org/bullseye/systemd/systemd-time-wait-sync.service.8.en.html
- https://github.com/systemd/systemd/issues/14061
- https://github.com/systemd/systemd/blob/9654645b62226263b923e79a0511fa8a4368d5dc/src/time-wait-sync/time-wait-sync.c#L117-L139
よってntpd, chronyなどで時間の同期を確実に待つ必要がある場合は専用のプログラムを書いて利用したほうが無難と言えます。
また、 time-sync.target
の意味が systemd-time-wait-sync.service
がenabled/disabledかで変わるようになってしまったため、これとは別に時間同期プログラムが起動したらreachする time-set.target
と言うtargetが提案・実装されsystemd v242から利用可能です。
Discussion