Synchronizing the time inside KVM guests is essential for a large number of reasons, including correlating logs from multiple guests and Maildir locking.
When a KVM guest start up it is provided with the host clock. This is used initialize the clock of the guest to the correct time. On older hardware this was usually good enough and the guest and host clocks would stay somewhat in sync. However on modern hardware different cores can run at different clockspeeds and even go completely idle. Causing the clock of the host and guest to go out of sync.
The most trivial solution is to shutdown and restart the guest every day, forcing the clock back in sync. Besides frequent reboots usually being undesirable, this also doesn’t completely sync both clocks.
The standard solution for syncing system is to enable configure a Network Time Protocol (NTP) client. A daemon will fetch the time from an internet source, estimate the time it took the response to receive the system, adjust and sync the clock. However this requires every guest to be able to communicate with a NTP server, and then still, not having the exact time due to uncertainties in determining the response delay.
By running a NTP server on the host and configuring the guests to use it, a large part of the network jitter is removed. However this still requires the time to go through two network stacks (on on the guest and one of the host).
Linux 4.11 introduced a way which allows up to cut out the network stacks and directly synchrinze by using the Precision Time Protocol (PTP). On physical hardware this is used with special network cards to pick up a highly accurate timing signal from the network. On KVM guests this can be used to keep the guest in sync with the host.
First of all, on the guests make sure the correct kernel module is loaded:
In order to make sure the module is loaded during startup create a file under /etc/modules-load.d:
echo ptp_kvm > /etc/modules-load.d/ptp_kvm.conf
Now the default NTP client on Debian does not support PTP, so we will need to install chrony:
apt-get install chrony
Edit chrony’s configuration file (/etc/chrony/chrony.conf) and replace the ‘pool’ statement with
refclock PHC /dev/ptp0 poll 2
I also recommend disabling the ‘makestep’ entry to make sure the clock is not adjusted immediately when restarting chrony.
The resulting config will look something like this (comments removed):
refclock PHC /dev/ptp0 poll 2 keyfile /etc/chrony/chrony.keys driftfile /var/lib/chrony/chrony.drift logdir /var/log/chrony maxupdateskew 100.0 rtcsync
Now restart chrony
service chrony restart
and use chony’s CLI to check your clock is (getting) in sync:
Depending on how much the guest clock was out of sync it may take a while for it to completely match the host clock.
Once in sync chrony will keep the guest in sync with the host.