在不知道产品中使用的NTP客户端的情况下,如何查看系统时间是否与NTP服务器同步?我正在开发一个可以在容器或独立系统中运行的应用程序。我的应用程序要求在尝试执行某些操作之前确保系统时间同步。但是,即使在主机操作系统中使用了一个或另一个 NTP 客户端,也不能保证 NTP/chrony 包的可用性在容器中可用。
所以我正在寻找一种统一的方式来知道系统时间是否同步?
在不知道产品中使用的NTP客户端的情况下,如何查看系统时间是否与NTP服务器同步?我正在开发一个可以在容器或独立系统中运行的应用程序。我的应用程序要求在尝试执行某些操作之前确保系统时间同步。但是,即使在主机操作系统中使用了一个或另一个 NTP 客户端,也不能保证 NTP/chrony 包的可用性在容器中可用。
所以我正在寻找一种统一的方式来知道系统时间是否同步?
通用计算上的应用程序无法在所有情况下都知道时间同步在它们运行的主机上是如何工作的。在容器中,您看不到也无法连接到主机上运行的 chronyd 或 ntpd,但这可以很好地保持时间。或者依赖主机时间同步的 VM 来宾,也不可见。进一步使一般答案变得困难,NTP 实现比您想象的要多:chrony、ntp、ntpsec、openntpd、w32tm。
通常记录正确时间的重要性就足够了。
在某些平台上,对 ntpd 启动的依赖是相对简单的。在 RHEL 上,等待时间同步
systemctl enable chrony-wait
并添加到您的 systemd 单元然而,有些应用程序具有严格的时间要求。我能想到的最苛刻的是时间戳权威,其中一个索赔标准要求不到一秒的偏移量,否则什么也不能签发。这种激进的响应意味着应用程序会进行自己的时间检查。
也许捆绑一个 SNTP 客户端,它检查应用程序中的 NTP 偏移量,与可配置的 NTP 服务器。无法检查 ntpd 是否正常运行,但无论时间同步如何对主机起作用,都可以检查偏移量。
有两种方法可以做到这一点。
如果您正在运行的容器具有完整的 systemd 实现,那么
timedatectl
程序可以通知您主机是否已同步。内部管理的方式是通过与
systemd-timedated
守护进程对话的 dbus。它正在执行一个系统调用:adjtimex
从中可以获取数据,指示正在完成的内核中调整的当前状态(如果有的话)。因此,在没有完整实现的情况下自己执行此操作的第二种方法是使用
adjtimex()
系统调用。内核不希望在时间报告中出现时间跳跃(或者更糟糕的是,时间倒退),因为它实现了时间偏差,在几个小时的过程中会纠正系统时间(完成每秒增加或延迟几毫秒,直到调整完成)。
adjtimex
NTP 系统通常使用系统调用来更改时钟面临的当前偏差,以使其与真正的时钟源正确同步——但它也可用于获取时钟源偏差的当前状态。因此,它使您能够窥探内核关于正在执行什么同步的想法(如果有的话)。手册页
adjtimex
提供了一些与您所要求的内容相关的有趣部分:和
因此,如果您没有完全成熟的容器,仍然可以获取这些数据。我写了一个简单的程序,它将通过
adjtimex
C 获取内核倾斜的状态。例如,您可以编译它gcc -o timex timex.c
在未同步的系统上运行:
在未同步的同一主机上的容器中运行:
在主机系统中设置要同步的时间:
在同一主机上的容器中执行相同的编程检查:
我尚未测试的时间命名空间可能存在一些问题(尽管它们确实非常新),以查看它们
adjtimex
在单独的上下文中是否不同或尊重(请参阅man 7 time_namespaces
),但从我读过的内容来看,它可能仍然可以工作 - - 我会留给你决定。没有。
设置正确的运行环境不是应用程序的责任,这取决于系统及其管理员。
应用程序依赖于系统返回的日期/时间。那个时间是“正确”还是“错误”;应用程序通常无法知道这一点。它只会使用该系统日期/时间。
如果您有一个客户端-服务器模型,那么当交易因为(极端)日期/时间偏移而被拒绝时提供有用的错误消息会很好。
请注意,这种偏移的存在并不能告诉您客户端是在错误的时钟上,还是在服务器上,或两者兼而有之。