Here’s a quick guide to run an NTP (Network Time Protocol) server using Chrony with a GPS (optional) receiver on a VMware ESXi Guest running Ubuntu 18.04. I should note this is experimental and something I setup in my homelab temporarily. For production environments I would run NTP on physical hardware and not VMware.
Create and Configure VM
Be sure to disable Guest Tools Time synchronization by editing the VM settings and uncheck Synchronize guest time with host.
Set the CPU shares to High… we want the NTP server to have priority if there is processor contention.
Install Chrony
sudo apt install chrony sudo vim /etc/chrony/chrony.conf
# Welcome to the chrony configuration file. See chrony.conf(5) for more # information about usuable directives. # This will use (up to): # 3 sources from ntp.ubuntu.com # 3 sources from us.pool.ntp.org # 3 sources from time.nist.gov pool ntp.ubuntu.com iburst maxsources 3 pool us.pool.ntp.org iburst maxsources 3 pool time.nist.gov iburst maxsources 3 # This directive specify the location of the file containing ID/key pairs for # NTP authentication. keyfile /etc/chrony/chrony.keys # This directive specify the file into which chronyd will store the rate # information. driftfile /var/lib/chrony/chrony.drift # Uncomment the following line to turn logging on. log tracking measurements statistics # Log files location. logdir /var/log/chrony # Stop bad estimates upsetting machine clock. maxupdateskew 100.0 # This directive enables kernel synchronisation (every 11 minutes) of the # real-time clock. Note that it can’t be used along with the 'rtcfile' directive. rtcsync # Step the system clock instead of slewing it if the adjustment is larger than # one second makestep 1 -1 allow
I diversified between Ubuntu’s, NTP.org’s and NIST’s time server pools.
That’s it, after restarting the chrony service (service restart chrony) you should be able to get time reports by running:
chronyc sources -v chronyc sourcestats -v chronyc tracking -v
Why You Shouldn’t Run an NTP Server in a VM Guest
VM’s can’t keep accurate time
I’ve generally found that VMs keep great time inside of VMware. One thing that can help with this is setting the CPU shares to high so your time server always has a priority. I ran Chrony in a VM for several weeks, compared it with Chrony on a Raspberry Pi. Both were acceptable, and both had a smaller standard deviation than public NTP servers over the internet, but the VM had a much smaller standard deviation than the Pi. That tells me VMs running on better hardware may be better than lesser bare physical hardware at time tracking under certain conditions, and a local NTP server in a VM can be more precise than grabbing time off the internet.
VMs can become out of sync during snapshots, suspend, failover, etc.
I ran a suspend test and this is true. I paused a VM, waited 10 seconds, then resumed it. It reported the wrong time to NTP clients for several minutes before it corrected itself from external NTP servers. Here’s a screenshot of my NTP server being 11 seconds off after a pause!
This is a valid reason to run an NTP server on physical hardware. However, I think it is possible to run an NTP server under VMware with the following precautions:
- Your NTP servers under VMware should never be paused. That means they should be excluded from failover (instead of failover it’s better to configure multiple NTP servers for your clients to connect to since it’s better for an NTP server to be down than report a wrong time).
- Have multiple NTP servers. At least three. You’ll notice in the screenshot above Chrony (running on a separate physical machine) flagged the server as not being accurate. This way if one of your VMs gets paused chrony will switch to another time-source automatically.
- Set makestep 1 -1 in the chrony.conf file (this tell chrony that any difference greater than one second will get stepped which allows for faster correction after a resume).
GPS Receiver
This is not really related to VMware. But I had a GPS receiver so thought I’d see how it works with Chrony….
I have a GlobalSat BU-353S4 USB GPS Receiver. This isn’t the best GPS receiver for accuracy. For me it’s accurate to within a few hundred milliseconds which is good enough for my experimental purposes but worse than just grabbing time off the internet. For serious time-keepers you’ll be wanting to use something faster than USB and more accurate than what a cheap GPS receiver can provide.
Configure gpsd
sudo apt install gpsd gpsd-clients sudo vim /etc/default/gpsd
# Start the gpsd daemon automatically at boot time START_DAEMON="true" # Use USB hotplugging to add new USB devices automatically to the daemon USBAUTO="true" # Devices gpsd should collect to at boot time. # They need to be read/writeable, either by user gpsd or the group dialout. DEVICES="/dev/ttyUSB0" # Other options you want to pass to gpsd GPSD_OPTIONS="-n -F /var/run/gpsd.sock"
Install Chrony
sudo apt install chrony sudo vim /etc/chrony/chrony.conf
# Welcome to the chrony configuration file. See chrony.conf(5) for more # information about usuable directives. # This will use (up to): 3 sources from ntp.ubuntu.com 3 sources from us.pool.ntp.org 3 sources from time.nist.gov 1 GPS device pool ntp.ubuntu.com iburst maxsources 3 pool us.pool.ntp.org iburst maxsources 3 pool time.nist.gov iburst maxsources 3 refclock SHM 0 refid GPS precision 1e-1 offset 0.250 delay 1e-9 # This directive specify the location of the file containing ID/key pairs for # NTP authentication. keyfile /etc/chrony/chrony.keys # This directive specify the file into which chronyd will store the rate # information. driftfile /var/lib/chrony/chrony.drift # Uncomment the following line to turn logging on. log tracking measurements statistics # Log files location. logdir /var/log/chrony # Stop bad estimates upsetting machine clock. maxupdateskew 100.0 # This directive enables kernel synchronisation (every 11 minutes) of the # real-time clock. Note that it can’t be used along with the 'rtcfile' directive. rtcsync # Step the system clock instead of slewing it if the adjustment is larger than # one second, at any time makestep 1 -1 allow
So, how did I get the values on the refclock line…
The way I came up with my offset of 0.250 is by initially setting the offset to 0.0, restarting chrony, and running chronyc sources -v several times taking note of the offset. I’d get numbers like +249ms, +253ms, +250ms, etc.
Since my GPS is off by about 250ms I set the offset to 0.250. Now it’s usually not off by more than 100ms.
The 100ms+- variance is not a problem when being combined with other sources, but if it was the only time source I’d be better off tolerating drift than the high variance of GPS for a short period without access to the NTP pools, if I had no internet for several months or an air-gapped network then time via GPS would probably be better than nothing–but a better GPS receiver should be used in those scenarios.
For most networks running chrony in a VM and using a GPS is unnecessary. It’s better to keep it simple. I just use the NTP service on my pfSense router and set all the clients to that.
…
Don’t forget to watch your clocks adjust themselves next Sunday!
Cool post, and a lot to think about – just off hand, how do you think it compares to a more conventional setup of using 2xWindows domain controllers as NTP servers, the first of which has a local NTP pool in its registry, and the second one pulling from the first?
avery@debbox:~$ ntpq -p
remote refid st t when poll reach delay offset jitter
LOCAL(0) .LOCL. 10 l 11d 64 0 0.000 0.000 0.000
*2012dc01.webtoo 208.75.89.4 3 u 358 1024 377 0.365 -3.022 12.830
2012dc02.webtoo .LOCL. 1 u 280 1024 377 0.632 58245.6 95.226
Regedit info can be found in this KB article, covers several versions of ESXi and Windows server:
https://kb.vmware.com/s/article/1035833
Good question averyfreeman. I’m not that familiar with Windows domain controllers–I know the sysadmins where I worked awhile ago stopped using Windows DCs (running on bare metal) as the main time source because they’d drift ahead or behind actual time by a minute or two throughout the day. I don’t know if that was an issue with the Windows Time Service or an issue in our environment (could have been bad hardware that couldn’t keep good time).
Sorry that copied text turned out awful, here’s a screenshot:
https://averyfreeman.com/images/ntpq-p.PNG