午前9時(JST)にうるう秒が挿入されますが、注意すべきポイントのおさらいです。うるう秒って何よNICTの資料の先頭7ページ目まで読んでください。言うと、現在の時計というのは「原子時計」が基準になっています。太陽の周りを回る公転周期に合わせて微調整するのがうるう年で、地球自体が回転する自転時間に合わせて微調整するのがうるう秒です。現象としては、「月末」の日付が変わる直前に1秒追加されます。これはUTC(協定世界時)での話なので、日本標準時では9時間の時差があるので朝9時(の直前)になるわけです。時間の進みを表にするとこんな感じです。4秒おわかり頂けただろうか。前回のうるう秒は2012年7月1日(JST)に挿入されましたが、このときにLinuxカーネルでいくつかの不具合が判明しました。影響が大きかったものが「CPU利用率が100%に張り付く」というもので、以下のブログ記事が詳しいです。カーネルの不具合に関する情報これは「不具合」による想定外の問題でしたが、そもそも「想定内」の範囲でも以下のような問題があります。いう特殊なタイムゾーンを設定した場合にのみ、59分60秒といううるう秒の時刻を取得できます。ままだと、59分59秒を二周します。IBMの技術記事の表記が分かりやすいので引用します。秒以下の時刻を表します。)ログの前後関係の逆転たとえば操作履歴の分析を想像して、手動で全力出しすぎて1秒以内に連続で操作したような場合、59分59秒を2周するような設定だと、操作の前後関係が逆転する可能性があります。400ミリ秒と記録され操作Aより前とみなされてしまうまた、監査ログの紐付けなどでも同様の問題が発生します。誤ったやり方でうるう秒を回避しようとした場合に発生します。Indicator)が無い場合には、時間のずれを検知してから15分間たってから一気に時刻を調整します。上位のNTPサーバに接続する間隔は、サーバの起動時間などの理由でバラバラなので、時刻が調整されるタイミングもバラバラになります。これではログ上の時刻突き合わせもできなくなり死ぬしかなくなります。このように、きちんと考えると闇奥が深いのがうるう秒の処理です。うるう秒を正しく扱う比較的新しいサービスのみ面倒を見ているのであれば、おそらくうるう秒に起因する不具合もないでしょうから、全力でうるう秒を受け入れてあげるのが良いと思います。2012年以上前のディストリビューションでは上記不具合が修正されていない可能性がありますが、それ以外は特に何の問題も無く動くと期待されています。タイムゾーンに変更するとより良いです。インターネットマルチフィードのNTPサーバから時刻を受信し、データセンター内の自前NTPサーバを立てているようなケースを想定すると、全体像は以下のようになります。うるう秒の情報は、最終的には3つの方法で各サーバのLinuxカーネルに届きます。Indicator(LI)というフラグを経由して各サーバに配布されます。最新のRFC上は一ヶ月前からフラグを立てても良いことになっていますが、NICTでは以前のRFC等も考慮してうるう秒の24時間前からフラグを立てる運用となっています。Indicatorを受け取ったNTPクライアントは、adjtimex(2)というシステムコールを呼んでLinuxカーネルにうるう秒の情報を伝えます。Linuxカーネルはtime_stateという変数にそれを保存しておき、月末(UTC)になったらその変数を見て必要ならばうるう秒を挿入します。うるう秒対応のタイムゾーンが設定されていれば、59分60秒という正しいうるう秒時刻を返し、そうでなければ59分59秒を2周するような時刻を返すようになります。2周する場合も、カーネルにより厳密にループが行われるので午前9時0分0秒(JST)になることなく繰り返されます。標準ntpdのデフォルト設定(STEPモード)ではこの動作となります。ChronyではSLEWモードで設定をしていてもLinuxカーネル側でうるう秒を挿入するようです。万が一、カーネルがうるう秒情報を受け取ってしまった後になって回避策を実施したい場合は、ntptimeコマンドでカーネル内のtime_stateを変更することができます。外部NTPサーバを参照するntpdが起動しっぱだとまた受け取ってしまうのでそちらの対応もお忘れ無きよう。何らかの設定により、NTPクライアントがうるう秒の処理をする場合があります。以下を実行しているRHEL系ディストリビューションでSLEWモード(後述)を設定した場合などが挙げられます。IndicatorによりNTPクライアントはうるう秒を把握しますが、その情報をLinuxカーネルには渡しません。その代わり、うるう秒になったらstetimeofday(2)やclock_settime(2)などのシステムコールを用いて1秒間時刻を戻します。カーネルの処理では無いため、一瞬だけ9時0分0秒(JST)を過ぎてから8時59分0秒(JST)に戻されます(検証例あり)。これは、安定した結果を保障できないため、オススメできません。NTPを利用せずtzdataからうるう秒を取得タイムゾーンの情報をまとめたtzdataというパッケージには、最新のうるう秒の情報が含まれます。そのため、最新のtzdataパッケージに更新しておくことで、NTPを利用できない場合にもうるう秒の処理を適切に行うことができます。実際のうるう秒前後の挙動は、1の場合と同じです。うるう秒を全力を挙げて見逃すにはこのように、うるう秒を上手い具合に処理するためにいくつかの方法が用意されているわけですが、古いカーネルで動けど止めづらいサーバがあったり、サーバ数が多すぎて漏れの無い対応がし切れないなどの理由で回避が必要であれば、全力を挙げて見逃す必要があります。その為には、以下の2つをどうするかを考えなくてはいけません。本来のうるう秒の処理を行わせない。別の方法でうるう秒の1秒を「うまく」さしこむ。回避すると決めたら、大事なのは「うるう秒をもたず、つくらず、もちこませず」の非うるう秒三原則をどう厳守するかを考えます。Indicatorをクリアする方法があります。私は未検証なので紹介に留まりますが、IBMの記事では01や10に強制セットするパッチが下部「図3」として記載されているので、00に強制クリアすることも可能でしょう。作らないntpdが落ちている場合でもうるう秒が不用意に挿入されないよう、意図しないサーバでtzdataが最新にならないようにします。最新のtzdataが入っているようなケースは他のパッケージでもうるう秒の影響を受けづらいとは思います。Indicatorを除去するためには、仮想化環境でない物理サーバがあるのであれば、ハードウェアクロック(RTC)もそれなりに正確ですので、一時的に外部のNTPサーバへの参照を辞めてしまうのが一番手っ取り早いです。Indicatorが設定されるので、それより前からうるう秒の後まで、24時間以上を外部への参照を止める必要があります。当然ながら、RTCの品質があまりにも悪い場合や仮想サーバなどでは秒単位で時刻がずれてしまう可能性もあります。Indicatorが一ヶ月前から設定されるようになると現実的では無くなるでしょう。それまでにはうるう秒を誰もが受け入れられる優しい世界か、なんらかの代替策が用意されていると嬉しいです。1秒の挿入方法うるう秒を無視するためには、その1秒を何らかの形で「より影響が少ない方法」で反映する必要があります。これは、時計をゆっくり動かして1秒を生み出すのが一般的です。実際に、パブリッククラウドのAWSやGCP、携帯キャリア、東京証券取引所などではこのやり方を採用しています。一般的には、ntpdのSLEWモードを使う事になります。自前でNTPサーバを立てず、NTPクライアント側で設定を入れるのであれば、「-x」オプションを付ければ良いです。前述したとおりNTPのバージョンによってはSLEWモードにしていても、うるう秒だけは1秒ガツンと戻されるような不具合がすぐ最近まで残っていたので、注意が必要です。その一方で、前述の図のように自前NTPサーバを立ててそこを参照しているような場合は、NTPクライアントの設定によりNTPサーバに時刻を聞きに来る頻度がデフォルト設定でも1024秒(約17分強)だったりするので、NTPサーバに「-x」オプションを付けるだけではダメです。自前NTPサーバも冗長化している場合にはそのサーバ間での時刻同期も重要となってきます。このように、結構厄介な地獄が待っていますが、詳しくはそのうちどっかで記事に載るのでは無いでしょうか(他人事)。Indicator、うるう秒を発生させられる検証用NTPサーバをNICTさんが配っているので、それを上位NTPサーバとして検証ができます。まとめうるう秒でも正しく動くシステムを作りましょう。うるう秒の廃絶に向けて、廃止の動きを応援しましょう。再受賞(2019)Slack情報収集のためのチートシートデザインテーマ変えてみましたもっと見る月別アーカイブ検索はてなブログをはじめよう!nekoruriさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。