Other

基于 ntpd / chrony 的 Linux 生产时钟管理

基于 ntpd / chrony 的 Linux 生产时钟管理

1. 概念

如在 CentOS 6 中时间设置有 datehwclock 命令,从 CentOS 7 开始使用了一个新的命令 timedatectl。

  • (1)UTC
    整个地球分为二十四时区,每个时区都有自己的本地时间。在国际无线电通信场合,为了统一起见,使用一个统一的时间,称为通用协调时(UTC, Universal Time Coordinated)。

  • (2)GMT
    格林威治标准时间 (Greenwich Mean Time)指位于英国伦敦郊区的皇家格林尼治天文台的标准时间,因为本初子午线被定义在通过那里的经线。(UTC与GMT时间基本相同,本文中不做区分)

  • (3)CST
    中国标准时间 (China Standard Time)【GMT + 8 = UTC + 8 = CST】

  • (4)DST
    夏令时(Daylight Saving Time) 指在夏天太阳升起的比较早时,将时钟拨快一小时,以提早日光的使用。(中国不使用)

  • 硬件时钟:
    RTC(Real-Time Clock)或CMOS时钟,一般在主板上靠电池供电,服务器断电后也会继续运行。仅保存日期时间数值,无法保存时区和夏令时设置。

  • 系统时钟:
    一般在服务器启动时复制RTC时间,之后独立运行,保存了时间、时区和夏令时设置。

2. 使用 ntpd 同步时钟(CentOS 7.x / 8.x / Ubuntu 20)

2.1 在线安装并同步

yum install ntp
# apt install ntp
systemctl enable ntpd
systemctl start ntpd
  • 手动同步
# 需更新默认 ntp 服务地址列表,否则可能 Connection refused

# 先备份
sudo cp /etc/ntp.conf /etc/ntp.conf.bak

# 删除
sed -i -r "/^server(.+)/d" /etc/ntp.conf

# 追加
sudo cat <<-EOF >>/etc/ntp.conf
server ntp.aliyun.com iburst
server ntp1.aliyun.com iburst
server ntp2.aliyun.com iburst
server ntp3.aliyun.com iburst
server ntp4.aliyun.com iburst
server ntp5.aliyun.com iburst
server ntp6.aliyun.com iburst
server ntp7.aliyun.com iburst
EOF

ntpq -p
  • 使用 timedatectl 设置时间 (CentOS7+ / Ubuntu18+ 通用)
# 更改时区
> timedatectl set-timezone Asia/Shanghai
# 启用ntp同步
> timedatectl set-ntp yes
# 读取时间
> timedatectl  # 等同于 timedatectl status
# 设置时间
> timedatectl set-time "YYYY-MM-DD HH:MM:SS"
# 列出所有时区
> timedatectl list-timezones
# 更改时区
> timedatectl set-timezone Asia/Shanghai
# 或
> ln -sf /usr/share/zoneinfor/Asia/Shanghai /etc/localtime
# 设置是否与NTP服务器同步
> timedatectl set-ntp yes  # yes 或 no
# 将硬件时钟调整为与本地时钟一致
> hwclock --systohc --localtime
# 或
> timedatectl set-local-rtc 1
# 注: 硬件时钟默认使用UTC时间,因为硬件时钟不能保存时区和夏令时调整,修改后就无法从硬件时钟中读取出准确标准时间,因此不建议修改。修改后系统会出现警告.
# 将硬件时间设置成 UTC
> hwclock --systohc --utc 或 timedatectl set-local-rtc 1
# 显示硬件时间:
> hwclock --show
# 设置硬件时间
> hwclock --set --date ‘08/02/2012 12:00:00’
# 将硬件时间同步到系统时间
> hwclock --hctosys
# 强制把系统时间写入CMOS
> clock -w
  • 修改为 24 小时制
# CentOS 7
> tzselect
Asia -> China -> Beijing Time -> Yes
> rm /etc/localtime
> ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

# Ubuntu 20
> cp /etc/default/locale /etc/default/locale.bak

> sudo cat <<-'EOF' > /etc/default/locale
LANG=en_US.UTF-8
LC_TIME=en_UK.UTF-8
EOF

