Skip to main content
Skip to content

到達不能な NTP サーバーによるクロック ドリフト

お使いの GitHub Enterprise Server インスタンスが設定されているタイム サーバーに到達できない場合、そのクロックはリアルタイムから離れてドリフトします。 サインイン、連携、およびGitHub Actionsは、クロックに言及しない理由で失敗する可能性があります。

Symptoms

実際に表示される内容では、時計が言及されることはほとんどありません。 代わりに症状は、時間について2つのシステムの合意に依存するものに影響が及びます。

  • ユーザーはサインインできないか、セッションが予想よりも早く終了します。
  • GitHub Connect 接続に失敗するか、ライセンス ページでサーバー エラーが返されます。
  • GitHub Actions ジョブが開始に失敗するか、トークンが無効として拒否されます。
  • /var/log/github/exceptions.log には、'Expiration time' claim ('exp') is too far in the future など、トークンの有効期限クレームが未来の遠すぎる時点に設定されていることに関するエラーが含まれています。
  • Web インターフェイス、ログ、またはコミット内のタイムスタンプが、予想した時刻と一致しません。

クロックが間違っているインスタンスによって署名されたトークンは、トークン自体に何も問題がなくても、それを受信するシステムには無効に見えます。 そのため、これらの失敗は、時刻ではなく認証を示しています。

原因

GitHub Enterprise Server は、UDP ポート 123 経由でネットワーク タイム プロトコル (NTP) サーバーと同期することで、クロックを正確に保ちます。 少なくともそのうちの 1 つに継続して接続できる必要があります。

一般的な理由により、構成されたサーバーに到達できなくなります。

  • ファイアウォールまたはセキュリティ グループは送信 UDP ポート 123 をブロックします。これは、残りのインスタンスが機能するため見逃しやすいです。
  • 内部タイム サーバーは使用停止または名前変更され、インスタンスは引き続き古いアドレスを指しています。
  • ホスト名は解決されなくなりました。
  • 構成されているサーバーは 1 つだけなので、サーバーが消えたときにフォールバックするものはありません。

構成されたサーバーに到達できない場合、chrony は外部修正なしでローカル システム クロックを実行し続け、GitHub Enterprise Server が設定するフォールバック stratum 10 を報告します。 これはハードウェア クロックではなく、chrony とは別に管理される別個のデバイスです。

その時点では何も失敗せず、エラーは発生しません。 クロックは修正されなくなり、最初はゆっくりとドリフトして、正確な時刻に依存するものが壊れるまで進みます。 ドリフトが大きいほど、障害の範囲が広がります。

また、仮想マシンのクロックを設定しようとするハイパーバイザーは、インスタンス独自の同期と戦うことで、同じ結果を生成できます。

問題の確認

  1. 管理シェルに SSH 接続します。 詳細については、「管理シェル (SSH) にアクセスする」を参照してください。

  2. タイム ソースとその状態を一覧表示します。

    sudo chronyc sources -v
    

    各ソースの左側にある MS 列を読んでください。 ?は、chrony がそのソースを使用していないことを意味します。 それだけでは、同じマーカーがそれ自体が同期されていないサーバーと、まだ十分な測定値を提供していないソースの両方に表示されるため、ネットワークの問題の証拠ではありません。

    到達不能なソースは、同じ行の裏付け情報で識別されます。 次の出力では、Reach は 0されています。つまり、最近のポーリングのいずれも応答を受け取らず、LastRx は - です。つまり、サンプルは一度も到着していません。 どちらのサーバーも一度も応答していません。

    MS Name/IP address         Stratum Poll Reach LastRx Last sample
    ===============================================================================
    ^? ntp1.example.com              0  10     0     -     +0ns[   +0ns] +/-    0ns
    ^? ntp2.example.com              0  10     0     -     +0ns[   +0ns] +/-    0ns
    

    ソースが *マークされている場合、chrony はそれを選択し、到達可能性の問題を除外します。 時刻が正確であることを確認するものではありません。chrony は大きなオフセットを徐々に補正するため、その間、インスタンスの時刻は実際の時刻から大きくずれている可能性があります。 いずれにしても残りのチェックを続行します。

  3. インスタンスの実際の同期対象を確認します。

    sudo chronyc tracking
    

10 の階層と共に、角かっこで囲まれた空の名前の参照 ID は、インスタンスが構成済みサーバーを見限り、独自のクロックを使用していることを意味します。

