👌 2021-06-26 Linux 时间全解
FileInfo Filename - Linux 时间全解 Version - v1.1.2107(2021/06/26 ~ 2021/07/01) Author - nuo standuke Email - shadowdoker@gmail.com DescriptionKey - Linux time solution
版本修订记录:
v1.0.2106:2021-06-26:建立 Linux 时间全解文档,修订人:nuo v1.1.2107:2021-07-01:新增 CentOS 与 Ubuntu 时间同步相关区别,修订人:nuo
[TOC]
简介
作为一切皆文件的 Linux 操作系统,日志的记录、定时任务的执行,甚至些许程序的配置「MySQL」也极度依赖系统时间,故系统时间在操作系统运行时尤为重要。和 Windows 一样,Linux 也分为本地时间用于手动设置和使用 ntp 方式自动同步的远程时间。
⚠️ 值得注意的是,考虑到文件的生成也会获取系统时间作为文件的时间戳,建议在安装操作系统时就将主板上的硬件时间同步,或者在安装操作系统时手动将时间校准。
在本文中将会涉及 CentOS 如下与时间相关的命令以及与时间相关的配置文件。同时稍有提及 Ubuntu 内的差异及其配置。
- timedatectl
- date
- chrony
- ntp / ntpdate
相关名词介绍
了解相关时间名词有利于理解后期相关术语的讲解,此处以 CentOS 内 timedatectl
标准输出作为样例。
>root ~
[vpc]# timedatectl
Local time: 二 2021-06-29 13:45:54 CST
Universal time: 二 2021-06-29 05:45:54 UTC
RTC time: 二 2021-06-29 05:45:54
Time zone: Asia/Shanghai (CST, +0800)
NTP enabled: yes
NTP synchronized: yes
RTC in local TZ: no
DST active: n/a
UTC 「Universal time: 二 2021-06-29 05:45:54 UTC」
协调世界时「UTC - Coordinated Universal Time」。地球分为二十四时区,每个时区都有自己的当地时间。在国际无线电通信场合,为了统一起见,使用一个统一的时间,称为协调世界时「UTC - Universal Time Coordinated」。
GMT
格林尼治标准时间「Greenwich Mean Time Zone」。指位于英国伦敦郊区的皇家格林尼治天文台的标准时间,因为本初子午线被定义在通过那里的经线。「UTC 与 GMT时间基本相同」
CTS 「Local time: 二 2021-06-29 13:45:54 CST」
中国标准时间「CST – China Standard Time」。GMT + 8 = UTC + 8 = CST
DST
夏令时,部分国家使用,在中国不使用。所以在国外服务器配置系统时间时需要注意。
RTC 硬件时间 「RTC time: 二 2021-06-29 05:45:54」
RTC「Real-Time Clock」或 CMOS / BIOS 时间,一般在主板上靠电池供电,服务器断电后也会继续运行。仅保存日期时间数值,无法保存时区和夏令时设置。
Local time 系统时间 / 本地时间 「Local time: 二 2021-06-29 13:45:54 CST」
服务器启动时复制 RTC 时间,之后独立运行,保存了时间、时区和夏令时设置。所以一般来说,本地的 RTC 最好保存 UTC 时间,系统时间依照操作系统内配置自己计算最终的时间。
- ⚠️ 硬件时间「RTC」与 本地时间「Local time」
在 timedatectl set-local-rtc yes
设置为 yes 时,会出现警告。「这个地方鄙视一下 阿里云,也算是一个坑,阿里云主机硬件『RTC』时间没有使用国际上通用的 UTC 时间,而是采用当地时间……」
# 告警如下
Warning: The system is configured to read the RTC time in the local time zone.
This mode can not be fully supported. It will create various problems
with time zone changes and daylight saving time adjustments. The RTC
time is never updated, it relies on external facilities to maintain it.
If at all possible, use RTC in UTC by calling
'timedatectl set-local-rtc 0'.
例如如果 RTC 时间与系统时间不一致,那么 MySQL 在重启或者关闭时就会报错 InnoDB: Waiting for page_cleaner to finish flushing of buffer pool
,原因就是 系统时间与mysql缓存的时间不一致,这时就需要把系统时间改在 MySQL 正常运行的时间之后。再将 timedatectl set-local-rtc no
设置为 no
。
所以在配置使用 timedatectl
去修改时间时会同时配置系统时间「例如命令 date -s
」和硬件时间「例如命令 hwclock -w
」,而硬件时间 RTC 的具体值是否和系统时间一致则由 set-local-rtc
来配置。
时间配置命令
timedatectl
简介
在名词介绍部分已经稍有提及 timedatectl
命令,其中的概念很关键,务必要看。
timedatectl
是 systemd-timedated.service
系统服务的命令行客户端,是在 RHEL7 及 CentOS7 中新增的 systemd 的一部分,用于系统时间管理。在 CentOS 7 系统上,建议使用 timedatectl
而不是 date
、hwclock
命令来调整时间。在 Ubuntu 系统上,也采用 timedatectl
来管理时间,但是在 Ubuntu 系统上时间的管理流程稍有不同。
在最新的 Ubuntu 版本中,timedatectl 替代了老旧的 ntpdate。默认情况下,timedatectl 在系统启动的时候会立刻同步时间,并在稍后网络连接激活后通过 socket 再次检查一次。如果已安装了 ntpdate / ntp,timedatectl 会退而让你使用之前的设置。这样确保了两个时间同步服务不会相互冲突,同时在你升级的时候还保留原本的行为和配置。但这也意味着从旧版本的发行版升级时ntp/ntpdate 仍会安装,因此会导致新的基于 systemd 的时间服务被禁用。
在最新的 Ubuntu 版本中,timesyncd 替代了 ntpd 的客户端的部分。默认情况下 timesyncd 会定期检测并同步时间。它还会在本地存储更新的时间,以便在系统重启时做时间单步调整。通过 timedatectl 和 timesyncd 设置的当前时间状态和时间配置,可以使用 timedatectl status命令来进行确认。而在 CentOS 7 中,不存在 timesyncd 服务,是由 chrony 来作为 ntpd 的客户端的部分。
- CentOS 7.0 +
timedatectl
-> systemd-timedated.service
-> chronyd.service
「配置文件 /etc/chrony.conf
」
- Ubuntu 16.04 LTS + 1
timedatectl
-> systemd-timedated.service
-> timesyncd.service
「配置文件 /etc/systemd/timesyncd.conf
」
timedatectl
能做到:修改系统时间、修改 RTC 时间、修改系统时区、设置 NTP 时间同步、查看当前系统时间状态。一般来说使用 timedatectl
已经能满足日常对于时间操作的需求了。
时间同步配置
对于时间、时区修改较为简单,这里着重介绍下 timedatectl
内的 NTP 相关原理以及配置。
- timedatectl 的 NTP 同步流程
使用 timedatectl
配置 NTP 客户端服务打开,systemd-timedated.service
收到 NTP 打开的信息,由 systemd-timedated.service
打开 chronyd.service
来启动 NTP,用于连接 服务端。timedatectl
内的 NTP 只能实现 NTP 的客户端角色,同时同步策略也较为激进「时间相差大则直接修改,相差小则慢慢追赶」,比较适合频繁启动的业务场景。
- 开启 timedatectl 的 NTP 同步
开启 timedatectl 的 NTP 同步需要系统安装 NTP 客户端「ntpd 或者 chrony,Ubuntu 还可以安装 timesyncd」,否则会有 Failed to set ntp: NTP not supported.
的报错。
timedatectl set-ntp true
修改配置为开启状态,再使用 timedatectl
查看 NTP enabled
、NTP synchronized
同步状态即可。如果没有安装 chrony 等同步软件,可参考如下注意事项的 timedatectl
输出。
注意事项
⚠️ 手动安装操作系统时,会提示是否打开 NTP 时钟同步,如果选择打开那么会默认安装 chrony
相关软件用于系统时间同步,如果不打开,则不会安装 chrony
,如此系统时间将不会同步。
- 安装系统时,不开启 NTP,timedatectl 的输出,也就是没有 NTP 客户端的情况。
>root ~
[node1]# timedatectl
Local time: 六 2021-06-26 10:53:42 CST
Universal time: 六 2021-06-26 02:53:42 UTC
RTC time: 六 2021-06-26 10:53:26
Time zone: Asia/Shanghai (CST, +0800)
NTP enabled: n/a
NTP synchronized: no
RTC in local TZ: no
DST active: n/a
- 安装系统时,开启 NTP,timedatectl 的输出
>root ~
[node1]# timedatectl
Local time: 六 2021-06-26 11:15:36 CST
Universal time: 六 2021-06-26 03:15:36 UTC
RTC time: 六 2021-06-26 03:15:36
Time zone: Asia/Shanghai (CST, +0800)
NTP enabled: yes
NTP synchronized: yes
RTC in local TZ: no
DST active: n/a
- 如果安装系统时不开启 NTP,
chrony
为后期安装,那 timedatectl 的输出如下。同时需要手动开启 NTP 同步,NTP enabled: no
才会变成yes
。
>root ~
[node1]# timedatectl
Local time: 六 2021-06-26 11:15:36 CST
Universal time: 六 2021-06-26 03:15:36 UTC
RTC time: 六 2021-06-26 03:15:36
Time zone: Asia/Shanghai (CST, +0800)
NTP enabled: no
NTP synchronized: no
RTC in local TZ: no
DST active: n/a
date
此处省略
我感觉一行命令就可以了……「网上对于 date
命令的介绍很多」
date +"%Y-%m-%d %H:%M"
chrony
Chrony 是一个 NTP 客户端的替代品。它可以更快地同步系统时钟,时间精度更高,对于一直不在线的系统尤其有用。chronyd 较小,它使用较少的内存,只在必要时才唤醒 CPU,这样可以更好地节省电能。即使网络拥塞较长时间,它也能很好地运行同步时间。它由两个程序组成,分别是 chronyd 和 chronyc。chronyd 是一个后台运行的守护进程,用于调整内核中运行的系统时钟和时钟服务器同步。它确定计算机增减时间的比率,并对此进行补偿。chronyc 提供了一个用户界面,用于监控性能并进行多样化的配置。
安装 chrony 软件包
yum install -y chrony
修改配置
# controller
- server *
+ server 127.127.1.0 iburst
+ allow 192.168.10.0/24
# node
- server *
+ server controller iburst
启动服务,并设置开机自启动
systemctl start chronyd && systemctl enable chronyd
ntp
安装 ntp 软件包
yum -y install ntp
备份配置
# 配置各节点 ntpd 配置文件
cp /etc/ntp.conf{,.bak}
修改配置
# 管理节点使用本地时钟源,执行以下语句即可
cat <<EOF>/etc/ntp.conf
driftfile /var/lib/ntp/drift
restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery
restrict 127.0.0.1
restrict -6 ::1
server 127.127.1.0 iburst
includefile /etc/ntp/crypto/pw
keys /etc/ntp/keys
EOF
# 其他节点的时钟源为管理节点,执行以下语句即可
cat <<EOF>/etc/ntp.conf
driftfile /var/lib/ntp/drift
restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery
restrict 127.0.0.1
restrict -6 ::1
server node1 iburst
includefile /etc/ntp/crypto/pw
keys /etc/ntp/keys
EOF
手动设置时间,写入硬件时钟
「CentOS 7 务必使用 timedatectl
来操作」
# 修改各节点时间,时间为当前时间
date -s "2019-11-30 16:07:00"
# 写入硬件时钟
hwclock -w
启动服务,并设置开机自启动
# 各节点启动服务
systemctl start ntpd
# 各节点设置开机自启动
systemctl enable ntpd
手动配置时钟
手动配置完时钟后一定要同步到硬件时钟里
timedatectl set-time "20:01:09"
date -s "20:01:09"
时钟同步状态校验
- timedatectl
timedatectl status
>root ~
[node1]# timedatectl status
Local time: 二 2021-06-29 16:47:25 CST
Universal time: 二 2021-06-29 08:47:25 UTC
RTC time: 二 2021-06-29 08:47:25
Time zone: Asia/Shanghai (CST, +0800)
NTP enabled: yes
NTP synchronized: yes
RTC in local TZ: no
DST active: n/a
- chrony
chronyc sources -v
chronyc tracking
>root ~
[node1]# chronyc sources -v
210 Number of sources = 4
.-- Source mode '^' = server, '=' = peer, '#' = local clock.
/ .- Source state '*' = current synced, '+' = combined , '-' = not combined,
| / '?' = unreachable, 'x' = time may be in error, '~' = time too variable.
|| .- 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
===============================================================================
^- tock.ntp.infomaniak.ch 1 10 377 22m +12ms[ +12ms] +/- 104ms
^* 120.25.115.20 2 10 377 307 +423us[ +432us] +/- 18ms
^- ntp1.flashdance.cx 2 10 377 664 +8908us[+8917us] +/- 154ms
^+ 119.28.183.184 2 10 337 884 -462us[ -453us] +/- 32ms
- ntp
ntpq -p
ntpstat
参考资料
https://www.iamhippo.com/2020-01/1306.html https://blog.csdn.net/weixin_34270606/article/details/91881851 https://ywnz.com/linuxml/5215.html https://www.cnblogs.com/opsprobe/p/13779933.html
-
Since Ubuntu 16.04 timedatectl / timesyncd (which are part of systemd) replace most of ntpdate / ntp. @ https://ubuntu.com/server/docs/network-ntp ↩︎