首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在不知道产品中使用的NTP客户端的情况下,检查系统时间是否同步到ntp服务器?

如何在不知道产品中使用的NTP客户端的情况下,检查系统时间是否同步到ntp服务器?
EN

Server Fault用户
提问于 2021-09-15 05:16:47
回答 3查看 1.7K关注 0票数 2

如何在不知道产品中使用的NTP客户端的情况下检查系统时间是否同步到NTP服务器?我正在开发一个在容器或独立系统中运行的应用程序。我的应用程序需要确保系统时间在尝试执行某些操作之前是同步的。但是,即使主机操作系统中使用了一个或另一个NTP客户端,也无法保证NTP/chrony包的可用性在容器中可用。

所以我在寻找一种统一的方法来知道系统时间是否是同步的?

EN

回答 3

Server Fault用户

回答已采纳

发布于 2021-09-15 17:12:22

通用计算机上的应用程序不可能在所有情况下都知道时间同步在运行它们的主机上是如何工作的。在容器中,您看不到并且无法连接到主机上运行的chronyd或ntpd,但这会使时间保持得很好。或者依赖于主机时间同步的VM客户机,也不可见。更难回答的是,有更多的ntp实现比您想象的要多: chrony、NTP、ntpsec、openntpd、w32tm。

通常,记录正确时间的重要性就足够了。

在一些平台上,对ntpd启动的依赖是相对直接的。在RHEL上,添加到等待时间同步 systemctl enable chrony-wait并添加到系统单元中

代码语言:javascript
运行
复制
After=time-sync.target
Requires=time-sync.target

然而,有些应用程序有严格的时间要求。我能想到的最苛刻的是时间戳当局,其中一种索赔标准要求不到1秒的抵消量,否则什么也不能发出。。响应的这种侵略性意味着应用程序会进行自己的时间检查。

也许将一个SNTP客户端捆绑在可配置的NTP服务器上,该客户机检查应用程序中的NTP偏移量。无法检查是否有正确的ntpd运行,但无论时间同步到主机的工作方式如何,都可以检查偏移量。

票数 2
EN

Server Fault用户

发布于 2021-09-15 08:24:13

有两种方法可以做到这一点。

如果正在运行的容器具有完整的systemd实现,那么timedatectl程序可以通知您主机是否同步。

内部管理的方式是通过dbus进行管理,dbus可以与systemd-timedated守护进程对话。它所做的是完成一个系统调用:adjtimex,它可以从其中获取数据,指示正在执行的内核(如果有的话)的当前调整状态。

因此,不需要完全实现的第二种方法是使用adjtimex()系统调用。

内核不希望在报告时间(或者更糟的是,向后移动的时间)中跳转时间,因为它在这样的时间内实现了一个偏斜,在几个小时的过程中,它将纠正一个系统时间(通过添加或延迟几毫秒每秒直到调整完成)。

NTP系统通常使用adjtimex系统来改变时钟所面临的当前偏斜,以使其与真正的时钟源正确同步--但它也可用于获取时钟源倾斜的当前状态。因此,它使您能够窥探内核的想法,什么是同步正在进行(如果有的话)。

adjtimex的手册页面提供了一些与您所要求的内容相关的有趣部分:

代码语言:javascript
运行
复制
       The  buf.status  field  is a bit mask that is used to set and/or retrieve status bits associated with the NTP implementation.  Some bits in the mask
       are both readable and settable, while others are read-only.
...
       STA_UNSYNC (read-write)
              Clock unsynchronized.

代码语言:javascript
运行
复制
RETURN VALUE
       On success, adjtimex() and ntp_adjtime() return the clock state; that is, one of the following values:
...
       TIME_ERROR  The system clock is not synchronized to a reliable server.  This value is returned when any of the following holds true:

                   *  Either STA_UNSYNC or STA_CLOCKERR is set.

                   *  STA_PPSSIGNAL is clear and either STA_PPSFREQ or STA_PPSTIME is set.

                   *  STA_PPSTIME and STA_PPSJITTER are both set.

                   *  STA_PPSFREQ is set and either STA_PPSWANDER or STA_PPSJITTER is set.

                   The symbolic name TIME_BAD is a synonym for TIME_ERROR, provided for backward compatibility.

因此,如果您没有一个完全成熟的容器,那么仍然有可能获得这些数据。我编写了一个简单的程序,它将通过C中的adjtimex获取内核的状态。您可以编译它,例如gcc -o timex timex.c

