在RHEL/CentOS Linux 中如何使NTP在启动时同步?

如何在 (RHEL 7/CentOS 7) Linux 中配置 NTP 客户端以在系统启动(引导)期间与 NTP 服务器同步?

在设置使用 NTP 服务器时,我意识到在 Red Hat Enterprise Linux 中,当我们为 NTPD 或者 chronyd 重新启动服务时,本地时间不会立即与 NTP 服务器同步,并且需要一端时间才能同步本地时钟

所以我们必须使用 ntpdate 手动将时钟与 NTP 服务器同步

但是,如果服务器重启时,日期和时间是错误的怎么办?

让我们进行测试:

首先更改日期

server2:~ # date --set "01 Jan 2015"
Mon Jan  1 00:00:00 IST 2015

记录一条消息以了解重新启动的时间

server2:~ # logger rebooting

NTP 服务器配置正确并已启用

server2:~ # systemctl is-enabled ntpd
enabled

接下来重新启动Knife 片服务器以查看它是否需要新的日期和时间

server2:~ # reboot
PolicyKit daemon disconnected from the bus.
We are no longer a registered authentication agent.

从我们在关机阶段看到的系统日志中,日志存储的时间错误

Jan  1 00:00:05 server2 jack: rebooting
Jan  1 00:00:21 server2 systemd: Stopped Dump dmesg to /var/log/dmesg.
Jan  1 00:00:21 server2 systemd: Stopping Dump dmesg to /var/log/dmesg...

幸运的是,我们的 hwclock 具有正确的日期和时间,因此一旦系统启动,它就有了正确的时间

Jan  1 00:00:21 server2 systemd: Stopping custom security scripts at start-up...
Jan  1 00:00:21 server2 systemd: Stopping OpenSSH server daemon...
Jan  1 00:00:21 server2 systemd: Stopping (null)...
Nov 20 15:34:50 server2 kernel: microcode: microcode updated early to revision 0x3a, date = 2015-01-30
Nov 20 15:34:50 server2 kernel: Initializing cgroup subsys cpuset
Nov 20 15:34:50 server2 kernel: Initializing cgroup subsys cpu
Nov 20 15:34:50 server2 kernel: Initializing cgroup subsys cpuacct

因此,让我们更改 hwclock 的日期和时间

server2:~ # hwclock --set --date  "01 jan 2015"
server2:~ # hwclock ;date
Mon 01 Jan 2015 12:00:14 AM IST  -0.547321 seconds
Tue Nov 20 15:41:16 IST 2015
server2:~ # logger rebooting again
server2:~ # reboot

从我们的系统日志中,我们看到节点在适当的时间关闭,因为我们的日期时间正确(只有 hwclock 被更改)

Nov 20 15:41:07 server2 jack: rebooting again
Nov 20 15:41:17 server2 systemd: Stopping custom firewall configuration using iptables...
Nov 20 15:41:17 server2 systemd: Unmounting RPC Pipe File System...
Nov 20 15:41:17 server2 systemd: Stopping system-systemdx2dfsck.slice.
Nov 20 15:41:17 server2 systemd: Stopped Stop Read-Ahead Data Collection 10s After Complete

接下来再次当我们看到系统尝试启动时,hwclock 时间用于记录目的,在我们的情况下,在重新启动之前设置不正确

Nov 20 15:41:17 server2 systemd: Stopping Pro-active monitoring utility for unix systems...
Nov 20 15:41:17 server2 systemd: Stopping LSB: LinuxICCM Scanner...
Nov 20 15:41:17 server2 systemd: Stopping Self Monitoring and Reporting Technology (SMART) Daemon...
Jan  1 00:02:57 server2 journal: Runtime journal is using 8.0M (max allowed 4.0G, trying to leave 4.0G free of 62.8G available â current limit 4.0G).
Jan  1 00:02:57 server2 kernel: microcode: microcode updated early to revision 0x3a, date = 2015-01-30
Jan  1 00:02:57 server2 kernel: Initializing cgroup subsys cpuset
Jan  1 00:02:57 server2 kernel: Initializing cgroup subsys cpu
Jan  1 00:02:57 server2 kernel: Initializing cgroup subsys cpuacct

