时间同步服务器一般都是用的网络时间协议 NTP而不是PTP,因为后者需要网络接口具备在物理层提供时间戳的功能,同步精度优于100ns,局域网的节点需要使用支持PTP功能的交换机。局域网网络接点不支持PTP的话,只能同不到us,而且受网络背景流量影响。而前者只需要软件层面实现,成本低,同步精度10ms左右。
在CentOS7及以后,系统将默认的ntpd更换为chrony,从时间上来看,ntpd已经20多年了,确实很老,但是为什么要用chrony呢。

1. 为什么用Chrony

chrony之前,市面上的主要两款工具,ntpdntpdate,他们都是基于NTP协议。
ntpd相比较ntpdate,前者是一套体系,而后者只是一条命令,区别大致如下:

NTP

  • 是一个时间服务
  • 采用柔性时间调整策略,让时间的变化和调整尽量减少对业务的影响
  • 不盲目相信远端时钟,服务器时间与远端超过恐慌阈值(默认1000秒),ntp甚至会停止时间同步
  • 自己会思考。它相信本地时间可能不对,但是不会忽快忽慢甚至停滞。ntpd通过多次收发包选择权威稳定的时间源,算出双方间的网络延迟,然后才会采信新的远端时钟进行时间同步。
  • 在和时间服务器的同步过程中,会把BIOS振荡时钟和远程时间服务的偏移量记录下来,这样即使网络有问题,本机仍然能维持一个相当精确的走时

NTPDATE

  • 是一个时间同步命令,通常采用crond+ntpdate方式同步时间
  • 盲目信任远端时钟,如果远端时钟错误,ntpdate永远相信远端时钟是正确的,可能造成服务器时钟停滞,甚至回逆
  • 简单粗暴,无脑不会思考。采用野蛮式(brute force,国外资料中这个词用的很好)、跃进式调整服务器时间

从上来看,ntpd秒杀ntpdate,因为前者是平滑逐渐调整时间,而后者是断点式更新时间,所以ntpdate以后就不要用了。
那么chrony相比较ntpd又有什么区别呢?

CHRONY

  • 平滑的调整时间, 并且相对ntpd更快的调整(调整都是控制系统时间的走速来达到时间调整的目的)
  • 能够更好地响应时钟频率的快速变化,这对于具备不稳定时钟的虚拟机或导致时钟频率发生变化的节能技术而言非常有用
  • 在初始同步后,它不会停止时钟,以防对需要系统时间保持单调的应用程序造成影响
  • 在应对临时非对称延迟时(例如,在大规模下载造成链接饱和时)提供了更好的稳定性
  • 无需对服务器进行定期轮询,因此具备间歇性网络连接的系统仍然可以快速同步时钟

2. Chrony的组成

chronychronyd守护进程与chronyccli命令组成,本地监听udp 323端口,监听udp 123端口提供服务。


3. 配置Chrony时间同步服务器

本身CentOS7已经自带chrony并且启动与自启动,这里我们直接修改配置文件,修改默认的ntp server。

# cat /etc/chrony.conf | grep -v '#'

server ntp1.aliyun.com iburst # 新增阿里云ntp服务器
server time1.cloud.tencent.com iburst # 新增腾讯云ntp服务器
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
allow 172.18.0.0/16 # 允许访问此服务器的网段
logdir /var/log/chrony

修改好以后开放udp 123端口并重启chrony守护进程。

# 开放端口
firewall-cmd --add-port=123/udp --permanent
firewall-cmd --reload

# 重启chrony守护进程
systemctl restart chronyd

现在使用chronyc来查看状态:

# chronyc sources
210 Number of sources = 2
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^* 120.25.115.20                 2  10   337   665  +1007us[ +949us] +/-   17ms
^+ 139.199.215.251               2  10   377   918   -853us[ -911us] +/-   47ms

可以看到^* 120.25.115.20*代表状态正常,且为生效的ntp服务器。


4. 使用Chrony时间同步服务器

现在内网机器可以修改配置后重启chronyd即可,但是配置中需要修改几个地方:

# cat /etc/chrony.conf | grep -v '#'

