Hướng dẫn cài đặt và cấu hình Chrony trên Ubuntu Server: Đồng bộ thời gian chuẩn xác cho hệ thống phân tán

Ubuntu tutorial - IT technology blog
Ubuntu tutorial - IT technology blog

Vì sao hệ thống phân tán không thể sống thiếu đồng bộ thời gian?

Tưởng tượng bạn đang trực ca lúc 2 giờ sáng để debug một cụm PostgreSQL Replication hay Kafka. Mở Grafana và Jaeger lên, bạn thấy một hiện tượng kỳ quặc: API downstream trả response về trước cả lúc upstream gửi request đi. Nguyên nhân chẳng đâu xa lạ. Đồng hồ giữa hai server đang lệch nhau 3 giây.

Lệch vài giây khi đọc log đã phiền, nhưng rơi vào tầng lưu trữ dữ liệu thì thực sự nguy hiểm. Các database dùng cơ chế Last-Write-Wins (như Cassandra hay Couchbase) dựa hoàn toàn vào timestamp để phân xử record nào mới nhất.

Giả sử node A chạy nhanh hơn node B 500ms, dữ liệu ghi mới tại node B sẽ bị bản ghi cũ hơn từ node A đè bẹp. Chưa kể, giao thức Kerberos hay token JWT sẽ từ chối request ngay lập tức nếu clock drift vượt quá ngưỡng cho phép (thường là 300 giây hoặc siết chặt về mức vài giây).

Ubuntu cài sẵn systemd-timesyncd. Dịch vụ này vừa đủ cho laptop cá nhân hay VPS chạy web tĩnh. Nhưng đưa vào cụm database hay Kubernetes, nó bộc lộ ngay 3 điểm yếu chí mạng:

  • Bản chất chỉ là SNTP client rút gọn, không thể đo lường hay bù trừ độ trôi tần số (drift rate) của thạch anh phần cứng.
  • Đồng bộ ngắt quãng theo từng đợt lớn, dễ gây bước nhảy thời gian đột ngột (step time) khiến MySQL hoặc PostgreSQL hoảng loạn treo connection.
  • Không hỗ trợ phát sóng làm local NTP server cho các máy nội bộ trong cùng subnet.

Chrony giải quyết trọn vẹn những điểm này. Công cụ này bắt mốc giờ nhanh hơn NTPd truyền thống, giữ sai số ổn định ở mức vài micro-giây. Quan trọng nhất, Chrony điều chỉnh giờ bằng cách co giãn nhịp đồng hồ mượt mà (slewing), triệt tiêu hoàn toàn nguy cơ giật lùi kim thời gian.

Tắt timesyncd và cài đặt Chrony trên Ubuntu

Hai tiến trình đồng bộ chạy song song sẽ tranh chấp cổng UDP 123 và can thiệp lẫn nhau vào kernel clock. Vì vậy, việc đầu tiên cần làm là vô hiệu hóa hoàn toàn systemd-timesyncd:

sudo timedatectl set-ntp false
sudo systemctl stop systemd-timesyncd
sudo systemctl disable systemd-timesyncd

Kế tiếp, kéo package chrony từ kho chính thức của Ubuntu về máy:

sudo apt update && sudo apt install -y chrony

Kiểm tra nhanh xem tiến trình nền đã nhận việc hay chưa:

sudo systemctl status chrony

Dòng trạng thái báo active (running) màu xanh là bạn đã sẵn sàng sang bước tinh chỉnh file cấu hình.

Thiết lập Chrony cho Server và Client nội bộ

File cấu hình chính nằm tại đường dẫn /etc/chrony/chrony.conf. Với hạ tầng thực tế gồm 30 node Kubernetes và cụm PostgreSQL chạy Ubuntu 22.04 LTS, bộ cấu hình dưới đây giúp giữ độ lệch thời gian luôn dưới 1.5ms.

Mở file bằng trình soạn thảo quen thuộc:

sudo nano /etc/chrony/chrony.conf

1. Cấu hình Chrony làm Client đồng bộ thời gian

Hãy tìm các dòng khai báo pool mặc định. Bạn nên thay bằng NTP pool gần vị trí địa lý của datacenter, hoặc tận dụng NTP server nội bộ của nhà cung cấp cloud (như AWS Time Sync 169.254.169.123 hay Google NTP metadata.google.internal):

# Sử dụng pool máy chủ gần nhất (Việt Nam / Châu Á)
pool vn.pool.ntp.org iburst maxsources 4

# Bổ sung các mốc quốc tế có Anycast network cực mạnh
server time.cloudflare.com iburst
server time.google.com iburst

# Chỉ cho phép nhảy giờ nếu lệch > 1s trong 3 lần cập nhật đầu lúc boot máy
makestep 1.0 3

# Định kỳ đồng bộ giờ chuẩn xuống Real-Time Clock của bo mạch
rtcsync

