ntpd 有效吗?

Mar*_*ich 3 ntpd ntp

ntpd在我的机器上运行,但我不确定它是否工作正常。如何查询ntpd确定是否已成功连接到时间服务器以及我的内核时间是否已同步?

Mar*_*ich 6

有几种方法可以确定是否ntpd有效:

  1. 使用ntpq -p(或ntpq -pn通过跳过 DNS 查找来节省时间)。

    这是 NTP 工作时的样子:

    host-a ~ # ntpq -p
         remote           refid      st t when poll reach   delay   offset  jitter
    ==============================================================================
     0.debian.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000
     1.debian.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000
     2.debian.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000
     3.debian.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000
    +mail.masters-of 144.76.76.107    3 u  975 1024  377   13.731   -0.737   2.552
    +ntp2.hetzner.de 124.216.164.14   2 u  232 1024  377   15.914   -0.650   0.854
    +rondra.lf-net.o 237.17.204.95    2 u 1020 1024  377   13.751   -0.557   4.292
    -funky.f5s.de    131.188.3.222    2 u  480 1024  377   15.730    2.082   4.377
    +stratum2-3.NTP. 129.70.137.82    2 u  742 1024  377   19.785   -0.366   7.498
    *mail.klausen.dk 193.79.237.14    2 u  173 1024  377   14.383   -0.513   2.066
    
    Run Code Online (Sandbox Code Playgroud)

    它会列出它所连接的实际对等点;*表示您同步到的源。NTP 文档中提供了有关输出的更多信息。

    这是它没有时的样子:

    host-b ~ # ntpq -p
         remote           refid      st t when poll reach   delay   offset  jitter
    ==============================================================================
     0.debian.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000
     1.debian.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000
     2.debian.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000
     3.debian.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,没有列出任何实际对等点,这通常表明ntpd无法连接到任何对等点,可能是因为防火墙阻止了连接。

    ntpq -p 不太适合脚本检查,因为必须解析输出,虽然它的速度(单个调用 30 毫秒)还不错,但我稍后将讨论更快的方法。

  2. 如果您正在使用systemd,则可以使用timedatectl status.

    这是 NTP 工作时的样子(注意System clock synchronized: yes):

    host-a ~ # timedatectl status 
                   Local time: Do 2021-04-22 13:29:20 CEST
               Universal time: Do 2021-04-22 11:29:20 UTC
                     RTC time: Do 2021-04-22 11:29:21
                    Time zone: Europe/Berlin (CEST, +0200)
    System clock synchronized: yes
                  NTP service: inactive
              RTC in local TZ: no
    
    Run Code Online (Sandbox Code Playgroud)

    这是它不是时的样子(注意System clock synchronized: no):

    host-b ~ # timedatectl status
                   Local time: Do 2021-04-22 13:29:53 CEST
               Universal time: Do 2021-04-22 11:29:53 UTC
                     RTC time: Do 2021-04-22 11:29:42
                    Time zone: Europe/Berlin (CEST, +0200)
    System clock synchronized: no
                  NTP service: inactive
              RTC in local TZ: no
    
    
    Run Code Online (Sandbox Code Playgroud)

    NTP service指的是systemd-timesyncd,systemd自己的 NTP 客户端。安装时它不应运行ntpd,因此no这里是可以预期的。)

    timedatectl statussystemd-timedated仅按需启动的查询,这会导致第一次调用时性能损失约 100 毫秒;进一步调用大约需要 12 毫秒。

    systemd-timedated反过来使用adjtimex(2)系统调用来查询内核;如果adjtimex(2)返回STA_UNSYNC设置了位的状态,则时钟不同步。这意味着它timedatectl实际上不是在与 交谈ntpd,而是查询存储在内核中的位,ntpd当同步状态发生变化时,NTP 服务会更新哪些。

    timedatectl status 非常适合脚本编写,因为您可以直接查询相关属性:

    host-a ~ # timedatectl show -p NTPSynchronized --value                          
    yes
    host-b ~ # timedatectl show -p NTPSynchronized --value
    no
    
    Run Code Online (Sandbox Code Playgroud)
  3. adjtimex(2)直接使用:

    这是对用户最不友好的方法,但却是编写脚本最快的方法。busybox正如 Debian busteradjtimex提供的那样,有一个小程序可以作为adjtimex(2)系统调用的简单包装器。

    这是 NTP 工作时的样子:

    host-a ~ # busybox adjtimex
        mode:         0
    -o  offset:       -570098 us
    -f  freq.adjust:  857283 (65536 = 1ppm)
        maxerror:     478704
        esterror:     302
        status:       8193 (PLL)
    -p  timeconstant: 10
        precision:    1 us
        tolerance:    32768000
    -t  tick:         10000 us
        time.tv_sec:  1619092119
        time.tv_usec: 60467600
        return value: 0 (clock synchronized)
    
    Run Code Online (Sandbox Code Playgroud)

    这是什么样子时,它不是(注意,UNSYNCstatus线路和):

    host-b ~ # busybox adjtimex
        mode:         0
    -o  offset:       0 us
    -f  freq.adjust:  2126708 (65536 = 1ppm)
        maxerror:     16000000
        esterror:     16000000
        status:       16449 (PLL | UNSYNC)
    -p  timeconstant: 7
        precision:    1 us
        tolerance:    32768000
    -t  tick:         10000 us
        time.tv_sec:  1619091984
        time.tv_usec: 307119
        return value: 5 (clock not synchronized)
    
    Run Code Online (Sandbox Code Playgroud)

    不幸的是,busybox adjtimex似乎没有提供只打印某个字段的方法,并且只打印返回值,而不是实际返回。这意味着对于脚本,您将不得不解析输出(例如busybox adjtimex | grep -q UNSYNC)。另一方面,它通过极快的速度弥补了这一点——只有 0.5 毫秒!

  • 请注意,您可以通过为 `systemd-timedated.service` 设置 `SYSTEMD_TIMEDATED_NTP_SERVICES` 环境变量来指定哪个服务 `timedatectl` 视为“NTP 服务:”。例如,如果您将变量设置为`SYSTEMD_TIMEDATED_NTP_SERVICES=chronyd.service:ntpd.service`,那么timedated(以及timedatectl)将查找`chronyd.service`,然后查找`ntpd.service`。旧版本的 systemd 可能不包含此功能。 (2认同)