Linux中使用NTP保持精确时间的方法详解
<p><span><strong>前言</strong></span></p>
<p>
如何保持正确的时间,如何使用 NTP 和 systemd 让你的计算机在不滥用时间服务器的前提下保持同步。下面话不多说了,来一起看看详细的介绍吧。</p>
<p>
<span><strong>它的时间是多少?</strong></span></p>
<p>
让 Linux 来告诉你时间的时候,它是很奇怪的。你可能认为是使用 time 命令来告诉你时间,其实并不是,因为 time 只是一个测量一个进程运行了多少时间的计时器。为得到时间,你需要运行的是 date 命令,你想查看更多的日期,你可以运行 cal 命令。文件上的时间戳也是一个容易混淆的地方,因为根据你的发行版默认情况不同,它一般有两种不同的显示方法。下面是来自 Ubuntu 16.04 LTS 的示例:</p>
<div class="jb51code">
<div>
<div class="syntaxhighlighterbash" id="highlighter_932662">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="bash plain">$ </code><code class="bash functions">ls</code> <code class="bash plain">-l</code>
</div>
<div class="line number2 index1 alt1">
<code class="bash plain">drwxrwxr-x 5 carla carla 4096 Mar 27 2017 stuff</code>
</div>
<div class="line number3 index2 alt2">
<code class="bash plain">drwxrwxr-x 2 carla carla 4096 Dec 8 11:32 things</code>
</div>
<div class="line number4 index3 alt1">
<code class="bash plain">-rw-rw-r-- 1 carla carla 626052 Nov 21 12:07 fatpdf.pdf</code>
</div>
<div class="line number5 index4 alt2">
<code class="bash plain">-rw-rw-r-- 1 carla carla 2781 Apr 18 2017 oddlots.txt</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
有些显示年,有些显示时间,这样的方式让你的文件更混乱。GNU 默认的情况是,如果你的文件在六个月以内,则显示时间而不是年。我想这样做可能是有原因的。如果你的 Linux 是这样的,尝试用 <code>ls -l --time-style=long-iso</code> 命令,让时间戳用同一种方式去显示,按字母顺序排序。请查阅 如何更改 Linux 的日期和时间:简单的命令 去学习 Linux 上管理时间的各种方法。</p>
<p>
<span><strong>检查当前设置</strong></span></p>
<p>
NTP —— 网络时间协议,它是保持计算机正确时间的老式方法。ntpd 是 NTP 守护程序,它通过周期性地查询公共时间服务器来按需调整你的计算机时间。它是一个简单的、轻量级的协议,使用它的基本功能时设置非常容易。systemd 通过使用 <code>systemd-timesyncd.service</code> 已经越俎代庖地 “干了 NTP 的活”,它可以用作 ntpd 的客户端。</p>
<p>
在我们开始与 NTP “打交道” 之前,先花一些时间来了检查一下当前的时间设置是否正确。</p>
<p>
你的系统上(至少)有两个时钟:系统时间 —— 它由 Linux 内核管理,第二个是你的主板上的硬件时钟,它也称为实时时钟(RTC)。当你进入系统的 BIOS 时,你可以看到你的硬件时钟的时间,你也可以去改变它的设置。当你安装一个新的 Linux 时,在一些图形化的时间管理器中,你会被询问是否设置你的 RTC 为 UTC(世界标准时间Coordinated Universal Time)时区,因为所有的时区和夏令时都是基于 UTC 的。</p>
<p>
你可以使用 hwclock 命令去检查:</p>
<div class="jb51code">
<div>
<div class="syntaxhighlighterbash" id="highlighter_148502">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
<div class="line number8 index7 alt1">
8</div>
<div class="line number9 index8 alt2">
9</div>
<div class="line number10 index9 alt1">
10</div>
<div class="line number11 index10 alt2">
11</div>
<div class="line number12 index11 alt1">
12</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="bash plain">$ </code><code class="bash functions">sudo</code> <code class="bash plain">hwclock --debug</code>
</div>
<div class="line number2 index1 alt1">
<code class="bash plain">hwclock from util-linux 2.27.1</code>
</div>
<div class="line number3 index2 alt2">
<code class="bash plain">Using the </code><code class="bash plain">/dev</code> <code class="bash plain">interface to the clock.</code>
</div>
<div class="line number4 index3 alt1">
<code class="bash plain">Hardware clock is on UTC </code><code class="bash functions">time</code>
</div>
<div class="line number5 index4 alt2">
<code class="bash plain">Assuming hardware clock is kept </code><code class="bash keyword">in</code> <code class="bash plain">UTC </code><code class="bash functions">time</code><code class="bash plain">.</code>
</div>
<div class="line number6 index5 alt1">
<code class="bash plain">Waiting </code><code class="bash keyword">for</code> <code class="bash plain">clock tick...</code>
</div>
<div class="line number7 index6 alt2">
<code class="bash plain">...got clock tick</code>
</div>
<div class="line number8 index7 alt1">
<code class="bash plain">Time </code><code class="bash functions">read</code> <code class="bash plain">from Hardware Clock: 2018</code><code class="bash plain">/01/22</code> <code class="bash plain">22:14:31</code>
</div>
<div class="line number9 index8 alt2">
<code class="bash plain">Hw clock </code><code class="bash functions">time</code> <code class="bash plain">: 2018</code><code class="bash plain">/01/22</code> <code class="bash plain">22:14:31 = 1516659271 seconds since 1969</code>
</div>
<div class="line number10 index9 alt1">
<code class="bash plain">Time since last adjustment is 1516659271 seconds</code>
</div>
<div class="line number11 index10 alt2">
<code class="bash plain">Calculated Hardware Clock drift is 0.000000 seconds</code>
</div>
<div class="line number12 index11 alt1">
<code class="bash plain">Mon 22 Jan 2018 02:14:30 PM PST .202760 seconds</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
Hardware clock is on UTC time 表明了你的计算机的 RTC 是使用 UTC 时间的,虽然它把该时间转换为你的本地时间。如果它被设置为本地时间,它将显示 Hardware clock is on local time。</p>
<p>
你应该有一个 /etc/adjtime 文件。如果没有的话,使用如下命令同步你的 RTC 为系统时间,</p>
<div class="jb51code">
<div>
<div class="syntaxhighlighterbash" id="highlighter_460527">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="bash plain">$ </code><code class="bash functions">sudo</code> <code class="bash plain">hwclock -w</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
这个命令将生成该文件,内容看起来类似如下:</p>
<div class="jb51code">
<div>
<div class="syntaxhighlighterbash" id="highlighter_106170">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="bash plain">$ </code><code class="bash functions">cat</code> <code class="bash plain">/etc/adjtime</code>
</div>
<div class="line number2 index1 alt1">
<code class="bash plain">0.000000 1516661953 0.000000</code>
</div>
<div class="line number3 index2 alt2">
<code class="bash plain">1516661953</code>
</div>
<div class="line number4 index3 alt1">
<code class="bash plain">UTC</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
新发明的 systemd 方式是去运行 timedatectl 命令,运行它不需要 root 权限:</p>
<div class="jb51code">
<div>
<div class="syntaxhighlighterbash" id="highlighter_121461">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
<div class="line number8 index7 alt1">
8</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="bash plain">$ timedatectl</code>
</div>
<div class="line number2 index1 alt1">
<code class="bash spaces"> </code><code class="bash plain">Local </code><code class="bash functions">time</code><code class="bash plain">: Mon 2018-01-22 14:17:51 PST</code>
</div>
<div class="line number3 index2 alt2">
<code class="bash spaces"> </code><code class="bash plain">Universal </code><code class="bash functions">time</code><code class="bash plain">: Mon 2018-01-22 22:17:51 UTC</code>
</div>
<div class="line number4 index3 alt1">
<code class="bash spaces"> </code><code class="bash plain">RTC </code><code class="bash functions">time</code><code class="bash plain">: Mon 2018-01-22 22:17:51</code>
</div>
<div class="line number5 index4 alt2">
<code class="bash spaces"> </code><code class="bash plain">Time zone: America</code><code class="bash plain">/Los_Angeles</code> <code class="bash plain">(PST, -0800)</code>
</div>
<div class="line number6 index5 alt1">
<code class="bash spaces"> </code><code class="bash plain">Network </code><code class="bash functions">time</code> <code class="bash plain">on: </code><code class="bash functions">yes</code>
</div>
<div class="line number7 index6 alt2">
<code class="bash plain">NTP synchronized: </code><code class="bash functions">yes</code>
</div>
<div class="line number8 index7 alt1">
<code class="bash spaces"> </code><code class="bash plain">RTC </code><code class="bash keyword">in</code> <code class="bash functions">local</code> <code class="bash plain">TZ: no</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
RTC in local TZ: no 表明它使用 UTC 时间。那么怎么改成使用本地时间?这里有许多种方法可以做到。最简单的方法是使用一个图形配置工具,比如像 openSUSE 中的 YaST。你也可使用 timedatectl:</p>
<div class="jb51code">
<div>
<div class="syntaxhighlighterbash" id="highlighter_786901">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="bash plain">$ timedatectl </code><code class="bash functions">set</code><code class="bash plain">-</code><code class="bash functions">local</code><code class="bash plain">-rtc 0</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
或者编辑 /etc/adjtime,将 UTC 替换为 LOCAL。</p>
<p>
<span><strong>systemd-timesyncd 客户端</strong></span></p>
<p>
现在,我已经累了,但是我们刚到非常精彩的部分。谁能想到计时如此复杂?我们甚至还没有了解到它的皮毛;阅读 man 8 hwclock 去了解你的计算机如何保持时间的详细内容。</p>
<p>
systemd 提供了 <code>systemd-timesyncd.service </code>客户端,它可以查询远程时间服务器并调整你的本地系统时间。在 <code>/etc/systemd/timesyncd.conf </code>中配置你的(时间)服务器。大多数 Linux 发行版都提供了一个默认配置,它指向他们维护的时间服务器上,比如,以下是 Fedora 的:</p>
<div class="jb51code">
<div>
<div class="syntaxhighlighterbash" id="highlighter_480105">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="bash plain"></code>
</div>
<div class="line number2 index1 alt1">
<code class="bash comments">#NTP=</code>
</div>
<div class="line number3 index2 alt2">
<code class="bash comments">#FallbackNTP=0.fedora.pool.ntp.org 1.fedora.pool.ntp.org</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
你可以输入你希望使用的其它时间服务器,比如你自己的本地 NTP 服务器,在 NTP= 行上输入一个以空格分隔的服务器列表。(别忘了取消这一行的注释)NTP= 行上的任何内容都将覆盖掉 FallbackNTP 行上的配置项。</p>
<p>
如果你不想使用 systemd 呢?那么,你将需要 NTP 就行。</p>
<p>
<span><strong>配置 NTP 服务器和客户端</strong></span></p>
<p>
配置你自己的局域网 NTP 服务器是一个非常好的实践,这样你的网内计算机就不需要不停查询公共 NTP 服务器。在大多数 Linux 上的 NTP 都来自 ntp 包,它们大多都提供 /etc/ntp.conf 文件去配置时间服务器。查阅 NTP 时间服务器池 去找到你所在的区域的合适的 NTP 服务器池。然后在你的 /etc/ntp.conf 中输入 4 - 5 个服务器,每个服务器用单独的一行:</p>
<div class="jb51code">
<div>
<div class="syntaxhighlighterbash" id="highlighter_365436">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="bash plain">driftfile </code><code class="bash plain">/var/ntp</code><code class="bash plain">.drift</code>
</div>
<div class="line number2 index1 alt1">
<code class="bash plain">logfile </code><code class="bash plain">/var/log/ntp</code><code class="bash plain">.log</code>
</div>
<div class="line number3 index2 alt2">
<code class="bash plain">server 0.europe.pool.ntp.org</code>
</div>
<div class="line number4 index3 alt1">
<code class="bash plain">server 1.europe.pool.ntp.org</code>
</div>
<div class="line number5 index4 alt2">
<code class="bash plain">server 2.europe.pool.ntp.org</code>
</div>
<div class="line number6 index5 alt1">
<code class="bash plain">server 3.europe.pool.ntp.org</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
driftfile 告诉 ntpd 它需要保存用于启动时使用时间服务器快速同步你的系统时钟的信息。而日志也将保存在他们自己指定的目录中,而不是转储到 syslog 中。如果你的 Linux 发行版默认提供了这些文件,请使用它们。</p>
<p>
现在去启动守护程序;在大多数主流的 Linux 中它的命令是 <code>sudo systemctl start ntpd</code>。让它运行几分钟之后,我们再次去检查它的状态:</p>
<div class="jb51code">
<div>
<div class="syntaxhighlighterbash" id="highlighter_692419">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="bash plain">$ ntpq -p</code>
</div>
<div class="line number2 index1 alt1">
<code class="bash spaces"> </code><code class="bash plain">remote refid st t when poll reach delay offset jitter</code>
</div>
<div class="line number3 index2 alt2">
<code class="bash plain">==============================================================</code>
</div>
<div class="line number4 index3 alt1">
<code class="bash plain">+dev.smatwebdesi 192.168.194.89 3 u 25 64 37 92.456 -6.395 18.530</code>
</div>
<div class="line number5 index4 alt2">
<code class="bash plain">*chl.la 127.67.113.92 2 u 23 64 37 75.175 8.820 8.230</code>
</div>
<div class="line number6 index5 alt1">
<code class="bash plain">+four0.fairy.mat 35.73.197.144 2 u 22 64 37 116.272 -10.033 40.151</code>
</div>
<div class="line number7 index6 alt2">
<code class="bash plain">-195.21.152.161 195.66.241.2 2 u 27 64 37 107.559 1.822 27.346</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
我不知道这些内容是什么意思,但重要的是,你的守护程序已经与时间服务器开始对话了,而这正是我们所需要的。你可以去运行 <code>sudo systemctl enable ntpd </code>命令,永久启用它。如果你的 Linux 没有使用 systemd,那么,给你留下的家庭作业就是找出如何去运行 ntpd。</p>
<p>
现在,你可以在你的局域网中的其它计算机上设置 systemd-timesyncd,这样它们就可以使用你的本地 NTP 服务器了,或者,在它们上面安装 NTP,然后在它们的 <code>/etc/ntp.conf </code>上输入你的本地 NTP 服务器。</p>
<p>
NTP 服务器会受到攻击,而且需求在不断增加。你可以通过运行你自己的公共 NTP 服务器来提供帮助。下周我们将学习如何运行你自己的公共服务器。</p>
<p>
<span><strong>总结</strong></span></p>
<p>
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。</p>
<p>
原文链接:https://linux.cn/article-9462-1.html</p>
頁:
[1]