時刻同期のアプローチ:Chrony vs. NTPd vs. systemd-timesyncd
クロックのズレ(クロックドリフト)を放置すると、分散インフラ全体に深刻な障害をもたらします。わずか200ミリ秒のズレであっても、etcdクラスターにおけるRaftコンセンサスを崩壊させ、有効期間の短いJSON Web Token(JWT)を失効させ、Jaegerによる分散トレーシングを狂わせる可能性があります。Linuxでタイムデーモンを選択する場合、一般的に次の3つの選択肢があります。
- systemd-timesyncd:systemdに直接組み込まれた最小限のSNTPクライアント。リモートソースから時刻を取得してローカルクロックを定期的に調整する機能のみを持ち、ローカルのタイムサーバーとして動作することはできません。
- レガシーNTPd:初期のUNIXシステムを支えてきた歴史あるリファレンスデーモン。実稼働での実績が豊富で高機能ですが、システム起動後に同期が安定するまで数時間かかることがあります。また、混雑したクラウドアドレスなどでネットワークレイテンシが急上昇した場合の追従性にも課題があります。
- Chrony (chronyd):仮想マシン、クラウドインスタンス、エッジデバイス向けに構築された最新の高性能NTPエンジン。VMスナップショットによる一時停止、ネットワークインターフェースの切断、クロック周波数の変動などにも迅速に適応します。
各ツールの比較:実運用におけるトレードオフ
それぞれのツールは異なる運用プロファイルを想定して設計されています。本番環境における各ツールの比較は以下のとおりです。
1. systemd-timesyncd
メリット:モダンなディストリビューションであれば追加パッケージのインストールが不要。メモリフットプリントが非常に小さく(RSS約3MB)、シンプルなスタンドアロン構成であればメンテナンスフリー。
デメリット:内部VPCサブネットへの時刻配信が不可。ハードウェアタイムスタンプ非対応。Network Time Security(NTS)の鍵交換に非対応。大きなオフセットが生じた初期状態からの復旧が遅い。
2. NTPd (Network Time Protocol Daemon)
メリット:数十年にわたる実環境での運用実績。電波受信機や原子時計などの特殊なハードウェアリファレンスクロックに対する幅広いドライバーサポート。
デメリット:収束が極めて遅く、クロックオフセットを10ミリ秒未満に抑えるまでに30〜60分を要することが多い。ジッターの大きいWAN接続で不安定になりやすい。煩雑なAutokey設定を行わない限り、平文パケットのなりすまし攻撃に脆弱だった歴史がある。
3. Chrony
メリット:起動から数秒でサブミリ秒の精度にシステム時刻を同期。クロック周波数のドリフトを高精度に制御。クライアントとしてもエンタープライズグレードのサーバーとしてもシームレスに動作。TLSベースのNetwork Time Security(NTS)をネイティブサポート。
デメリット:ディストリビューション標準のデーモンと置き換える必要があるため、ntpqの出力を取得している既存のシェルスクリプトはchronycを使用するように更新が必要。
本番環境で検証済みの推奨アーキテクチャ
高可用性が求められる環境では、数百台のインスタンスが外部のパブリックプールサーバーに個別にポーリングする構成は避けるべきです。代わりに、次のような2層の同期モデルを構築します。
- VPCエッジタイムリレー:クラウドリージョンごとに少なくとも2台の内部Chronyリレーノードをデプロイします。これらはTLS認証された安全なチャネルを介して、パブリックなNTS対応Stratum-1およびStratum-2サーバーから時刻を取得するように設定します。
- 内部ワークロードノード:データベースサーバー、Kubernetesノード、マイクロサービスホストをChronyクライアントとして設定し、プライベートサブネット経由で内部リレーを参照させます。ディザスタリカバリ用にフォールバックプールも含めておきます。
- 厳格なドリフトポリシー:
makestepはマシンの初回起動時のみ許可するように設定します。稼働中は緩やかなクロック調整(スルーイング)を強制してください。通常運用中に時刻が逆戻り(ステップ調整)すると、PostgreSQL、Cassandra、Prometheusなどの書き込み順序が破損する危険があります。
ステップバイステップ導入ガイド
ステップ 1: Chronyのインストールと競合デーモンの無効化
まず、UDPポート123の競合を防ぐため、デフォルトのデーモンを停止および無効化します。
# Ubuntu/Debianの場合
sudo apt update && sudo apt install -y chrony
sudo systemctl stop systemd-timesyncd 2>/dev/null || true
sudo systemctl disable systemd-timesyncd 2>/dev/null || true
# RHEL/Rocky/AlmaLinuxの場合
sudo dnf install -y chrony
ステップ 2: NTS対応クライアントとしてのChrony設定
Network Time Security(NTS)はNTPとTLSを組み合わせたプロトコルです。暗号化によって上流のタイムソースを検証し、中間者攻撃(MitM)を完全に遮断します。設定ファイル /etc/chrony/chrony.conf(RHEL系の場合は /etc/chrony.conf)を編集します。
# 地理的に近く、信頼できる複数のNTS対応Stratum-1/2サーバーを指定
server time.cloudflare.com iburst nts
server nts.netnod.se iburst nts
server ptbtime1.ptb.de iburst nts
# オフセットが1秒を超える場合、最初の3回までの更新に限りステップ調整を許可
# それ以降は緩やかな調整(スルーイング)を強制
makestep 1.0 3
# 再起動をまたいで水晶振動子の周波数ドリフトを記録
driftfile /var/lib/chrony/drift
# 11分ごとにカーネルRTC(リアルタイムクロック)を同期
rtcsync
# クロック調整ログの出力先
logdir /var/log/chrony
変更を反映し、OS起動時にサービスが自動開始されるよう設定します。
sudo systemctl restart chrony
sudo systemctl enable chrony
ステップ 3: 内部ネットワークへの時刻配信(サーバー化)
ゲートウェイや踏み台ホストをVPC向けのローカルNTPサーバーとして構成します。設定ファイルを開き、サブネットへのアクセス許可とローカルフォールバックStratumを追加します。
# プライベートVPCサブネットからの同期リクエストを許可
allow 10.0.0.0/16
# 上流のインターネット接続が一時的に切断された場合でもローカル時刻を配信
local stratum 10
# 内部インターフェース(例: eth1のIP)にのみバインド
bindaddress 10.0.1.5
アクティブなセッションを中断することなくサーバー設定を反映します。
sudo systemctl reload chrony
ステップ 4: NTS暗号化の検証とドリフト監視
Ubuntu 22.04 LTSを実行するAWS c6i.largeインスタンスで10,000 req/secの負荷をかけたテスト検証では、ChronyはUTCからのクロックオフセットを18マイクロ秒以内に維持しました。メモリ使用量はRSS 6MB未満で安定し、CPU使用率は0.1%以下にとどまりました。
上流との同期状態とピアの健全性を確認します。
chronyc sources -v
最適なソースの横にアスタリスク(*)が表示されていれば、Chronyがそれをプライマリリファレンスとしてロックしていることを意味します。次に、NTS認証の状態を確認します。
chronyc authdata
クッキー数がゼロ以外で、鍵交換が検証されていることが確認できれば、暗号化認証は正常に機能しています。
本番環境におけるドリフトとネットワーク障害のトラブルシューティング
1. ソースに到達できない(Reference ID 00000000 / Stratum 0)
chronyc tracking を実行して主要メトリクスを確認します。
chronyc tracking
# 上流リンクが切断されている場合の出力例:
# Reference ID : 00000000 ()
# Stratum : 0
# Leap status : Not synchronised
Reference IDが空白の場合、通常はネットワークファイアウォールによってトラフィックがブロックされています。NTSには2つのポート開放が必要です。初回TLS鍵交換ハンドシェイク用のTCPポート4460と、時刻パケット用のUDPポート123です。nc を使用して接続性をテストします。
# NTS鍵交換ポートのテスト (TCP 4460)
nc -zvw3 time.cloudflare.com 4460
# NTPパケットポートのテスト (UDP 123)
nc -zuvw3 time.cloudflare.com 123
2. 深刻なVM一時停止からの復旧
ハイパーバイザーのメンテナンスやライブマイグレーションにより、ゲストVMが数秒から数分間フリーズすることがあります。VMが再開されると、Chronyは実行中のアプリケーションへの悪影響を避けるため、デフォルトではクロックを徐々にスルー調整します。ワークロードですぐに時刻を同期させる必要がある場合は、手動でステップ調整を強制します。
sudo chronyc makestep
これにより緩やかな調整をスキップし、システム時刻が即座に同期されます。
3. ジッターの監査と不安定なピアの除外
各ピアのネットワークジッターとクロック安定性の推移を監視します。
chronyc sourcestats -v
Std Dev(推定標準偏差)と Est offset の列に注目してください。標準偏差が10ミリ秒を超えるサーバーやパケットロス率が高い上流サーバーは、設定から除外し、ジッターの少ない代替サーバーに切り替える必要があります。