代码语言:javascript
运行
复制
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#include <sys/timex.h>

/* Written for https://serverfault.com/questions/1077601/how-to-check-whether-the-system-time-is-synchronised-to-ntp-server-without-knowi */

void test_status(
    int st) 
{
  if (st & STA_PLL)
    printf("Phase locked loop\n");
  if (st & STA_PPSFREQ)
    printf("Pulse per second frequency discipline\n");
  if (st & STA_FLL)
    printf("PPS Time discipline\n");
  if (st & STA_INS)
    printf("Insert leap second and end-of-day\n");
  if (st & STA_DEL)
    printf("Delete leap second and end-of-day\n");
  if (st & STA_UNSYNC)
    printf("Clock is not syncronized\n");
  if (st & STA_FREQHOLD)
    printf("Hold frequency\n");
  if (st & STA_PPSSIGNAL)
    printf("Valid PPS signal is present\n");
  if (st & STA_PPSJITTER)
    printf("PPS signal jitter exceeded\n");
  if (st & STA_PPSWANDER)
    printf("PPS Signal wander exceeded\n");
  if (st & STA_PPSERROR)
    printf("PPS signal calibration error\n");
  if (st & STA_CLOCKERR)
    printf("Clock hardware fault\n");

  if (st & STA_NANO)
    printf("Nanosecond resolution\n");
  else
    printf("Microsecond resolution\n");

  if (st & STA_MODE)
    printf("Frequency locked loop\n");
  else
    printf("Phase locked loop\n");
}

int main() {
  struct timex tx = {};
  tx.modes = ADJ_OFFSET_SS_READ;
  int err = adjtimex(&tx);

  switch(err) {
    case -1:
      printf("Time error: %s\n", strerror(errno));
    break;

    case TIME_WAIT:
      printf("Leap second insert/delete completed\n");
    break;

    case TIME_INS:
      printf("Leap second to be added next UTC day\n");
    break;

    case TIME_DEL:
      printf("Leap second to be deleted next UTC day\n");
    break;

    case TIME_OOP:
      printf("Leap second insertion in progress\n");
    break;

    case TIME_ERROR:
      printf("Error getting time\n");
    break;

    case TIME_OK:
      printf("Time OK\n");
    break;

    default:
      printf("Time default: %x (%d)\n", err, err);
    break;
  }

  test_status(tx.status);
  exit(0);
}

运行在不同步的系统上:

代码语言:javascript
运行
复制
$ ./timex 
Error getting time
Clock is not syncronized
Microsecond resolution
Phase locked loop

在未同步的同一主机上运行的容器中:

代码语言:javascript
运行
复制
# podman run -v /tmp/timex/timex:/timex  docker.io/gammabytehosting/rockylinux /timex
Error getting time
Clock is not syncronized
Microsecond resolution
Phase locked loop

将主机系统中要同步的时间设置为:

代码语言:javascript
运行
复制
# systemctl start chronyd
# chronyc sources
210 Number of sources = 9
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^* _gateway            2   6     7     1  +5568ns[ -720ms] +/-   32ms
# ./timex 
Time OK
Microsecond resolution
Phase locked loop

在同一主机上的容器中执行相同的编程检查:

代码语言:javascript
运行
复制
# podman run -v /tmp/timex/timex:/timex  docker.io/gammabytehosting/rockylinux /timex
Time OK
Microsecond resolution
Phase locked loop

时间命名空间可能存在一些问题,我还没有对它们进行测试(虽然它们确实是非常新的),看看它们在单独的上下文中是否不同或是否支持adjtimex (请参阅man 7 time_namespaces),但从我所读到的可能仍然有效的内容来看--让您来确定。

票数 1
EN

Server Fault用户

发布于 2021-09-15 07:20:20

如何检查系统时间是否与NTP服务器同步?

没有。

我的应用程序需要确保系统时间在尝试执行某些操作之前是同步的。

应用程序没有责任设置要运行的正确环境,这取决于系统及其管理员。

应用程序依赖于系统返回的日期/时间。无论时间是“正确的”还是“错误的”,应用程序一般都无法知道这一点。它将简单地使用该系统日期/时间。

如果您有一个客户机-服务器模型,那么每当事务由于(极端)日期/时间偏移而被拒绝时,都会提供有用的错误消息。

请注意,这种设置的存在并不能告诉您客户端是否位于不正确的时钟上,或者服务器上,或者两者都有。

票数 -1
EN
页面原文内容由Server Fault提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://serverfault.com/questions/1077601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档