#server ntp1.aliyun.com iburst # 注释阿里云ntp服务器
#server time1.cloud.tencent.com iburst # 注释腾讯云ntp服务器
server 172.18.0.150 iburst # 新增内网chrony服务器
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
# allow 172.18.0.0/16 # 注释此段
logdir /var/log/chrony

4.1 使用Ansible配置时间同步服务器

默认在ansible服务器已经添加了需要配置的设备。
首先在ansible新建一个roles,然后写入自己的文件。

# cd /etc/ansible
# ansible-galaxy init chrony
# tree roles/
roles/
└── chrony
    ├── defaults
    │   └── main.yml
    ├── files
    │   └── chrony.conf
    ├── handlers
    │   └── main.yml
    ├── meta
    │   └── main.yml
    ├── README.md
    ├── tasks
    │   ├── copy_chrony_file.yml
    │   ├── main.yml
    │   ├── remove_ntpd.yml
    │   ├── restart_chrony_service.yml
    │   └── set_timezone.yml
    ├── templates
    ├── tests
    │   ├── inventory
    │   └── test.yml
    └── vars
        └── main.yml

9 directories, 13 files

这里我已经增加好了文件,主要有:

  • files.chorony.conf
  • tasks.remove_ntpd.yml
  • tasks.copy_chrony_file.yml
  • tasks.restart_chrony_service.yml
  • tasks.set_timezone.yml
files.chrony.conf

与上面相同:

# cat chrony.conf | grep -v '#'

server 172.18.0.150 iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
logdir /var/log/chrony
tasks

几个tasks

---
- name: copy chrony file
  copy:
    src=chrony.conf
    dest=/etc/

---
- name: restart chrony service
  shell: systemctl restart chrony

---
- name: set timezone
  shell: timedatectl set-timezone Asia/Shanghai

---
- name: remove ntpd
  yum:
    name: ntp
    state: absent
tasks.main.yml

main.yml中引用自定义的task,这里注意include将会在未来版本中移除,现在需要使用include_tasks

---
- include_tasks: remove_ntpd.yml
- include_tasks: copy_chrony_file.yml
- include_tasks: restart_chrony_service.yml
- include_tasks: set_timezone.yml

最后设置一个playbook文件头引用roles即可。
保存为set_chrony.yml,这里假定我们要对配置harbor这台主机。

---
- hosts: harbor
  remote_user: root
  roles:
    - chrony
配置生效
# ansible-playbook chrony.yml 

PLAY [harbor] ***********************************************************************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************************************************************************ok: [harbor]

TASK [chrony : include_tasks] *******************************************************************************************************************************************************************included: /etc/ansible/roles/chrony/tasks/remove_ntpd.yml for harbor

TASK [chrony : remove ntpd] *********************************************************************************************************************************************************************ok: [harbor]

TASK [chrony : include_tasks] *******************************************************************************************************************************************************************included: /etc/ansible/roles/chrony/tasks/copy_chrony_file.yml for harbor

TASK [chrony : copy chrony file] ****************************************************************************************************************************************************************ok: [harbor]

TASK [chrony : include_tasks] *******************************************************************************************************************************************************************included: /etc/ansible/roles/chrony/tasks/restart_chrony_service.yml for harbor

TASK [chrony : restart chrony service] **********************************************************************************************************************************************************changed: [harbor]

TASK [chrony : include_tasks] *******************************************************************************************************************************************************************included: /etc/ansible/roles/chrony/tasks/set_timezone.yml for harbor

TASK [chrony : set timezone] ********************************************************************************************************************************************************************changed: [harbor]

PLAY RECAP **************************************************************************************************************************************************************************************harbor                     : ok=9    changed=2    unreachable=0    failed=0   
验证配置

等待约30秒后查看:

# ansible harbor -m shell -a 'chronyc sources'
harbor | SUCCESS | rc=0 >>
210 Number of sources = 1
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^* 172.18.0.150                  3   6     7    39   -215us[ -185us] +/-   18ms

可以看到^* 172.18.0.150已经生效正常。

感谢

  1. linux时间同步 - 知乎
  2. ntpd和ntpdate的区别 | 十字螺丝钉的DBA日记
  3. https://blog.gnuers.org/?p=1483
Last modification:September 18th, 2019 at 10:41 am