#ntp #ec2 #shared-memory #system-clock #aws #time

bin+lib clock-bound-d

一个守护进程,为客户端提供带有误差边界的时间戳间隔

6 个版本 (1 个稳定版本)

1.0.0 2024年4月9日
0.1.4 2023年11月16日
0.1.3 2023年1月11日
0.1.2 2022年3月11日
0.1.0 2021年11月1日

日期和时间 类别中排名第 36

每月下载量 49

GPL-2.0-only

165KB
2.5K SLoC

Crates.io License: GPL v2

时钟边界守护进程

概述

clockbound 守护进程通过与 chronyd 和操作系统时钟接口,为客户端提供系统时钟误差的边界。该 clockbound 守护进程会定期更新共享内存段,该段存储计算任何时间点的时钟误差边界的参数。客户端通过 C 库(在 clock-bound-ffi/ 中)或 Rust 库(在 clock-bound-client/ 中)打开共享内存段并读取一个时间戳间隔,在这个间隔内存在真实时间。

先决条件

同步守护进程 - chronyd

clockbound 守护进程会持续与 chronyd 通信以组成时钟误差边界参数。必须运行 chronyd 守护进程以同步系统时钟并提供时钟校正参数。

Chrony 安装

  • 如果在 Amazon Linux 2 上运行,chronyd 已经被设置为默认的 NTP 守护进程。
  • 如果在 Amazon EC2 上运行,请参阅 EC2 用户指南 了解有关安装 chronyd 和同步到 Amazon 时间同步服务的更多信息。

Chrony 权限

chronyd 守护进程在初始化后具有降级权限的能力。本指南的其余部分假定 chronydchrony 系统用户下运行,这是大多数发行版的默认设置。

请注意,这会影响哪些进程可以与chronyd进行通信。clockbound守护进程通过chronyd Unix 数据报套接字(通常在/var/run/chrony/chronyd.sock)与chronyd通信。chronyd守护进程设置了权限,使得只有运行在rootchrony用户下的进程才能写入它。

Chrony配置

重要:配置maxclockerror指令

clockbound考虑了多个同步错误源,以确保真实时间在时钟误差界限区间内。其中之一捕获了构建系统时钟的本地振荡器的稳定性。默认情况下,chronyd使用一个非常乐观的1 PPM值,这对于时钟误差估计是合适的,但不是对于界限。要使用的确切值取决于您的硬件(您应该检查),否则,50 PPM的值对于大多数配置来说应该合适,以捕获时钟更新之间的最大漂移。

更新/etc/chrony.conf配置文件,并添加以下指令以配置50 PPM的最大漂移率

# Ensures chronyd grows local dispersion at a rate that is realistic and aligned with clockbound.
maxclockerror 50

安装

Cargo

可以使用Cargo安装ClockBound守护进程。有关如何安装Cargo的说明,请参阅doc.rust-lang.org

如果您是首次在AL2 EC2实例上安装Cargo,您可能还需要安装gcc

sudo yum install gcc

使用发布标志运行cargo build

cargo build --release

Cargo安装将ClockBound守护进程的二进制文件放置在以下相对路径

target/release/clockbound

配置

Systemd配置

如果您使用Cargo从源代码构建,建议设置systemd来管理ClockBound守护进程。

在下面的systemd配置中,请注意

  • clockbound守护进程以chrony用户身份运行,以便它可以访问位于/var/run/chrony/chronyd.sock的chronyd UDS套接字。
  • 包含支持共享内存段的文件的RuntimeDirectory需要在clockbound重启事件中保留。这允许客户端代码在clockbound守护进程重启时无间断运行。
  • 根据使用的systemd版本(>=235),可以将RuntimeDirectoryRuntimeDirectoryPreserve结合使用。

配置步骤

将二进制文件移动到您想要运行它的位置

sudo mv target/release/clockbound /usr/local/bin/clockbound
sudo chown chrony:chrony /usr/local/bin/clockbound

创建unit文件/usr/lib/systemd/system/clockbound.service。此文件的內容将根据您正在运行的systemd版本而异。

要确定您正在运行的systemd版本,请运行systemctl --version

在下面的示例中,systemd版本是219。

$ systemctl --version
systemd 219
+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN

对于systemd版本>=235,创建文件/usr/lib/systemd/system/clockbound.service,内容如下

[Unit]
Description=ClockBound

[Service]
Type=simple
Restart=always
RestartSec=10
ExecStart=/usr/local/bin/clockbound --max-drift-rate 50
RuntimeDirectory=clockbound
RuntimeDirectoryPreserve=yes
WorkingDirectory=/run/clockbound
User=chrony
Group=chrony

