こんにちは、キクです。
本記事ではLinux学習シリーズとして、僕が学んだ内容をアウトプットしていこうと思います。
今回は『UTC』および『時刻関連の仕組み』をテーマに書いていきたいと思います!
本記事の内容
それでは、よろしくお願いします。
システムにおける時刻設定の重要性
昨今世界にはたくさんのシステムが存在しています。
それらのシステムにおいては今回のテーマである「時刻設定」は非常に重要な要素であることは言うまでもありませんよね。
時刻情報が使われるケースはさまざまです。
身近なで言えば「ファイルの更新日時」ながとあります。
システム内に多数存在する各ファイルやフォルダは「いつ」作成されたものなのか。
もしシステムの時刻情報がヘンテコな設定になっていたら?
作成日・更新日などが分からず困ってしまいますよね。
またシステムに何かしらの「障害」が発生したとき。
こんなときにはシステムが吐き出した「ログファイル」を頼りに障害の発生日時や原因を追跡していくと思います。
もしシステムの時刻情報がとんちんかんな設定になっていたら?
障害調査が進まず困ってしまいますよね。
ここで上げたのは僅かな例ですが、これだけでもシステムにおいて時刻情報が大切であることがお分かりいただけるかと思います。
UTCとは
ここから時刻関連の内容をいくつかお話しますが、まずは「UTC」について触れていきたいと思います。
UTCとは「Universal Time Coordinated」の略で、「協定世界時」と呼ばれるものです。
この「協定世界時」というのは、現在世界の基準となっている時刻(標準時)のことです。
UTCと並ぶ概念で「GMT」と呼ばれるものがあります。
GMTとは「Greenwich Mean Time」の略で、「グリニッジ標準時」と呼ばれるものです。
UTCが現在の世界標準時になる以前はGMTが世界の標準時として扱われていました。
切り替わった理由としては、それぞれの時刻算出方法の面でUTCの方がより正確であろうとなったからだそうです。
ちなみにUTCはセシウム原子の振動数をもとに時間を導き出しており、GMTはグリニッジ天文台という場所で天文観測をして時間を導き出しています。
地球の自転の関係で1日の長さが年間を通して一定ではないということも影響してUTCに軍配が上がったとか。
しかし、両者の差異はとても小さいため「UTC=GMT」として扱うこともあるみたいです。
タイムゾーンとは
次に「タイムゾーン」について。
タイムゾーンは先述の「UTC」をもとに地域ごとに区分された標準時間帯のこと。
例えば日本(東京)のタイムゾーンは「Asia/Tokyo」として存在しており、「UTC」から9時間進めた時刻になります。
また、タイムゾーンにより地域ごとに区分された標準時のことを「ローカルタイム」と呼びます。
日本(東京)の場合は「JST」です。
UTCがPM13:00の時、JSTは9時間加えたPM22:00という形になります。
ここで少しLinux的なお話。
タイムゾーンの情報は「/usr/share/zoneinfoディレクトリ配下」にバイナリファイルとして格納されています。
[root@centos7 ~]# ls /usr/share/zoneinfo
Africa Chile GB Indian Mexico posixrules Universal
America CST6CDT GB-Eire Iran MST PRC US
Antarctica Cuba GMT iso3166.tab MST7MDT PST8PDT UTC
Arctic EET GMT0 Israel Navajo right WET
Asia Egypt GMT-0 Jamaica NZ ROC W-SU
Atlantic Eire GMT+0 Japan NZ-CHAT ROK zone1970.tab
Australia EST Greenwich Kwajalein Pacific Singapore zone.tab
Brazil EST5EDT Hongkong leapseconds Poland Turkey Zulu
Canada Etc HST Libya Portugal tzdata.zi
CET Europe Iceland MET posix UCT
そしてシステムで利用するタイムゾーンは上記のファイルを「/etc/localtimeファイル」にコピーまたはシンボリックを作成して設定します。
例えばシンボリックリンクで作成されている場合は以下のように確認することができます。
[root@centos7 ~]# ls -l /etc/localtime
lrwxrwxrwx. 1 root root 32 Nov 30 2020 /etc/localtime -> ../usr.share/zoneinfo/Asia/Tokyo
この結果から、タイムゾーンは「日本」に設定されていることが分かります。
システムクロックについて
続いて「システムクロック」について。
システムクロックはOSが管理している時計のことです。
先述した「ファイルの更新日時」などはこのシステムクロックを利用しています。
この時計はメモリ上に置かれています。
そのため、電源を落としたらリセットされます。
ではリセットされた時計はどのように設定すればよいのか。
基本的にはOS起動のタイミングで後述の「ハードウェアクロック」を参照してセットされます。
なお、システムクロックは「UTC」で運用・管理されます。
そして設定したタイムゾーンの差異を反映した時刻がシステムで利用されます。
timedatectlコマンドが便利だった話
timedatectlというコマンドを実行した結果が個人的に内容がスッと入ってきたのでご紹介します。
[root@centos7 ~]# timedatectl status
Local time: Wed 2021-01-06 20:18:22 JST
Universal time: Wed 2021-01-06 11:18:22 UTC
RTC time: Wed 2021-01-06 11:18:19
Time zone: Asia/Tokyo (JST, +0900)
NTP enabled: yes
NTP synchronized: no
RTC in local TZ: no
DST active: n/a
上記実行結果の「Universal time」という項目が「システムクロック」になります。
右端に「UTC」と表示されていることからもシステムクロックがUTCであることが分かります。
その上の「Local time」はそのまま「ローカルタイム」のことです。
この環境ではタイムゾーンとして「日本」を設定しているので「UTC+9時間」の時刻になっています。
ハードウェアクロックについて
次は「ハードウェアクロック」について。
ハードウェアクロックはその名の通りハードウェア上に実装された時計になります。
先程のシステムクロックはメモリ上で稼働していたため電源を落とすとリセットされていましたが、
こちらのハードウェアクロックは電源を落としても稼働し続けることができます。
1時間電源を落としてから起動しても、時刻情報は1時間後のものになっています。
ハードウェアクロックの運用・管理方法は「UTC」または「ローカルタイム」の2パターンあります。
システムクロックはOS起動時にハードウェアクロックを参照して時刻をセットするとお話しましたが、
この2パターンの設定内容により動作が異なります。
ハードウェアクロックが「UTC」の場合には、システムクロックも「UTC」なのでそのままセットすることができます。
しかし、ハードウェアクロックが「ローカルタイム」の場合には、システムクロックにセットする際には設定したタイムゾーン分の時刻を考慮してセットされます。
ややこしいのでローカルタイム「JST」を例にもう少し詳しく書いていきます。
JSTは「UTC+9」の時刻でした。
ハードウェアクロックが「ローカルタイム」で設定されている場合には最初からJSTがハードウェアクロックにセットされます。
「JST=UTC+9」は「JST-9=UTC」でもあるので、システムクロックには「UTC」すなわち「JST-9」がセットされれば辻褄が合います。
システムクロックのお話でも登場したtimedatectlコマンドを使って比較してみます。
ハードウェアクロック=UTC
まず「ハードウェアクロック=UTC」の場合。
[root@centos7 ~]# timedatectl status
Local time: Wed 2021-01-06 20:18:22 JST
Universal time: Wed 2021-01-06 11:18:22 UTC
RTC time: Wed 2021-01-06 11:18:19
Time zone: Asia/Tokyo (JST, +0900)
NTP enabled: yes
NTP synchronized: no
RTC in local TZ: no
DST active: n/a
「RTC time」がハードウェアクロックを表しています。
システムクロック(Universal time)がUTCなので、その時刻と(ほぼ)一致していることからもハードウェアクロックがUTCであることが分かります。
これであればシステムクロックはOS起動時にハードウェアクロックの時刻をそのままセットすればいいことになります。
ハードウェアクロック=ローカルタイム
次に「ハードウェアクロック=ローカルタイム」の場合。
[root@centos7 ~]# timedatectl status
Local time: Wed 2021-01-06 20:18:22 JST
Universal time: Wed 2021-01-06 11:18:22 UTC
RTC time: Wed 2021-01-06 20:18:22
Time zone: Asia/Tokyo (JST, +0900)
NTP enabled: yes
NTP synchronized: no
RTC in local TZ: yes
DST active: n/a
ここでは「RTC in local TZ」という項目が「yes」になっています。
これが「ハードウェアクロック=ローカルタイム」であることを判断する1つの材料になります。
また「Local time」が「RTC time」と一致していることからもハードウェアクロックがローカルタイムで動いていることが分かりますね。
そしてシステムクロック(Universal time)がハードウェアクロック(RTC time)から9時間前の時刻になっていることも分かるかと思います。
システムクロックはOS起動時にハードウェアクロックの時刻を参照するのでした。
そのためハードウェアクロックがローカルタイム(JST)の場合にはUTCであるシステムクロックは-9時間にしてあげないと辻褄が合いません。
この実行結果からもちゃんと時刻調整ができていることが読み取れます。
ハードウェアクロックを「ローカルタイム」とした場合にはどこからその時刻情報を持ってくるのかということについてですが、
この情報は「環境変数TZ」あるいは「/etc/localtimeファイル」から取得することになります。
NTPサーバについて
ここまでで「システムクロック」と「ハードウェアクロック」について簡単にお話しました。
これら2つに共通して言えることは「精度が優れているとは言い難い」ということです。
システムクロックは電源を落としたらリセットされてしまいますし、ハードウェアクロックもマザーボード内臓の電池が消耗されていくにつれて時計が狂ってきてしまうそうです。
そんな悩みを解決してくれるのが「NTPサーバ」です。
NTPとは「Network Time Protocol」の略で、ネットワークに接続されたコンピュータや各種機器の時刻同期に用いられるプロトコルのことです。
つまりNTPサーバとは時刻サービスを提供するサーバになります。
システムクロックやハードウェアクロックは自身の内部的なお話でしたが、NTPサーバを用いることで自身とは別の外部から時刻情報を取得して時計をセットする形になります。
ちなみにNTPサーバの情報を用いてセットするのは「システムクロック」になります。
同期した「システムクロック」から必要に応じて「ハードウェアクロック」にも同期をかけたりもします。
また、NTPサーバは階層構造になっていて最上位は「原子時計」や「GPS」などです。
この階層構造を利用して、NTPサーバは自分より上位のNTPサーバから正確な時刻を取得しています。
そして現在世界中で稼働する多くのシステムがNTPサーバから時刻情報の同期を実施して時刻合わせをしています。
今回NTPサーバについては深堀りはしませんが、今日のシステムにおいてNTPサーバがなくてはならない存在であることは間違いありません。
おわりに
いかがだったでしょうか。
「システムクロック」「ハードウェアクロック」「NTPサーバ」などさまざまな時計の仕組みがありましたね。
僕も本記事を書くことを通して、改めて...というより更に深く理解することができました。
システムにおいて正確性が求められる「時刻情報」。
何かあったときに仕組みを理解していることはとても重要ですよね。
本記事が少しでもその理解のお役に立てれば嬉しいです!
・・・いい機会なのでNTPサーバについてもより深く勉強してみようかな🤔
本記事を最後まで読んでいただき、ありがとうございました。
ではでは!