# 注销重登
logout

3. 使用 chrony 同步时钟(CentOS 7.x / 8.x / Ubuntu 20)

上面 timedatectl 命令是一样的

3.1 在线安装

yum install chrony
# apt install chrony
systemctl enable chronyd
systemctl start  chronyd

3.2 离线安装

git clone https://github.com/wl4g-collect/chrony.git
cd chrony
git checkout 4.1
./configure
make && make install
# CentOS 7
sudo curl -OL https://gitee.com/wl4g-collect/chrony/attach_files/854232/download/chrony-4.1-centos7-x86_64.tar

# Ubuntu 20
sudo curl -OL https://gitee.com/wl4g-collect/chrony/attach_files/854232/download/chrony-4.1-ubuntu20-x86_64.tar

sudo tar -xf chrony-*
cp -r chrony-*/bin/chronyc /usr/bin/chronyc
cp -r chrony-*/sbin/chronyd /usr/sbin/chronyd
cp -r chrony-*/libexec/chrony-helper /usr/libexec/chrony-helper
sudo chmod +x /usr/bin/chronyc
sudo chmod +x /usr/sbin/chronyd
sudo chmod +x /usr/libexec/chrony-helper
rm -rf chrony-*

# 验证
chronyc --version
chronyd --version
/usr/libexec/chrony-helper --version

3.3 使用 chrony 为内网集群节点搭建 NTP 服务

IP Host Role Rmark 时间同步方式
10.0.0.120 ntp-server-1 NTP server 从阿里云公网NTP服务器同步时间,同时作为内网 NTP Server,供内网其它服务器请求同步时间 chronyd 服务平滑同步
10.0.0.121 k8s-master-1 NTP client 向内网 NTP Server 10.0.0.120 同步时间 chronyd服务平滑同步
10.0.0.122 k8s-master-2 NTP client 向内网 NTP Server 10.0.0.120 同步时间 chronyd服务平滑同步

...

使用 chronyd 服务平滑同步时间的方式要优于 crontab + ntpdate,因为 ntpdate 同步时间会造成时间的跳跃,对一些依赖时间的程序和服务会造成影响,例如:sleep、timer等,且chronyd服务可以在修正时间的过程中同时修正CPU tick;

  • 运行配置 (chronyd 服务端)

可联通外网的机器,运行 chronyd 作为内网的服务端,接收内网其他节点 chronyc 发起的同步请求,对于客户端节点的配置,只需修改为 server 10.0.0.120 iburst 部分即可

sudo cat <<-'EOF' >/etc/chrony.conf
# 指定使用上游阿里云公网 NTP 服务作为 NTP 时间源
server ntp1.aliyun.com minpoll 4 maxpoll 10 iburst
server ntp1.cloud.aliyuncs.com minpoll 4 maxpoll 10 iburst
server ntp10.cloud.aliyuncs.com minpoll 4 maxpoll 10 iburst
server ntp11.cloud.aliyuncs.com minpoll 4 maxpoll 10 iburst
server ntp12.cloud.aliyuncs.com minpoll 4 maxpoll 10 iburst
server ntp2.aliyun.com minpoll 4 maxpoll 10 iburst
server ntp2.cloud.aliyuncs.com minpoll 4 maxpoll 10 iburst
server ntp3.aliyun.com minpoll 4 maxpoll 10 iburst
server ntp3.cloud.aliyuncs.com minpoll 4 maxpoll 10 iburst
server ntp4.aliyun.com minpoll 4 maxpoll 10 iburst
server ntp4.cloud.aliyuncs.com minpoll 4 maxpoll 10 iburst
server ntp5.aliyun.com minpoll 4 maxpoll 10 iburst
server ntp5.cloud.aliyuncs.com minpoll 4 maxpoll 10 iburst
server ntp6.aliyun.com minpoll 4 maxpoll 10 iburst
server ntp6.cloud.aliyuncs.com minpoll 4 maxpoll 10 iburst
server ntp7.cloud.aliyuncs.com minpoll 4 maxpoll 10 iburst
server ntp8.cloud.aliyuncs.com minpoll 4 maxpoll 10 iburst
server ntp9.cloud.aliyuncs.com minpoll 4 maxpoll 10 iburst
server ntp.aliyun.com minpoll 4 maxpoll 10 iburst
server ntp.cloud.aliyuncs.com minpoll 4 maxpoll 10 iburst
# Ignore stratum in source selection.
# 让 chronyd 在选择源时忽略源的层级
stratumweight 0.05
# Record the rate at which the system clock gains/losses time.
# 记录系统时钟获得/丢失时间的速率至drift文件中
driftfile /var/lib/chrony/drift
# Enable kernel RTC synchronization.
rtcsync
# In first three updates step the system clock instead of slew
# if the adjustment is larger than 10 seconds.
# 如果系统时钟的偏移量大于 10sec,则允许在前三次更新中步进调整系统时钟
makestep 10 3
# 只允许 10.0.0.0/24 网段的客户端进行时间同步
allow 10.0.0.0/24
# Listen for commands only on localhost.
#bindcmdaddress 127.0.0.1
#bindcmdaddress ::1
# 指定包含NTP验证密钥的文件
#keyfile /etc/chrony.keys
# Serve time even if not synchronized to any NTP server.
# 阿里云提供的公网NTP服务器不可用时,采用本地时间作为同步标准
local stratum 10
# Disable logging of client accesses.
# 禁用客户端访问的日志记录
noclientlog
# Send a message to syslog if a clock adjustment is larger than 0.5 seconds.
#  如果时钟调整大于0.5秒,则向系统日志发送消息
logchange 0.5
logdir /var/log/chrony
#log measurements statistics tracking
EOF