[Install]
WantedBy=multi-user.target

对于systemd版本< 235,创建文件/usr/lib/systemd/system/clockbound.service,内容如下

[Unit]
Description=ClockBound

[Service]
Type=simple
Restart=always
RestartSec=10
PermissionsStartOnly=true
ExecStartPre=/bin/mkdir -p /run/clockbound
ExecStartPre=/bin/chmod 775 /run/clockbound
ExecStartPre=/bin/chown chrony:chrony /run/clockbound
ExecStartPre=/bin/cd /run/clockbound
ExecStart=/usr/local/bin/clockbound --max-drift-rate 50
User=chrony
Group=chrony

[Install]
WantedBy=multi-user.target

重新加载systemd

sudo systemctl daemon-reload

启用ClockBound守护进程在启动时启动

sudo systemctl enable clockbound

启动ClockBound守护进程

sudo systemctl start clockbound

然后您可以使用以下命令检查服务的状态

systemctl status clockbound

日志可在/var/log/daemon.log访问,或通过运行以下命令

sudo journalctl -u clockbound

一次性手动配置

以下步骤主要针对开发人员或测试目的。

ClockBound守护进程需要

  • 将文件/var/run/clockbound/shm支持的共享内存段写入。
  • /var/run/chrony/chronyd.sock 读取和写入 chrony UDS 套接字。如果 clockbound 守护进程以用户 chrony 运行,则允许这样做。
  • 具有与 chronyd 配置匹配的 --max-drift-rate 参数。

支持 ClockBound 守护进程设置的命令

sudo mkdir /var/run/clockbound
sudo chown root:chrony /var/run/clockbound
sudo chmod g+rwx /var/run/clockbound
sudo -u chrony /usr/local/bin/clockbound --max-drift-rate 50

用法

要与 ClockBound 守护进程通信,需要一个客户端。

  • 有关应用程序可以使用以与 ClockBound 守护进程通信的 C 库,请参阅 clock-bound-ffi
  • 有关 Rust 客户端库,请参阅 clock-bound-client

时钟状态

写入共享内存段中的时钟状态值由下文所述的有限状态机驱动。

有限状态机中的每个转换都是由从 chrony 获取的更新触发的,该更新包含时钟状态,可以是 UnknownSynchronizedFreeRunning 之一。

State Diagram for ClockStatus in SHM

EC2 上的 PTP 硬件时钟 (PHC) 支持

chronyd 正在与 PHC 同步时(因为 chronyd 假设 PHC 自身具有 0 错误边界,这并不一定正确),需要为 ClockBound 提供PHC 参考ID 和 PHC 网络接口(即 ENA 接口,如 eth0),以便读取 PHC 的时钟错误边界并将其添加到 chronyd 的时钟错误边界。这可以通过 CLI 参数 -r(参考ID)和 -(接口)来完成。参考ID可在 chronyc tracking 中看到,即

$ chronyc tracking
Reference ID    : 50484330 (PHC0) <-- This 4 character ASCII code
Stratum         : 1
Ref time (UTC)  : Wed Nov 15 18:24:30 2023
System time     : 0.000000014 seconds fast of NTP time
Last offset     : +0.000000000 seconds
RMS offset      : 0.000000060 seconds
Frequency       : 6.614 ppm fast
Residual freq   : +0.000 ppm
Skew            : 0.019 ppm
Root delay      : 0.000010000 seconds
Root dispersion : 0.000001311 seconds
Update interval : 1.0 seconds
Leap status     : Normal

网络接口应该是主网络接口(来自 ifconfig,索引为 0 的接口) - 在 Amazon Linux 2 中这通常是 eth0,在 Amazon Linux 2023 中这通常是 ens5

例如

/usr/local/bin/clockbound -r PHC0 -i eth0

要使您的 systemd 单元执行此操作,您需要编辑上述行以提供正确的参数。

例如

[Unit]
Description=ClockBound

[Service]
Type=simple
Restart=always
RestartSec=10
ExecStart=/usr/local/bin/clockbound -r PHC0 -i eth0
RuntimeDirectory=clockbound
RuntimeDirectoryPreserve=yes
WorkingDirectory=/run/clockbound
User=chrony
Group=chrony

[Install]
WantedBy=multi-user.target

安全性

有关更多信息,请参阅 CONTRIBUTING

许可证

根据 GPL v2 许可证授权。

依赖关系

~5–17MB
~172K SLoC