但是NTPD永远不会将本地时钟日期和时间与NTP服务器同步,直到我们的节点完全启动
几分钟后节点启动后,我观察到本地时间与 NTP 同步

Jan  1 00:04:04 server2 rsyslogd: action 'action 0' resumed (module 'builtin:ompipe') [v8.24.0 try http://www.rsyslog.com/e/2359 ]
Jan  1 00:04:04 server2 rsyslogd: action 'action 0' resumed (module 'builtin:ompipe') [v8.24.0 try http://www.rsyslog.com/e/2359 ]
Jan  1 00:04:04 server2 systemd: Started Stop Read-Ahead Data Collection.
Nov 20 15:47:32 server2 systemd: Time has been changed
Nov 20 15:47:32 server2 rsyslogd: imjournal: journal reloaded... [v8.24.0 try http://www.rsyslog.com/e/0 ]
Nov 20 15:48:19 server2 su: (to root) jack on pts/0

所以你看到NTPD在这方面真的很慢而且不是很好。

但实际上我们在 NTPD 中几乎没有可以用来调整这种行为的选项

我们可以使用 ntpdate 在 NTPD 启动之前使用 NTP 服务器强制同步本地时钟
在 Red Hat 7 中,我们有以下 ntpdate.service 的单元文件

# systemctl cat ntpdate
# /usr/lib/systemd/system/ntpdate.service
[Unit]
Description=Set time via NTP
After=syslog.target network.target nss-lookup.target
Before=time-sync.target
Wants=time-sync.target
[Service]
Type=oneshot
ExecStart=/usr/libexec/ntpdate-wrapper
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target

默认情况下禁用此服务,因此启用此服务

# systemctl enable ntpdate.service
Created symlink from /etc/systemd/system/multi-user.target.wants/ntpdate.service to /usr/lib/systemd/system/ntpdate.service.

接下来修改 ntpdate 将在 /etc/ntp/step-tickers 中同步的 NTP 服务器

server2:~ # cat /etc/ntp/step-tickers
# List of NTP servers used by the ntpdate service.
192.168.1.100

接下来让我们再次更改 hwclock 日期和时间

server2:~ # hwclock --set --date  "01 jan 2015"

添加记录器消息以监视日志

server2:~ # logger "rebooting to test ntpdate"

最后重启Knife 片服务器

server2:~ # reboot

现在让我们在节点启动后监控我们的系统日志
这里节点重新启动

Nov 20 15:54:03 server2 jack: rebooting to test ntpdate
Nov 20 15:54:06 server2 systemd: Stopping custom firewall configuration using iptables...

这里我的系统开始启动

Nov 20 15:54:06 server2 systemd: Stopping Serial Getty on ttyS0...
Nov 20 15:54:06 server2 systemd: Stopping Getty on tty1...
Jan  1 00:02:56 server2 journal: Runtime journal is using 8.0M (max allowed 4.0G, trying to leave 4.0G free of 62.8G available â current limit 4.0G).
Jan  1 00:02:56 server2 kernel: microcode: microcode updated early to revision 0x3a, date = 2015-01-30
Jan  1 00:02:56 server2 kernel: Initializing cgroup subsys cpuset
Jan  1 00:02:56 server2 kernel: Initializing cgroup subsys cpu
Jan  1 00:02:56 server2 kernel: Initializing cgroup subsys cpuacct

现在,由于我们启用了 ntpdate 服务,我观察到在系统启动期间 ntpdate 与 NTP 服务器强制同步

Jan  1 00:03:16 server2 hp-ams[2476]: amsHelper Started . .
Jan  1 00:03:16 server2 systemd: Started HP Agentless Management Service daemon.
Jan  1 00:03:16 server2 cntdb.security: - Setup B&R chain ...
Nov 20 15:57:11 server2 systemd: Time has been changed
Nov 20 15:57:11 server2 ntpdate[2612]: step time server 192.168.1.100 offset 4377234.731233 sec
Nov 20 15:57:11 server2 systemd: Started Set time via NTP.

但是我又不喜欢这种依赖性,我的期望是从 hwclock 记录的第一条消息必须是正确的,因此我们必须确保在系统停机之前 hwclock 与本地时钟同步

重要说明:在 Red Hat Enterprise 7 中,当系统时钟由网络时间协议 (NTP) 或者精确时间协议 (PTP) 同步时,内核会每 11 分钟自动将硬件时钟与系统时钟同步一次。

但是仍然考虑到最坏的情况,系统时钟没有正确设置 hwclock 并且系统以错误的 hwclock 时间重新启动?

我对此的解决方案是创建一个 systemd 单元文件,该文件将在关闭之前和启动期间调用以确保

  • 第一个本地时间与 NTP 服务器同步
  • 然后 hwclock 与本地时钟同步

因此,在重新启动期间,我们的节点将始终提供适当的时间

server1:~ # systemctl cat set_my_clock.service
# /usr/lib/systemd/system/set_my_clock.service
[Unit]
Description=Syncing system and hardware clock
[Service]
Type=oneshot
ExecStart=/etc/init.d/set_my_clock start
ExecStop=/etc/init.d/set_my_clock stop
RemainAfterExit=true
[Install]
WantedBy=basic.target

注意:我们也可以在“/etc/systemd/system”下创建此文件,因为这是 Red Hat 推荐的位置

接下来创建将完成工作的主脚本
注意:我已启用调试以监视重新启动期间的执行情况,我们可以删除 set -x

# cat /etc/init.d/set_my_clock
#!/bin/bash
set -x
case "" in
  start|stop)
    echo "Set Sys time according to Hardware Clock";
 # This will force sync the local system clock with NTP server
    /sbin/ntpdate -u 192.168.1.00 192.168.1.101;

 # This will sync our hwclock with the system clock time
    /sbin/hwclock --systohc;
    ;;
   *)
         echo "Usage: 
# systemctl enable set_my_clock.service
{start|stop}" exit 1 ;; esac echo "done !" exit 0

启用此脚本

server1 # hwclock --set --date "05 Nov 2015"

是时候验证我们的修复了
让我们更改 hwclock 的日期和时间

server1 # date --set "01 Jan 2015"
Mon Jan  1 00:00:00 IST 2015
server1:~ # logger rebooting

让我们有一个记录器消息来监视日志

server1:~ # reboot

重启服务器

Jan  1 00:00:13 server1 jack: rebooting
Jan  1 00:00:15 server1 systemd: Stopping Availability of block devices...
Jan  1 00:00:15 server1 systemd: Stopped Stop Read-Ahead Data Collection 10s After Completed Startup.

这里开始关机

Jan  1 00:00:15 server1 set_my_clock: + case "" in
Jan  1 00:00:15 server1 set_my_clock: + echo 'Set Sys time according to Hardware Clock'
Jan  1 00:00:15 server1 set_my_clock: Set Sys time according to Hardware Clock
Jan  1 00:00:15 server1 set_my_clock: + /sbin/ntpdate -u 192.168.1.100 192.168.1.101

我们的脚本在系统关闭期间正确执行,但如我们所见,它无法更改系统日志的当前时间

Nov 20 16:41:54 server1 kernel: Initializing cgroup subsys cpuset
Nov 20 16:41:54 server1 kernel: Initializing cgroup subsys cpu
Nov 20 16:41:54 server1 kernel: Initializing cgroup subsys cpuacct

虽然系统提供了正确的时间,所以我们知道我们的 hwclock 与上面的系统时钟正确同步

Nov 20 16:42:02 server1 systemd: Starting Syncing system and hardware clock...
Nov 20 16:42:02 server1 set_my_clock: + case "" in
Nov 20 16:42:02 server1 set_my_clock: + echo 'Set Sys time according to Hardware Clock'
Nov 20 16:42:02 server1 set_my_clock: Set Sys time according to Hardware Clock
Nov 20 16:42:02 server1 set_my_clock: + /sbin/ntpdate -u 192.168.1.100 192.168.1.101
Nov 20 16:42:02 server1 set_my_clock: 20 Nov 16:42:02 ntpdate[1118]: no servers can be used, exiting
Nov 20 16:42:02 server1 set_my_clock: + /sbin/hwclock --systohc

再次在启动期间

##代码##

现在我们的系统将提供正确的日期和时间,我们不需要依赖 NTP 服务守护程序来启动系统。

日期:2020-06-02 22:18:27 来源:oir作者:oir