关于 chrony 为内集群从外网同步的部署参考

  • 服务配置
sudo cat <<-'EOF' >/etc/systemd/system/chronyd.service
[Unit]
Description=A NTP Client/Server of chrony. refer to official mirror repo: https://github.com/wl4g-collect/chrony
Documentation=man:chronyd(8) man:chrony.conf(5)
After=ntpdate.service sntp.service ntpd.service
Conflicts=ntpd.service systemd-timesyncd.service
ConditionCapability=CAP_SYS_TIME

[Service]
Type=forking
PIDFile=/run/chrony/chronyd.pid
EnvironmentFile=-/etc/sysconfig/chronyd
ExecStart=/usr/sbin/chronyd $OPTIONS
ExecStartPost=/usr/libexec/chrony-helper update-daemon
PrivateTmp=yes
ProtectHome=yes
ProtectSystem=full
Group=root
User=root

[Install]
WantedBy=multi-user.target
EOF

sudo mkdir -p /var/run/chrony
sudo mkdir -p /var/log/chrony
sudo chmod 700 /var/run/chrony
sudo chmod 700 /var/log/chrony
sudo chown -R root:root /var/run/chrony/
sudo chown -R root:root /var/log/chrony/

sudo systemctl daemon-reload
sudo systemctl enable chronyd
sudo systemctl restart chronyd
sudo systemctl status chronyd
# Follow logs
sudo journalctl -u chronyd
  • 同步操作
# 查看时间同步源
>  chronyc sources -v
  .-- Source mode  '^' = server, '=' = peer, '#' = local clock.
 / .- Source state '*' = current best, '+' = combined, '-' = not combined,
| /             'x' = may be in error, '~' = too variable, '?' = unusable.
||                                                 .- xxxx [ yyyy ] +/- zzzz
||      Reachability register (octal) -.           |  xxxx = adjusted offset,
||      Log2(Polling interval) --.      |          |  yyyy = measured offset,
||                                \     |          |  zzzz = estimated error.
||                                 |    |           \
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^* 120.25.115.20                 2   5   277    59   -127us[ -157us] +/- 5987us
^- 203.107.6.88                  2   5   377     9  -4159us[-4159us] +/-   34ms

# 查看时间同步源状态
> chronyc sourcestats -v
                             .- Number of sample points in measurement set.
                            /    .- Number of residual runs with same sign.
                           |    /    .- Length of measurement set (time).
                           |   |    /      .- Est. clock freq error (ppm).
                           |   |   |      /           .- Est. error in freq.
                           |   |   |     |           /         .- Est. offset.
                           |   |   |     |          |          |   On the -.
                           |   |   |     |          |          |   samples. \
                           |   |   |     |          |          |             |