Reference ID    : 7F7F0101 ()
Stratum         : 10
System time     : 0.000000000 seconds fast of NTP time

Stratum は、参照クロックからインスタンスが何段階離れているかを示し、インスタンスは常に、自身が従うサーバーより 1 つ大きい値を報告します。 10の値は特定の値です。これは、ソースが利用できない場合にGitHub Enterprise Serverが構成するフォールバックであるため、名前のない参照 ID と共に表示されるのがシグナルです。

正常なインスタンスは、代わりにフォローしているサーバー名を示し、そのサーバーより1つ上のストラタムを報告します。

Reference ID    : D9723B03 (ntp1.example.com)
Stratum         : 3
System time     : 0.000079420 seconds fast of NTP time

System time は、インスタンスがフォローしているサーバーに対して測定されるため、自身のクロックを参照している場合、その値は意味がありません。 クロックがどれだけずれていても、ゼロに近い値と読み取ります。

  1. インスタンス クロックを信頼できるソースと比較して、そのずれを自分で測定します。

    date -u
    

    どの程度ずれているかに注意してください。 大きな差がある場合、クロックが補正されないままずれてきたことを示します。

  2. 各ソースの詳細情報 (傾斜の程度や保持されたサンプルの数など) が必要な場合は、次のコマンドを使用します。

    sudo chronyc sourcestats -v
    

問題の解決

最初に同期を復元してから、同期が失われていた間に蓄積された誤差を修正します。 到達可能性を修正せずにドリフトを修正しても、再発までの時間稼ぎにしかなりません。

  1. 管理コンソールの [時間] セクションで、インスタンスがどのサーバーに対して構成されているかを確認します。 詳細については、「時間の同期を構成する」を参照してください。

  2. インスタンスがそれらに接続できることを確認します。 送信 UDP ポート 123 は、インスタンスとサーバーの間のすべてのファイアウォールとセキュリティ グループで、各サーバーに対して開かれている必要があります。 詳細については、「ネットワーク ポート」を参照してください。

  3. サーバーがなくなった場合、またはサーバーへのパスにアクセスできない場合は、インスタンスが到達できるサーバーを構成します。 少なくとも 2 つを構成して、1 つが失われてもインスタンスに何も残らない状態にならないようにします。

  4. chrony がソースを再び選択していることを確認してください。 そのうちの 1 つは、* でマークされ、Reach が 0 以外になっているはずです。

    sudo chronyc sources -v
    
  5. インスタンスが同期されていない間に蓄積したドリフトを修正します。 NTP は単独で小さな不一致を修正しますが、大きな違いには次のコマンドが必要です。 詳細については、「時間の同期を構成する」を参照してください。

    sudo chronyc -a makestep
    
  6. 時計が今、信頼できるソースと一致していることを確認します。 これは、ドリフトがまだ補正されているのではなく、実際になくなったことを示すチェックです。

    date -u
    
  7. 失敗していたものを再試行してください。

再発防止

  • 少なくとも 2 つのタイム サーバーを構成して、1 つを失しても同期が停止しないようにします。
  • サーバーを変更した後、インスタンスが実際にサーバーに到達できることを確認します。 構成されたサーバーは必ずしも動作しているわけではありません。応答を停止しても警告してくれるものはありません。
  • ファイアウォール規則が変更されたときに、送信 UDP ポート 123 をタイム サーバーに対して開いたままにしておきます。
  • ハイパーバイザーが仮想マシンのクロックを設定しないようにして、インスタンス独自の同期と競合しないようにします。 詳細については、仮想化プロバイダーによって提供されるドキュメントを参照してください。
  • 定期的な正常性チェックの一環として、タイム ソースを確認します。 ドリフトは、そうでなくなるまでは無害であり、問題が小さいうちに検知すれば、無関係ないくつかの障害のうち、どれがクロックに起因するのかを切り分ける手間を省けます。

連絡する GitHub のサポート

構成とネットワーク パスを確認した後もインスタンスがタイム サーバーに到達できない場合、またはクロックが正確になっても元の現象が継続する場合は、続行するのではなく、GitHub のサポート に連絡してください。 詳細については、「サポートチケットの作成」を参照してください。

既にチケットを開いている場合は、サポート バンドルをアタッチすると、GitHub のサポート 問題をより迅速に診断するのに役立ちます。 詳細については、「GitHub サポートにデータを提供する」を参照してください。

詳細については、次を参照してください。