【RHEL】這いよる閏秒 7月1日9:00(JST)の挙動(3年ぶりだな)

【RHEL】這いよる閏秒 7月1日9:00(JST)の挙動(3年ぶりだな) はてなブックマーク - 【RHEL】這いよる閏秒 7月1日9:00(JST)の挙動(3年ぶりだな)


◆ 第三種接近遭遇、的な

来月 7 月 1 日 8:59:59 – 9:00:00 (日本時間 JST) に、「うるう秒」(leap second) 挿入があります。閏秒は、08:59:60 です。約三年半ぶりの閏秒の挿入、皆さんのシステムでは、準備はお済みでしょうか(閏秒の詳細は NICT のプレスリリースをご覧ださい)

RHELでは、ntp を使っているかどうか、また tzdata (タイムゾーンデータ)を更新済みかどうかで、挙動が異なります。身近に這いよる┌(┌ ^o^)┐閏秒ォ…に備え、挙動を確認してみました。

以下、手許の RHEL5 の環境で、閏秒発生時どのような挙動をするかの記録です。といっても、殆ど自分のためのメモ書き。

◆ 結論

日本標準時
JST
2012/07/01
ntpdを使っている
(stepモード
デフォルト)
ntpを使っていない
tzdata 更新済み 未対策
08:59:59 08:59:59 08:59:59 08:59:59
08:59:60
08:59:59 08:59:60 09:00:00
09:00:00 09:00:00 09:00:00 09:00:01

