文章简介:chrony 静态编译及跨操作系统安装 systemd service
更新
基于 ubuntu 的镜像编译出的 chronyc 在 centos7.9 下执行 chronyc sources -v
会 Segmentation fault
, 初步断定是由于 glibc 静态编译时有部分动态依赖的 wake link 被使用到导致的。替换成基于 alpine 的 musl 即可解决问题.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
FROM alpine:edge as build
ARG branch=4.2
ENV DEBIAN_FRONTEND noninteractive
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories
WORKDIR /opt
# COPY chrony . # 二选一
RUN apk add build-base libcap-dev texinfo nettle-dev gnutls-dev bash wget tar gcc make \
&& wget https://download.tuxfamily.org/chrony/chrony-${branch}.tar.gz \
&& tar zxf chrony-${branch}.tar.gz \
&& mv chrony-${branch} chrony \
&& rm -f chrony-${branch}.tar.gz
RUN cd chrony; \
CFLAGS='-static -g' LDFLAGS='-static -lm' \
./configure \
--enable-scfilter \
--enable-ntp-signd \
&& make; echo $?; \
mkdir -p /install_root; \
make DESTDIR=/install_root install \
&& find /install_root
RUN rm -rf /install_root/usr/local/share \
&& rmdir /install_root/var/lib/chrony/ /install_root/etc
FROM scratch AS bin
COPY --from=build /install_root /
|
正文
最近一段时间做的需求主要是适配 kylinsec 国产化操作系统. 因为产品是 tob 私有化部署 k8s 集群,并且多机器需要同步时间。经过调研后发现 chrony 已经作为 redhat 8 等多种发行版的默认选项,决定统一使用 chrony 作为我们的时间同步 daemon.
应用的自动化部署方案使用了 ansible,不同 Linux 发行版软件包不相同,所以适配一种 Linux 发行版,就需要为这种 Linux 发行版下载对应软件包。比如 chrony 在 centos 7/8/9, ubuntu 20.04/18.04, kylinsec … 等都需要单独下载一遍 chrony 安装包,整体总共适配了 6 遍,十分麻烦。当需要适配的软件包更多后,成本就凸显出来了. 可以选择静态编译,抹平各发行版的差异,一次搞定。
还好,静态编译的工作已经有大佬做过了静态编译 chrony,
dockerfile 如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
# docker buildx build -f Dockerfile.chrony --platform linux/amd64 --target bin --output installer
FROM ubuntu:20.04 as build
ARG branch=4.2
ENV DEBIAN_FRONTEND noninteractive
RUN sed -ri 's/(ports|deb|security|archive).(debian.org|ubuntu.com)/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list \
&& apt-get update
WORKDIR /opt
# COPY chrony . # 二选一
#RUN apt-get install -y git && git clone --branch ${branch} https://git.tuxfamily.org/chrony/chrony.git
RUN apt-get install -y wget && wget https://download.tuxfamily.org/chrony/chrony-${branch}.tar.gz \
&& tar zxf chrony-${branch}.tar.gz \
&& mv chrony-${branch} chrony \
&& rm -f chrony-${branch}.tar.gz
RUN apt-get install -y \
bison asciidoctor \
gcc \
make \
pkg-config \
libcap-dev \
pps-tools \
libedit-dev \
nettle-dev \
libnss3-dev \
libtomcrypt-dev \
libgnutls28-dev \
libseccomp-dev
RUN cd chrony; \
CFLAGS='-static -s' LDFLAGS='-static -lm' \
./configure \
--enable-scfilter \
--enable-ntp-signd \
&& make; echo $?; \
mkdir -p /install_root; \
make DESTDIR=/install_root install \
&& find /install_root
RUN rm -rf /install_root/usr/local/share \
&& rmdir /install_root/var/lib/chrony/ /install_root/etc
FROM scratch AS bin
COPY --from=build /install_root /
|
buildx 一步编译出软件包
1
2
3
4
5
6
7
8
|
docker buildx build -f Dockerfile.chrony --platform linux/amd64 --target bin --output installer
file installer/{usr/local/bin/chronyc,usr/local/sbin/chronyd}
installer/usr/local/bin/chronyc: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=a8851c783b1074f3414d8b38bb337cb10a8b016d, for GNU/Linux 3.2.0, stripped
installer/usr/local/sbin/chronyd: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=a7ed52ca561252969d5e0f29b8894380b70bd8c5, for GNU/Linux 3.2.0, stripped
# 多平台编译
docker buildx build . --platform linux/amd64,linux/arm64 --target bin --output installer
|
有了二进制文件该如何部署服务呢?
如下是写好的 systemd service 文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
cat <<EOF >/etc/chrony.conf
# Generated by TODO
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
server pool.ntp.org iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
# Enable kernel synchronization of the real-time clock (RTC).
rtcsync
allow 0.0.0.0/0
local stratum 10
logdir /var/log/chrony
log measurements statistics tracking
EOF
cat <<EOF >/etc/chrony.keys
# This file is solely used for NTP authentication with symmetric keys
# as defined by RFC 1305 and RFC 5905.
#
# It can contain ID/key pairs which can be generated using the “keygen” option
# from “chronyc”; for example:
# chronyc keygen 1 SHA256 256 >> /etc/chrony/chrony.keys
# would generate a 256-bit SHA-256 key using ID 1.
#
# A list of supported hash functions and output encoding is available by
# consulting the "keyfile" directive in the chrony.conf(5) man page.
EOF
cat <<EOF >/etc/systemd/system/chrony.service
[Unit]
Description=chrony, an NTP client/server
Documentation=man:chronyd(8) man:chronyc(1) man:chrony.conf(5)
Conflicts=openntpd.service ntp.service ntpsec.service systemd-timesyncd.service
Wants=time-sync.target
Before=time-sync.target
After=network.target
# ConditionCapability=CAP_SYS_TIME
[Service]
# Type=forking
# PIDFile=/run/chronyd.pid
# EnvironmentFile=-/etc/default/chrony
# Starter takes care of special cases mostly for containers
ExecStart=/usr/sbin/chronyd -F -0 -d -f /etc/chrony.conf
PrivateTmp=yes
ProtectHome=yes
ProtectSystem=full
[Install]
Alias=chronyd.service
WantedBy=multi-user.target
EOF
systemctl enable --now chrony
|
到这里就可以了吗?
当我们执行 timedatectl set-ntp off
后, chronyd 服务并没有按照预期停止时间同步。根据文档 timedated , 命令 timedatectl set-ntp off
会启动或停止 systemd-timedated.service
; 文档 systemd-timedated.service 描述, systemd-timedated.service 会从 /usr/lib/systemd/ntp-units.d/50-chronyd.list
文件中启停系统时间同步服务。当前使用的时间服务是 chrony,需要覆盖文件/usr/lib/systemd/ntp-units.d/50-chronyd.list
中的值,使得 timedatectl set-ntp off
能够按照预期启停时间同步.
1
|
echo 'chrony.service' >/usr/lib/systemd/ntp-units.d/50-chronyd.list
|
到这里,chrony 正式工作了.
安装 chrony service 的完整脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
#!/usr/bin/env bash
set -o errtrace
set -o errexit
set -o nounset
set -o pipefail
set -o xtrace
cd $(dirname "$0")
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root"
exit 1
fi
DIR=$(dirname $(realpath $0))
install_chrony() {
systemctl stop chrony || true
systemctl disable chrony || true # 向前兼容 ubuntu 20.04 中可能会安装有 chrony
systemctl stop chronyd || true
systemctl disable chronyd || true
# ubuntu 20.04 中会有此服务
systemctl stop systemd-timesyncd || true
systemctl disable systemd-timesyncd || true
chown root:root /var/run/chrony || true
# for chrony logdir on ubuntu
rm -rf /var/log/chrony
mkdir -p /var/log/chrony
mkdir -p /var/lib/chrony/
mkdir -p /etc/chrony/
# ubuntu 默认的配置文件位置是 /etc/chrony/chrony.conf
# centos7 默认的配置文件位置是 /etc/chrony.conf
test -f "/etc/chrony/chrony.conf" && mv /etc/chrony/chrony.conf /etc/chrony/chrony.conf.$(date "+%Y-%m-%d_%H%M%S").bak
test -f /etc/chrony.conf && mv /etc/chrony.conf /etc/chrony.conf.$(date "+%Y-%m-%d_%H%M%S").bak
ln -s -f /etc/chrony.conf /etc/chrony/chrony.conf
cat <<EOF >/etc/chrony.conf
# Generated by TODO
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
server pool.ntp.org iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
# Enable kernel synchronization of the real-time clock (RTC).
rtcsync
allow 0.0.0.0/0
local stratum 10
logdir /var/log/chrony
log measurements statistics tracking
EOF
cat <<EOF >/etc/chrony.keys
# This file is solely used for NTP authentication with symmetric keys
# as defined by RFC 1305 and RFC 5905.
#
# It can contain ID/key pairs which can be generated using the “keygen” option
# from “chronyc”; for example:
# chronyc keygen 1 SHA256 256 >> /etc/chrony/chrony.keys
# would generate a 256-bit SHA-256 key using ID 1.
#
# A list of supported hash functions and output encoding is available by
# consulting the "keyfile" directive in the chrony.conf(5) man page.
EOF
cat <<EOF >/etc/systemd/system/chrony.service
[Unit]
Description=chrony, an NTP client/server
Documentation=man:chronyd(8) man:chronyc(1) man:chrony.conf(5)
Conflicts=openntpd.service ntp.service ntpsec.service systemd-timesyncd.service
Wants=time-sync.target
Before=time-sync.target
After=network.target
# ConditionCapability=CAP_SYS_TIME
[Service]
# Type=forking
# PIDFile=/run/chronyd.pid
# EnvironmentFile=-/etc/default/chrony
# Starter takes care of special cases mostly for containers
ExecStart=/usr/sbin/chronyd -F -1 -d -f /etc/chrony.conf
PrivateTmp=yes
ProtectHome=yes
ProtectSystem=full
[Install]
Alias=chronyd.service
WantedBy=multi-user.target
EOF
cp usr/local/sbin/chronyd /usr/sbin/chronyd
cp usr/local/bin/chronyc /usr/bin/chronyc
# timedatectl set-ntp off 会触发
# http://www.freedesktop.org/wiki/Software/systemd/timedated
# systemctl status systemd-timedated
# https://www.freedesktop.org/software/systemd/man/systemd-timedated.service.html#
# STEP: centos7.9
ls /usr/lib/systemd/ntp-units.d/
echo 'chrony.service' >/usr/lib/systemd/ntp-units.d/50-chronyd.list || true
# /usr/sbin/chronyd -f /etc/chrony/chrony.conf -d -R
systemctl enable --now chrony || true
systemctl restart chrony
}
install_chrony
|
参考