# 时间同步（chronyd）

URL: https://caijiao.org/rockylinux/time-sync
Source: docs/rockylinux/time-sync.md
Description: 详细介绍 Rocky Linux 中使用 chronyd 进行系统时间同步的方法，包括配置、管理和监控 NTP 服务

时间同步在计算机系统中扮演着至关重要的角色，特别是在分布式系统、日志记录、安全认证和事务处理等场景下。不准确的系统时间可能导致服务故障、日志分析困难、安全认证失败等问题。在 Rocky Linux 中，chronyd 是默认的 NTP（网络时间协议）实现，它提供了高效、准确的时间同步服务。本教程将详细介绍如何在 Rocky Linux 中配置和管理 chronyd 服务。

## chronyd 概述

chronyd 是一个灵活的网络时间协议（NTP）客户端和服务器，它专为以下场景设计：

1. **间歇性连接的系统**：如笔记本电脑或移动设备
2. **资源受限的系统**：如嵌入式设备
3. **需要精确时间同步的服务器**：如金融交易系统、数据库服务器

与传统的 ntpd 相比，chronyd 具有以下优势：

- **更快的初始同步**：能够在几秒内完成初始时间调整
- **更好的时钟稳定性**：即使在网络连接不稳定的情况下也能保持较好的时间同步
- **更低的资源消耗**：CPU 和内存使用更少
- **更好的处理系统时钟频率变化**：适用于虚拟机等环境
- **支持硬件时间戳**：可以提高时间精度

## 检查 chronyd 服务状态

在 Rocky Linux 中，chronyd 通常已经预装并默认启用。可以通过以下命令检查其状态：

```bash
# 检查 chronyd 服务状态
systemctl status chronyd

# 检查 chronyd 是否开机自启
systemctl is-enabled chronyd
```

如果 chronyd 未安装，可以使用以下命令安装：

```bash
# 安装 chronyd
sudo dnf install chrony -y
```

## 启动和管理 chronyd 服务

### 启动 chronyd 服务

```bash
# 启动 chronyd 服务
sudo systemctl start chronyd

# 设置 chronyd 服务开机自启
sudo systemctl enable chronyd
```

### 重启和停止 chronyd 服务

```bash
# 重启 chronyd 服务
sudo systemctl restart chronyd

# 停止 chronyd 服务
sudo systemctl stop chronyd
```

## 使用 chronyc 命令行工具

chronyc 是 chronyd 的命令行界面工具，用于监控和控制 chronyd 守护进程。

### 基本命令

```bash
# 查看时间同步状态
chronyc tracking

# 查看 NTP 源状态
chronyc sources

# 查看更详细的 NTP 源信息
chronyc sources -v

# 查看 NTP 源统计信息
chronyc sourcestats

# 手动执行时间同步
chronyc makestep

# 查看 chronyd 系统时钟性能数据
chronyc -n tracking

# 查看当前客户端访问权限
trycmd access
```

### 查看时间同步状态详解

执行 `chronyc tracking` 命令后，可以看到类似以下输出：

```
Reference ID    : A9FE060B (time.cloudflare.com)
Stratum         : 4
Ref time (UTC)  : Wed May 10 12:34:56 2023
System time     : 0.000001234 seconds fast of NTP time
Last offset     : +0.000000123 seconds
RMS offset      : 0.000002345 seconds
Frequency       : 123.456 ppm slow
Residual freq   : +0.001 ppm
Skew            : 0.010 ppm
Root delay      : 0.034567 seconds
Root dispersion : 0.001234 seconds
Update interval : 1024.0 seconds
Leap status     : Normal
```

主要字段说明：

- **Reference ID**：当前同步的参考时钟 ID
- **Stratum**：时钟层级，值越小越接近参考时钟
- **System time**：系统时间与 NTP 时间的偏差
- **Last offset**：最后一次测量的时间偏差
- **RMS offset**：最近几次测量的均方根偏差
- **Frequency**：系统时钟频率误差（ppm - 百万分之一）
- **Update interval**：更新间隔
- **Leap status**：闰秒状态（Normal, Insert second, Delete second, Not synchronized）

## 配置 chronyd

chronyd 的主配置文件是 `/etc/chrony.conf`。在修改前，建议先备份原始配置：

```bash
sudo cp /etc/chrony.conf /etc/chrony.conf.bak
```

### 编辑配置文件

```bash
sudo vim /etc/chrony.conf
```

### 主要配置选项

#### 1. NTP 服务器配置

```
# 使用公共 NTP 服务器
pool 2.rocky.pool.ntp.org iburst
pool 3.rocky.pool.ntp.org iburst

# 或者指定具体的 NTP 服务器
server time1.google.com iburst
server time2.google.com iburst
```

**参数说明**：

- `pool`：使用 NTP 服务器池
- `server`：指定单个 NTP 服务器
- `iburst`：在启动时发送一系列突发包，加速初始同步

#### 2. 本地时钟配置

```
# 如果无法访问外部 NTP 服务器，可以将本地时钟作为时间源
# 但请注意，这不会提供准确的时间
local stratum 10
```

#### 3. 系统时钟与硬件时钟同步

```
# 启用系统时钟与硬件时钟同步
hwtimestamp *
rtcsync

# 指定系统时钟与硬件时钟的偏差补偿
makestep 1.0 3
```

**参数说明**：

- `hwtimestamp *`：为所有支持硬件时间戳的接口启用硬件时间戳
- `rtcsync`：启用内核的 RTC 同步功能，每 11 分钟将系统时间写入硬件时钟
- `makestep threshold limit`：当系统时钟与 NTP 时间的偏差超过 threshold 秒时，允许 chronyd 直接调整系统时钟，最多调整 limit 次

#### 4. 日志文件配置

```
# 指定日志文件
logdir /var/log/chrony
log measurements statistics tracking
```

**参数说明**：

- `logdir`：指定日志目录
- `log`：指定要记录的日志类型

#### 5. 访问控制配置

```
# 允许本地网络客户端查询时间
allow 192.168.1.0/24

# 允许所有客户端查询时间，但不允许修改
allow

# 拒绝特定网络访问
deny 10.0.0.0/8
```

#### 6. 其他配置选项

```
# 指定最小轮询间隔（秒）
minpoll 4

# 指定最大轮询间隔（秒）
maxpoll 10

# 调整系统时钟频率，不执行步进调整
smoothie

# 禁用客户端访问
deny all
```

### 应用配置更改

修改配置后，需要重启 chronyd 服务以应用更改：

```bash
sudo systemctl restart chronyd
```

## 配置防火墙

如果系统启用了防火墙，需要确保允许 NTP 流量通过：

```bash
# 允许 NTP 服务通过防火墙
sudo firewall-cmd --permanent --add-service=ntp

# 重新加载防火墙规则
sudo firewall-cmd --reload
```

## 使用 chronyd 作为 NTP 服务器

chronyd 不仅可以作为 NTP 客户端从其他服务器同步时间，还可以作为 NTP 服务器为其他客户端提供时间同步服务。

### 配置 NTP 服务器

编辑 `/etc/chrony.conf` 文件，添加以下内容：

```
# 允许指定网络的客户端访问
allow 192.168.1.0/24

# 如果无法访问外部 NTP 服务器，使用本地时钟作为备份
local stratum 10
```

### 验证 NTP 服务器功能

1. 重启 chronyd 服务：

   ```bash
   sudo systemctl restart chronyd
   ```

2. 验证 NTP 服务器是否正在监听端口：

   ```bash
   sudo ss -tuln | grep 123
   ```

3. 在客户端测试连接：
   ```bash
   chronyc -h ntp-server-ip sources
   ```

## 手动调整系统时间

在某些情况下，可能需要手动调整系统时间。可以使用以下命令：

### 使用 date 命令调整时间

```bash
# 显示当前时间
date

# 设置系统时间（格式：MMDDhhmmYYYY.ss）
sudo date 051012342023.00

# 设置系统时间（人类可读格式）
sudo date -s "2023-05-10 12:34:00"
```

### 使用 timedatectl 命令

timedatectl 是 systemd 提供的时间管理工具，可以设置系统时间、时区等：

```bash
# 显示当前时间和时区
timedatectl

# 设置系统时间
sudo timedatectl set-time "2023-05-10 12:34:00"

# 设置时区
sudo timedatectl set-timezone Asia/Shanghai

# 启用网络时间同步
sudo timedatectl set-ntp true

# 禁用网络时间同步
sudo timedatectl set-ntp false
```

## 时区配置

正确配置时区对于日志记录和应用程序正常运行非常重要。

### 查看当前时区

```bash
# 方法一
timedatectl

# 方法二
ls -la /etc/localtime

# 方法三
date +"%Z %z"
```

### 列出可用时区

```bash
# 列出所有可用时区
timedatectl list-timezones

# 过滤亚洲时区
timedatectl list-timezones | grep Asia
```

### 设置时区

```bash
# 设置时区为上海
sudo timedatectl set-timezone Asia/Shanghai

# 或者手动创建符号链接
sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
```

## 硬件时钟管理

硬件时钟（RTC - Real Time Clock）是独立于操作系统的时钟，即使系统关机也能保持时间。

### 查看硬件时钟

```bash
# 查看硬件时钟
sudo hwclock --show

# 或者
sudo hwclock -r
```

### 设置硬件时钟

```bash
# 设置硬件时钟
sudo hwclock --set --date="2023-05-10 12:34:00"

# 从系统时钟同步到硬件时钟
sudo hwclock --systohc

# 从硬件时钟同步到系统时钟
sudo hwclock --hctosys
```

### 配置硬件时钟时区

硬件时钟可以设置为 UTC 或本地时间。在 Linux 系统中，建议将硬件时钟设置为 UTC：

```bash
# 将硬件时钟设置为 UTC
sudo timedatectl set-local-rtc 0

# 或者将硬件时钟设置为本地时间（不推荐）
sudo timedatectl set-local-rtc 1
```

## chronyd 日志分析

chronyd 的日志文件默认存储在 `/var/log/chrony/` 目录下。可以通过分析这些日志来排查时间同步问题。

```bash
# 查看测量日志
sudo cat /var/log/chrony/measurements.log

# 查看统计日志
sudo cat /var/log/chrony/statistics.log

# 查看跟踪日志
sudo cat /var/log/chrony/tracking.log
```

## 常见问题与故障排除

### 时间同步失败

如果 chronyd 无法与 NTP 服务器同步，可以尝试以下方法：

1. 检查网络连接：

   ```bash
   ping 8.8.8.8
   ```

2. 检查 NTP 服务器可达性：

   ```bash
   ping 2.rocky.pool.ntp.org
   ```

3. 检查防火墙设置：

   ```bash
   sudo firewall-cmd --list-all
   ```

4. 尝试使用其他 NTP 服务器，编辑 `/etc/chrony.conf`：

   ```
   server 0.cn.pool.ntp.org iburst
   server 1.cn.pool.ntp.org iburst
   server 2.cn.pool.ntp.org iburst
   server 3.cn.pool.ntp.org iburst
   ```

5. 手动执行时间同步：
   ```bash
   sudo chronyc makestep
   ```

### 系统时间与硬件时钟不同步

如果系统时间与硬件时钟不同步：

1. 检查硬件时钟是否设置为 UTC：

   ```bash
   timedatectl | grep "RTC in local TZ"
   ```

2. 从系统时钟同步到硬件时钟：

   ```bash
   sudo hwclock --systohc
   ```

3. 确保 chronyd 配置中包含 `rtcsync` 选项。

### chronyd 服务无法启动

如果 chronyd 服务无法启动：

1. 检查配置文件语法：

   ```bash
   sudo chronyc -n -f /etc/chrony.conf
   ```

2. 查看服务状态和错误信息：

   ```bash
   sudo systemctl status chronyd
   sudo journalctl -u chronyd
   ```

3. 确保端口 123 未被其他服务占用：
   ```bash
   sudo ss -tuln | grep 123
   ```

## 安全最佳实践

1. **选择可靠的 NTP 服务器**：使用官方或受信任的 NTP 服务器池

2. **配置访问控制**：限制哪些客户端可以访问你的 NTP 服务器

   ```
   allow 192.168.1.0/24
   ```

3. **定期更新 chrony**：确保安装最新的安全补丁

   ```bash
   sudo dnf update chrony -y
   ```

4. **使用防火墙限制 NTP 流量**：只允许必要的 NTP 流量

5. **考虑使用认证**：对于敏感环境，配置 NTP 认证以防止时间欺骗攻击

   ```
   # 在服务器端生成密钥
   sudo chronyc keygen

   # 在配置文件中添加密钥
   keyfile /etc/chrony.keys
   ```

## 高级功能

### NTP 认证

NTP 认证可以防止时间欺骗攻击，确保系统只从受信任的 NTP 服务器同步时间。

1. 生成密钥：

   ```bash
   sudo chronyc keygen > /etc/chrony.keys
   sudo chmod 600 /etc/chrony.keys
   ```

2. 编辑 `/etc/chrony.conf`，添加以下内容：

   ```
   # 指定密钥文件
   keyfile /etc/chrony.keys

   # 为 NTP 服务器配置认证
   server time.example.com key 123 iburst
   ```

3. 重启 chronyd 服务：
   ```bash
   sudo systemctl restart chronyd
   ```

### 使用硬件时间戳

对于需要高精度时间同步的场景，可以启用硬件时间戳：

```
# 在 /etc/chrony.conf 中添加
hwtimestamp eth0
```

### 调整系统时钟参数

可以根据系统特性调整时钟参数：

```
# 在 /etc/chrony.conf 中添加
# 增加更新间隔
maxpoll 17

# 减少更新间隔（用于高精度场景）
minpoll 3
maxpoll 8

# 调整时钟参数
clockfilter 2
```

## 总结

chronyd 是 Rocky Linux 中强大而灵活的时间同步工具，它能够提供准确的时间同步服务，适用于各种网络环境和系统需求。本教程详细介绍了 chronyd 的安装、配置、管理以及常见问题的排查方法。

通过正确配置和使用 chronyd，您可以确保系统时间的准确性，为各种网络服务和应用程序提供可靠的时间基础。无论是单机服务器还是大规模分布式系统，chronyd 都能够满足您的时间同步需求。

记住，在网络环境中，准确的时间同步对于系统日志分析、安全认证、分布式事务处理等方面都至关重要。定期检查和维护时间同步服务，是系统管理工作中不可忽视的一部分。