Name/IP Address            NP  NR  Span  Frequency  Freq Skew  Offset  Std Dev
==============================================================================
120.25.115.20              19  10   329     -0.007      3.265    -81ns   373us
203.107.6.88               21  11   315     -2.234     15.873  -2933us  1847us
18.1.1. Differences Between ntpd and chronyd
Things chronyd can do better than ntpd:

chronyd can work well in an environment where access to the time reference is intermittent, whereas ntpd needs regular polling of time reference to work well.
chronyd can perform well even when the network is congested for longer periods of time.
chronyd can usually synchronize the clock faster and with better accuracy.
chronyd quickly adapts to sudden changes in the rate of the clock, for example, due to changes in the temperature of the crystal oscillator, whereas ntpd may need a long time to settle down again.
In the default configuration, chronyd never steps the time after the clock has been synchronized at system start, in order not to upset other running programs. ntpd can be configured to never step the time too, but it has to use a different means of adjusting the clock, which has some disadvantages including negative effect on accuracy of the clock.
chronyd can adjust the rate of the clock on a Linux system in a larger range, which allows it to operate even on machines with a broken or unstable clock. For example, on some virtual machines.
chronyd is smaller, it uses less memory and it wakes up the CPU only when necessary, which is better for power saving.
Things chronyd can do that ntpd cannot do:

chronyd provides support for isolated networks where the only method of time correction is manual entry. For example, by the administrator looking at a clock. chronyd can examine the errors corrected at different updates to estimate the rate at which the computer gains or loses time, and use this estimate to adjust the computer clock subsequently.
chronyd provides support to work out the rate of gain or loss of the real-time clock, for example the clock that maintains the time when the computer is turned off. It can use this data when the system boots to set the system time using an adapted value of time taken from the real-time clock. These real-time clock facilities are currently only available on Linux systems.
chronyd supports hardware timestamping on Linux, which allows extremely accurate synchronization on local networks.
Things ntpd can do that chronyd cannot do:

ntpd supports all operating modes from NTP version 4 (RFC 5905), including broadcast, multicast and manycast clients and servers. Note that the broadcast and multicast modes are, even with authentication, inherently less accurate and less secure than the ordinary server and client mode, and should generally be avoided.
ntpd supports the Autokey protocol (RFC 5906) to authenticate servers with public-key cryptography. Note that the protocol has proven to be insecure and will be probably replaced with an implementation of the Network Time Security (NTS) specification.
ntpd includes drivers for many reference clocks, whereas chronyd relies on other programs, for example gpsd, to access the data from the reference clocks using shared memory (SHM) or Unix domain socket (SOCK).

4. FAQ

  • 问题现象:每隔一段时间,系统时间比BIOS硬件时间走慢几分钟,timedatectl命令看到了NTP synchronized cannot set to yes,CentOS 7.5, 配置过 ntpd 与某个时间服务器同步后,偶然发现某一个节点的NTP synchronized一直是 no :
timedatectl
      Local time: 二 2019-07-30 09:41:08 CST
  Universal time: 二 2019-07-30 01:41:08 UTC
        RTC time: 二 2019-07-30 01:08:13
       Time zone: Asia/Shanghai (CST, +0800)
     NTP enabled: yes
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a

停掉ntpd, 执行ntpd -gq重新调整时间后,再启动ntpd:

systemctl stop ntpd
ntpd -gq
ntpd: time slew +0.000041s
systemctl start ntpd

等待一会儿后,NTP synchronized恢复成yes:

> timedatectl
      Local time: 二 2019-07-30 09:44:28 CST
  Universal time: 二 2019-07-30 01:44:28 UTC
        RTC time: 二 2019-07-30 01:44:28
       Time zone: Asia/Shanghai (CST, +0800)
     NTP enabled: yes
NTP synchronized: yes
 RTC in local TZ: no
      DST active: n/a

参考 1; https://askubuntu.com/questions/929805/timedatectl-ntp-sync-cannot-set-to-yes

留言

您的电子邮箱地址不会被公开。