2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

VMware Workstation で Linuxの時刻を3コマンドで合わせる方法

Last updated at Posted at 2021-12-15

はじめに

検証環境や閉環境などのインターネットもNTPもない環境で仮想マシンを作成すると、ゲストOS(Linux)の時刻が9時間進んた時刻になってしまいます。
dateコマンドを使って現実世界の時計を見ながら設定したり、スクリプトを使って-9時間した時刻を設定している方もいるのではないでしょうか。

しかし、ホストOSの時刻とゲストOSの時刻はなぜずれてしまうのでしょうか。

本記事では、時刻がずれてしまう原因の簡単な解説を行い、dateコマンドを使わず、現実世界の時計も見ず、
ホストOS(Windows)の時刻(JST)を基準として時刻合わせを行う方法を紹介します。

環境

  • ホストOS: Windows10
  • VMware Workstation 16
  • ゲストOS:Ubuntu 20.04

状況と原因

VMware Workstation で仮想マシンを作成したとき、インターネット接続もなく、ntp環境もない場合はゲストOSの時刻はいつまでもおかしな時刻を指します。
「おかしな」というのは、ホストOSであるWindowsの時刻は現実世界に一致しているのに、ゲストOSであるLinuxは、ホストOSのローカルタイム(日本時刻JST)をUTCとして扱ってしまっていることです。

下記に示すように、現実世界とWindowsが11:00 JST のとき、ゲストOSの表示時刻(JST)は9時間進んだ時刻 20:00 JST を示してしまいます。

測定場所 時刻
現実世界(日本時刻) 11:00 JST
ホストOS Windows表示時刻 11:00 JST
ゲストOS Linux表示時刻(UTC) 11:00 UTC (おかしい)
ゲストOS Linux表示時刻(JST) 20:00 JST

原因の解説は 仮想化雑記帳: 仮想マシンとハードウェアクロック を読んでいただくとして、簡単に解説すると、

  • 仮想マシンが初回に起動するときは、VMware WorkstationがホストOS(Windows)のローカルタイム(日本時刻)を仮想マシンのリアルタイムクロック(RTC)に書き込む
  • RTCにタイムゾーンの概念はない
  • 仮想マシン上のゲストOS(Linux)は、RTCの時刻をUTCとして扱う
  • なので、Linuxが表示するローカルタイム(日本時刻)はUTCから9時間進んだ時刻になる

image.png

3コマンドで合わせる方法

結論

何も考えずに次の3コマンドを実行すればOKです。Linuxインストール時に設定したタイムゾーンには依存しません。

sudo timedatectl set-timezone Asia/Tokyo    # ホストOSのタイムゾーンに合わせる
sudo hwclock --hctosys --localtime          # ハードウェアクロック(hc)の時刻をローカルタイムとみなして、システムクロック(sys)に適用する
sudo hwclock --systohc --utc                # システムクロック(sys)の時刻を、ハードウェアクロック(hc)に適用する。その際、hcはUTCを表示させるべきものとして扱います

解説

各コマンドの実行結果を、timedatectl の結果を確認しながら進めます。

なお、作業時点でのWindowsの表示時刻は 「10:00 JST」頃となっています。

まずは、timedatectl コマンドで現在の状況を確認します。
RTC timeが10:00となってしまっています。
RTC timeはUTC時刻を表示していてほしいので、ここをなんとか01:00(日本時刻の9時間前)にするのが目標です。

$ timedatectl 
               Local time: Wed 2021-12-15 10:00:38 UTC
           Universal time: Wed 2021-12-15 10:00:38 UTC
                 RTC time: Wed 2021-12-15 10:00:37     # ここを01:00:37と表示されるようにしたい
                Time zone: Etc/UTC (UTC, +0000)       
System clock synchronized: no                         
              NTP service: active                     
          RTC in local TZ: no                         

まずは、timedatectl set-timezoneコマンドで、LinuxのローカルタイムゾーンをJSTにします。
ここでJSTを選んだ理由は、ホストOSのタイムゾーンがJSTであることと、以降のコマンドで、RTC timeの時刻をJSTとして扱いためです。
ホストOSの時刻がESTの方は、LinuxのローカルタイムゾーンをESTにしてください。
(作業後は好きなタイムゾーンに変更できます)

$ sudo timedatectl set-timezone Asia/Tokyo
$ timedatectl 
               Local time: Wed 2021-12-15 19:04:08 JST   # ローカルタイムゾーンがJSTになった
           Universal time: Wed 2021-12-15 10:04:08 UTC
                 RTC time: Wed 2021-12-15 10:04:07    
                Time zone: Asia/Tokyo (JST, +0900)    
System clock synchronized: no                         
              NTP service: active                     
          RTC in local TZ: no                         

次に、hwclock --hctosysコマンドで、hc(ハードウェアクロック、RTC)時刻をsys(システムクロック、Linuxの時計)に適用します。
この際、--localtimeオプションを付与することで、hcがローカルタイム(JST時刻)を表示しているものとして扱います。

$ sudo hwclock --hctosys --localtime 
$ timedatectl 
               Local time: Wed 2021-12-15 10:04:34 JST   # RTC time の時刻(JST扱い)がLocal timeに適用された
           Universal time: Wed 2021-12-15 01:04:34 UTC
                 RTC time: Wed 2021-12-15 10:04:34    
                Time zone: Asia/Tokyo (JST, +0900)    
System clock synchronized: no                         
              NTP service: active                     
          RTC in local TZ: no                         

最後に、hwclock --systohcコマンドで、sys(システムクロック、Linuxの時計)を、hc(ハードウェアクロック、RTC)に適用します。
この際、--utcオプションを付与することで、hcはUTCを表示させるべきものとして扱います。
つまり、timedatectlコマンドの「Universal time」がRTCに適用されます。

$ sudo hwclock --systohc --utc
$ timedatectl 
               Local time: Wed 2021-12-15 10:04:48 JST
           Universal time: Wed 2021-12-15 01:04:48 UTC
                 RTC time: Wed 2021-12-15 01:04:48        # Universal time が Local timeに適用された
                Time zone: Asia/Tokyo (JST, +0900)    
System clock synchronized: no                         
              NTP service: active                     
          RTC in local TZ: no    

これで仮想マシンのRTCが、期待する状態になりました。
仮想マシンを再起動しても、電源OFF/ONしても、クローンしても時刻は期待する状態を維持します。

ただし、仮想マシンをエクスポートしてova,ovf形式にし、その後インポートした場合にはまた時刻がおかしくなります。
RTCの時刻はovaファイルに保存されないためです。
(この表現は正確ではないので、解説は仮想化雑記帳: 仮想マシンとハードウェアクロック を参照ください)

まとめ

  • 仮想マシンの初回起動時はOSのローカルタイムをUTCとして扱ってしまう
  • dateコマンドで時刻を修正することもできるが、RTCを正しい値に修正することで正しい状態にすることができる
  • コマンドは、何も考えずに3行実行するだけでよい
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?