如何在 (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 服务守护程序来启动系统。