🕰️

systemdの時間同期に関するUnit

2021/12/05に公開

この記事は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場合によっては期待通りに動かない場合があります。詳細については以下を参照ください。

よってntpd, chronyなどで時間の同期を確実に待つ必要がある場合は専用のプログラムを書いて利用したほうが無難と言えます。
また、 time-sync.target の意味が systemd-time-wait-sync.service がenabled/disabledかで変わるようになってしまったため、これとは別に時間同期プログラムが起動したらreachする time-set.target と言うtargetが提案・実装されsystemd v242から利用可能です。

Discussion