Những tùy chọn này hoạt động ra sao?

  • iburst: Bắn liên tiếp 4 đến 8 gói tin thăm dò ngay khi vừa khởi động service. Nhờ đó, máy chủ chốt mốc giờ chuẩn chỉ sau 2-3 giây thay vì đợi vài phút.
  • makestep 1.0 3: Cho phép bước nhảy (step) tức thì nếu phát hiện lệch trên 1 giây trong 3 nhịp đầu. Hết 3 nhịp này, Chrony chuyển hẳn sang cơ chế trượt (slew) từ từ để tránh làm crash các service nhạy cảm với thời gian.
  • rtcsync: Ghi nhận giờ chuẩn trực tiếp vào chip RTC của mainboard. Khi reboot, BIOS vẫn giữ mốc giờ chính xác nhất có thể.

2. Biến Chrony thành Time Master cho mạng nội bộ (LAN / Private VPC)

Mô hình 100 máy chủ cùng bắn request ra ngoài Internet để hỏi giờ rất dễ dính rate-limit và ngốn NAT bandwidth. Cách làm chuẩn trong production: Chọn 2 máy làm Chrony Master hứng giờ từ public pool, toàn bộ 98 node còn lại chỉ trỏ về IP private của 2 máy này.

Thêm hai dòng sau vào cuối file /etc/chrony/chrony.conf trên 2 máy Master:

# Cấp quyền cho subnet nội bộ hỏi giờ qua cổng UDP 123
allow 192.168.1.0/24

# Nếu đứt cáp quang ra Internet, Master vẫn tiếp tục cấp giờ cho các client nội bộ
local stratum 10

Khởi động lại daemon để ăn cấu hình mới:

sudo systemctl restart chrony

Đừng quên mở tường lửa UFW trên máy Master nếu có bật:

sudo ufw allow 123/udp comment 'Chrony NTP Service'

Giám sát và kiểm tra độ lệch thời gian thực tế

Chrony đi kèm bộ CLI chronyc để kiểm tra chất lượng đồng bộ.

Xem danh sách nguồn thời gian (Sources)

chronyc sources -v

Bảng kết quả trả về tương tự như sau:

  .-- Source mode  '^' = server, '=' = peer, '#' = local clock.
 / .- Source state '*' = current best, '+' = combined, '-' = not combined,
| /             'x' = may be in error, '~' = too variable, '?' = unusable.
||                                                 .- xxxx [ -xx ] +/- dddd
||      Reachability register (octal) -.           |  xxxx = adjusted offset
||      Log2(interval) -+              |           |  xx   = measured offset
||                      \             |           |  dddd = error bound
||                       \            |           |  
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^* time.cloudflare.com           3   6   377    25   -120us[ -140us] +/-   12ms
^+ time.google.com               1   6   377    24   +310us[ +290us] +/-   18ms
^+ 118.107.240.230               2   6   377    26    -45us[  -65us] +/-   22ms

Bốn cột cần quan sát:

  • Ký hiệu ^*: Nguồn chính đang được Chrony chọn để bám giờ (System Peer).
  • Ký hiệu ^+: Nguồn dự phòng đạt chuẩn, sẵn sàng thay thế nếu nguồn chính mất kết nối.
  • Cột Reach: Con số 377 (hệ bát phân) đại diện cho 8 lần gửi gói tin gần nhất đều nhận phản hồi toàn vẹn (tương đương 100% uptime).
  • Cột Last sample: Mức chênh lệch thực tế. Con số -120us cho thấy đồng hồ chỉ lệch 0.12 mili-giây so với chuẩn quốc tế.

Theo dõi thông số trôi dạt của kernel (Tracking)

Muốn biết sức khỏe tổng thể của clock trên OS, gõ lệnh:

chronyc tracking
Reference ID    : A29FC801 (time.cloudflare.com)
Stratum         : 4
Ref time (UTC)  : Mon Oct 12 10:45:00 2026
System time     : 0.000045123 seconds slow of NTP time
Last offset     : -0.000012450 seconds
RMS offset      : 0.000065201 seconds
Frequency       : 12.450 ppm fast
Residual freq   : -0.002 ppm
Skew            : 0.045 ppm
Update interval : 64.2 seconds
Leap status     : Normal

Tập trung vào 2 chỉ số cốt lõi:

  • System time: Độ lệch tức thời giữa OS và mốc chuẩn. Trên môi trường production, hãy alert qua Prometheus/Alertmanager nếu giá trị này vượt quá 0.005 giây (5ms).
  • RMS offset: Độ lệch bình phương trung bình trong suốt thời gian vận hành. Giá trị này càng thấp chứng tỏ tần số dao động của clock càng phẳng và ổn định.

Chỉ cần 15 phút cấu hình đúng Chrony, bạn đã loại bỏ được hàng loạt lỗi ngầm khó chịu về dữ liệu, giúp việc trace log và vận hành cụm server phân tán trở nên nhẹ nhàng hơn rất nhiều.

Share: