手元には数十個の Vagrant 仮想マシンがありますが、その大半は普段は使われることがなく眠っています。しばらくぶりに起動した仮想マシンは、時刻がずれていることが多いです。
VitualBox 付属の vbguest を VirtualBox 自身や Linux カーネルに追従してアップデートしていけば問題ないのかもしれませんが、これにも結構なコストがかかります。仮想マシンの起動に時間がかかりすぎるのも困るので、最近は Vagrantfile に以下のように手を入れて、自動ではアップデートしないようにしています。
if Vagrant.has_plugin?("vagrant-vbguest")
VMNAME.vbguest.auto_update = false
end
すると、今度は時刻のズレが気になります。マシンの時刻が大幅にずれていると yum コマンドが失敗するなど、いったいどこに影響が出るのか予測がつきません。
そこで、とりあえず .bashrc に時刻を強制同期するコマンドを入れてみました。
sudo chronyc makestep >& /dev/null
“>& /dev/null” 部分は非常に重要です。これがないと、chronyc makestep は “200 OK” というレスポンスを返します。ログイン時にこのような余計な文字列が標準出力に出力されると、ansible において ssh や scp が失敗したとみなされたりして思いがけないトラブルの元になります。
こんな感じでやり過ごそうとしていたら、実は sudo chronyc makestep >& /dev/null でもうまくいかないケースがありました。原因は、仮想マシンの起動直後は時刻同期に必要な時刻ソース(インターネット上のタイムサーバ)が取得できていないからのようです。時刻ソースの取得は sources サブコマンドで行います。
vagrant@VMNAME:~$ sudo chronyc sources
210 Number of sources = 4
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^- y.ns.gin.ntt.net 2 6 377 20 +5335us[+5335us] +/- 100ms
^? 45.76.111.149.vultr.com 2 9 0 34m +51410m[-1087us] +/- 17ms
^* ntp-b2.nict.go.jp 1 6 377 26 +478us[ +645us] +/- 12ms
^- tama.paina.net 2 6 377 24 +1315us[+1315us] +/- 53ms
.bashrc はシェルを起動するたびに何度も読み込まれるので、実行に結構な時間を要する sudo chronyc sources を .bashrc に入れるのはちょっとまずそうです。.bashrc の中で「時刻がずれていれば同期する」という if 文で挟めればよいのですが、時刻がずれていることをロジックで判断するためのアイデアが今の所思いつきません。
もっとも、本件はほぼ Vagrant 環境に限った話なので、もし自動化するなら時刻同期の処理自体を Vagrantfile の config.vm.provision ブロックにいれることが考えられます。
config.vm.provision "shell", inline: <<-SHELL
# sudo nmcli con mod "System eth0" ipv4.ignore-auto-dns No ipv4.dns 8.8.8.8
sudo chronyc sources
sudo systemctl restart chronyd
sleep 5
sudo chronyc makestep
# sudo yum -y update
SHELL
ただしこれだと初回の1回しか走らないので、仮想マシンの起動後は、コマンドラインで別途
vagrant provision
してやる必要があります。
(2021/08/27 追記)
さらに調べたところ、どうも chronyd の初期設定で、単に急激な時刻同期をやらないようになっているだけのようです。CentOS7 のデフォルトでは、/etc/chrony.conf で以下のようになっています。
# Allow the system clock to be stepped in the first three updates
# if its offset is larger than 1 second.
makestep 1.0 3
Vagrant 環境に限りますが、これを
makestep 1.0 -1
にしておけば、概ね数秒以内に正しく時刻同期されるようです。ただし、あまりにも急激に時間が過去や未来に飛んでしまうと確実にカーネルや各種サービスに影響が出るので、それだけは気にかけておいたほうがよいでしょう。仮想マシンの起動後に何か動作がおかしいと思ったら、まず vagrant reload することで事象が収まるかどうかを確認した方がよさそうです。