[1] ntpd が有効な場合、標準のstepモードでは、閏秒 08:59:60 (JST)挿入時、08:59:59 を繰り返す(時間遡行)
– 基本、対応不要だと思われるが、環境によっては支障が無いか要確認
– kernel が古い場合はクラッシュする可能性があるので、kernel をバージョンアップする必要
RHEL4 | kernel-2.6.9-89.EL (RHSA-2009:1024-1) 以上に
RHEL5 | kernel-2.6.18-164.el5 (RHSA-2009:1243-3) 以上に
(関連情報 : https://access.redhat.com/knowledge/ja/articles/106233 要ログイン)
– ntpd に ‘-x’ オプション(slewモード)を有効にすると、うるう秒を挿入せず、ゆっくり時間補正する。しかし、ntp-4.2.2p1-9 以下の ntpd では、-x オプションをつけても時間が遡行する(詳細)。

[2] ntpd を入れていない場合、世間から「1 秒」時刻が進む
– 対策は、tzdata パッケージを更新する。ntp を動かさなくても、08:59:60 をカウントさせる
– ただし、08:59:60 秒をカウントしても、許容されうる環境のみ推奨

参考になる URL

プレスリリース | 「うるう秒」挿入のお知らせ | NICT-独立行政法人 情報通信研究機構
http://www.nict.go.jp/press/2012/01/31-1.html

Red Hat Enterprise Linux におけるうるう秒について – Red Hat Customer Portal
https://access.redhat.com/knowledge/ja/articles/106233

うるう秒のLinuxへの影響(2012年7月版) – cuspy diary
http://www.cuspy.org/diary/2012-06-05

IBM Linux at IBM | 【Technical Notes】Linux システムクロックの『うるう秒』調整
http://www-06.ibm.com/jp/domino01/mkt/cnpages7.nsf/page/default-0019DB89

 

なお、検証に用いたの RHEL5 の環境は、kernel 2.6.18-128.1.14.el5 および ntp-4.2.2p1-15.el5_7.1。CentOS でも同様の問題が発生しうるのかな?と思いますが、僕の手許には無いので未確認です。また、検証にあたっては、Tsukasa Hamano氏の blog うるう秒のLinuxへの影響(2012年7月版)を、非常に参考にさせていただきました。

◆ 検証の為の環境作り(簡易SNTPを用いる)

検証にあたって、ntpd が動いていない場合は、data コマンドで時刻を修正します。

# date --set="2012/07/01 08:59"

あとは、Tsukasa Hamano氏の blog で紹介されているスクリプト gettimeofday.pl を使い、閏秒挿入時の時刻推移をみます。

$ perl ./gettimeofday.pl
(snip)
08:59:59.098719
08:59:59.199718
08:59:59.301111
08:59:59.401718
08:59:59.502718
08:59:59.603718
08:59:59.704718
08:59:59.805718
08:59:59.906718
09:00:00.007718
09:00:00.108718
09:00:00.209718
09:00:00.311096
09:00:00.411718
09:00:00.512718
09:00:00.613717
09:00:00.714718
09:00:00.815719
09:00:00.916718

このように、未対策の場合は、何事も無く 08:59:59 -> 09:00:00 に推移します。

では、ntpd を起動した場合はどうなるでしょうか。ここで、電磁波計測研究所で公開されている、SNTPサーバ うるう年テストバージョンを用います。

日本標準時プロジェクト 関連資料
http://www2.nict.go.jp/aeri/sts/tsp/link/leap.html#2

このスクリプトをダウンロードします。このスクリプトを用い簡易 SNTP サーバをたてます。これは、時刻計測を行うサーバとは別です。

SNTP 用のサーバでは、sntp.pl 等としてファイルを設置します。基本このままですが、閏秒(leap time) 発生時の調整が必要です。

$NTP_LI = timegm( 0, 0, 0, 30, 6-1, 12 );      # 12/06/30 00:00:00 UTC
$NTP_LEAP = timegm( 0, 0, 0, 1, 7-1, 12 );     # 12/07/01 00:00:00 UTC
$USO_LEAP = timegm( 0, 0, 12, 23, 6-1, 12 );   # 12/06/23 12:00:00 UTC = 6/23 21:00 JST

$NTP_LI と $TNP_LEAP は、コピペで大丈夫です。UTC 7月1日 0:00 が、JST 9:00 にあたります。注意すべきは3行目の $USO_LEAP です。これは、このブログを書いている今、6月23日21:00(JST) に閏秒を挿入したい場合の例です。ここで記述する時間が、UTC のため、現在時刻から9時間引いた日時を記述する必要があります。

次に、パーミッションの変更と、root 権限で sntp.pl を実行する必要があります。

# chmod +x ./sntp.pl
# ./sntp.pl

root 権限でないと、ntp ポートを開くことはできません(エラー:bind: 許可がありません at ./sntp.pl line 31.と出ます)。

この状態で、元の時刻計測サーバで、時刻を補正します。おそらく、ntpdate を実行するのが手っ取り早いです。ntpdate 実行後、ntpd を起動します(このときは、何もオプションを付与しない 、デフォルトの step モードで ntpd を起動)。

# /usr/sbin/ntpdate node2
 1 Jul 08:49:02 ntpdate[9219]: step time server 210.158.217.159 offset 64800.000021 sec
# date
2012年  7月  1日 日曜日 08:49:03 JST
# /etc/rc.d/init.d/ntpd start
ntpd を起動中:                                             [  OK

この状態で、閏秒挿入時の挙動を確認します。

08:59:59.016055
08:59:59.117422
08:59:59.218055
08:59:59.319054
08:59:59.420054
08:59:59.521055
08:59:59.622055
08:59:59.723054
08:59:59.824055
08:59:59.925055
08:59:59.026423
08:59:59.127055   <- 閏秒発生時、08:59:59 (JST) が繰り返されている
08:59:59.228055
08:59:59.329426
08:59:59.430054
08:59:59.531055
08:59:59.632055
08:59:59.733054
08:59:59.834054
08:59:59.935054
09:00:00.036054
09:00:00.137038
09:00:00.238365
09:00:00.339054
09:00:00.440054
09:00:00.541055
09:00:00.642054
09:00:00.743445
09:00:00.844054
09:00:00.945054

このように、ntpd 起動時(stepモード)は、閏秒挿入時に 08:59:59 を繰り返していることが分かります。ちなみに、このとき、/var/log/messages には、次のようにログが出力されます。

Jul  1 08:59:59 node3 kernel: Clock: inserting leap second 23:59:60 UTC

◆ タイムゾーンデータ(tzdata)のパッケージ更新時の状況

ntpd による時刻補正を行わず、閏秒を補正したい場合があると思います。RHEL では、tzdat パッケージを最新にアップデートし、かつデータを更新する事で、閏秒に対応します。tzdata 更新時は、閏秒時には 08:59:60(JST) として認識されます。

更新方法は以下の通りです。

# yum -y update tzdata
# cp -p /etc/localtime /etc/localtime.orig
# cp /usr/share/zoneinfo/right/Asia/Tokyo /etc/localtime
cp: `/etc/localtime' を上書きしてもよろしいですか(yes/no)? y

これで作業は完了です。あとは、擬似的に日時をずらし、先の gettimeofday.pl で推移を見ます。

# date --set "2012/07/01 08:59:40"
# perl ./gettimeofday.pl
(snip)
08:59:59.094392
08:59:59.195392
08:59:59.296393
08:59:59.397393
08:59:59.498393
08:59:59.599394
08:59:59.700394
08:59:59.801394
08:59:59.902396
08:59:60.003396 <-- 閏秒
08:59:60.104396
08:59:60.205396
08:59:60.306397
08:59:60.407397
08:59:60.508397
08:59:60.609399
08:59:60.710399
08:59:60.811399
08:59:60.912400
09:00:00.013400
09:00:00.114400
09:00:00.215401
09:00:00.316769
09:00:00.417402
09:00:00.518402
09:00:00.619403
09:00:00.720403
09:00:00.821403
09:00:00.922405

このように「08:59:60」(JST) が挿入されている事がわかります。

◆ より詳しい Linux kernel の理解の為に

なお、Linux kernel における閏秒の処理については、中井さん(@enakai00)の著書「プロのための Linuxシステム・10年効く技術」にて詳しい解説がなされています。p.252 ~の「4.4 カーネルソース解析の実例」において、まさに kernel 内部での時刻制御の詳細が記述されています。

なお、この本は、Linux サーバ管理者やインフラ担当者にとって、とても参考になると思います。内部構造やコマンド群など、非常に実践的な構成です。興味がありましたら、どうぞ。
(中井さん、献本をいただきました。ありがとうございます!!)

◆ 挙動の把握と、リスクアセスメントを。

閏秒の発生は、事前にプレスリリースもされています。今回のように、影響を受ける可能性がある場合は、

  • 利用しているシステムの影響範囲を確認する
  • その影響に対して、問題があるかどうかを判断する

この作業が必要です。

今回のケースでは、閏秒発生時、ntpd の稼働の有無により、挙動が異なります。さらに、運用環境によって、59秒が繰り返されても良いのか、60秒が挿入されてもよいかどうかは、異なると思います。一番安全そうなのは ntpd に -x オプション(slew モード)をつけて、徐々に時刻補正をかける方法でしょうか(NTTの時報と同じような感じですね)。

もし、閏秒対策がまだでしたら、今からやりましょう。まだ十分に時間はあります。7月1日は日曜日ですし、何かあった時に慌てる事になると大変。今のうちに、検証・確認をされる事を、おすすめします(´・ω・`)

※内容に関して、記述ミス等ありましたら、ご指摘ください。