Truy tìm những “bóng ma” trong tệp tin Log
Không có gì khó chịu hơn việc phải truy tìm một “bóng ma” trong các tệp tin log. Hãy tưởng tượng bạn đang debug một lỗi cơ sở dữ liệu trên một cụm (cluster) gồm ba nút. Bạn kiểm tra Máy chủ A, sau đó chuyển sang Máy chủ B để tìm sự kiện tương ứng. Thật ngạc nhiên, log của Máy chủ B lại khẳng định sự kiện đó đã xảy ra hai giây trước khi nó bắt đầu trên Máy chủ A. Sự sai lệch này khiến việc truy vết các giao dịch hoặc sự kiện bảo mật trở thành một cơn ác mộng.
Gần đây tôi đã xử lý một sự cố trên môi trường production gây ra bởi sự sai lệch chỉ vỏn vẹn 500ms. Khoảng cách nhỏ nhoi đó đã khiến các mã thông báo JSON Web Tokens (JWT) hết hạn sớm vì máy chủ xác thực chạy nhanh hơn một chút so với máy chủ ứng dụng. Những lỗi “du hành thời gian” này rất phổ biến trong các hệ thống phân tán. Chúng dẫn đến hỏng dữ liệu, sao lưu thất bại và phá hỏng các giao thức xác thực.
Tại sao đồng hồ trên Linux lại chạy sai
Trước khi khắc phục sự sai lệch, chúng ta cần phân biệt giữa hai loại đồng hồ mà máy chủ của bạn quản lý:
- Đồng hồ phần cứng (RTC): Đây là đồng hồ chạy bằng pin trên bo mạch chủ. Nó duy trì thời gian ngay cả khi tắt nguồn.
- Đồng hồ hệ thống: Được duy trì bởi nhân (kernel) Linux. Nó cung cấp dấu thời gian (timestamp) được sử dụng bởi các ứng dụng, log và các tác vụ cron.
Phần cứng không bao giờ hoàn hảo. Các bộ dao động thạch anh trong hầu hết các bo mạch chủ đều nhạy cảm với nhiệt độ và tuổi thọ. Một máy chủ thông thường có thể bị trôi từ 10 đến 20 giây mỗi tháng nếu không có đồng bộ hóa bên ngoài. Việc ảo hóa còn làm tình hình tệ hơn. Trong môi trường AWS hoặc GCP, CPU được chia sẻ. Các “nhịp” (ticks) mà đồng hồ hệ thống dựa vào có thể bị trì hoãn hoặc bị bỏ qua hoàn toàn, gây ra hiện tượng trôi thời gian nhanh chóng.
Mặc dù giao thức Network Time Protocol (NTP) tiêu chuẩn đã được thiết kế từ nhiều thập kỷ trước, nó gặp khó khăn với các thách thức hiện đại. Nó thường thất bại trong việc xử lý các kết nối mạng chập chờn hoặc các hệ thống thường xuyên vào chế độ ngủ (sleep mode). Chrony được xây dựng để giải quyết chính xác những vấn đề này.
NTP và Chrony: Sự lựa chọn tối ưu hơn
NTP là giao thức, nhưng phần mềm triển khai nó đã thay đổi. Trong nhiều năm, ntpd là lựa chọn mặc định. Tuy nhiên, các bản phân phối hiện đại như Ubuntu, RHEL và Fedora đã chuyển sang chronyd (Chrony). Đây là lý do tại sao sự thay đổi này lại quan trọng:
- Đồng bộ hóa nhanh chóng: Chrony đồng bộ đồng hồ trong vài giây thay vì vài phút. Đây là cứu cánh cho các instance đám mây thường xuyên được khởi tạo và hủy bỏ.
- Bù đắp sai lệch: Chrony tính toán tốc độ chính xác mà đồng hồ của bạn chạy nhanh hoặc chậm. Nó tiếp tục điều chỉnh đồng hồ ngay cả khi mất kết nối mạng.
- Tối ưu cho ảo hóa: Nó xử lý hiện tượng “jitter” (độ trễ không ổn định) của phần cứng ảo hóa mượt mà hơn nhiều so với daemon NTP cũ.
Trên các nút Ubuntu 22.04 production của tôi, việc chuyển sang Chrony đã loại bỏ các bước nhảy thời gian đột ngột từng gây treo các tác vụ chạy ngầm nhạy cảm. Hệ thống hiện điều chỉnh thời gian một cách mượt mà bằng cách tăng hoặc giảm tốc độ đồng hồ một chút.
Thiết lập thực tế: Triển khai Chrony
Chrony thường đã có sẵn trong trình quản lý gói của bạn. Hãy làm theo các bước sau để nó hoạt động chính xác.
1. Cài đặt gói
Trước tiên, hãy gỡ bỏ bất kỳ dịch vụ NTP cũ nào để tránh xung đột. Sau đó, cài đặt Chrony.
# Dành cho Ubuntu/Debian
sudo apt update && sudo apt install chrony -y
# Dành cho RHEL/CentOS/AlmaLinux
sudo dnf install chrony -y
2. Cấu hình các máy chủ nguồn đáng tin cậy
Tệp cấu hình của bạn nằm tại /etc/chrony/chrony.conf (Ubuntu) hoặc /etc/chrony.conf (RHEL). Mở nó bằng trình chỉnh sửa:
sudo nano /etc/chrony/chrony.conf
Tìm các dòng bắt đầu bằng pool. Để có kết quả tốt nhất, hãy sử dụng các máy chủ gần về mặt địa lý với trung tâm dữ liệu của bạn. Nếu máy chủ của bạn ở Bắc Mỹ, hãy sử dụng các dòng sau:
# Sử dụng các máy chủ công cộng từ dự án pool.ntp.org.
pool 0.north-america.pool.ntp.org iburst
pool 1.north-america.pool.ntp.org iburst
pool 2.north-america.pool.ntp.org iburst
Chỉ thị iburst rất quan trọng. Nó yêu cầu Chrony gửi một loạt yêu cầu dồn dập khi khởi động, đảm bảo máy chủ của bạn tìm thấy thời gian chính xác chỉ trong vài giây.
3. Khởi động lại dịch vụ
sudo systemctl enable --now chrony
sudo systemctl restart chrony
Kiểm tra trạng thái đồng bộ
Đừng chỉ giả định rằng nó đang hoạt động. Chrony đi kèm với một công cụ dòng lệnh tiện lợi gọi là chronyc để kiểm tra sức khỏe thời gian của bạn.
Kiểm tra các nguồn thời gian
Kiểm tra kết nối của bạn với các máy chủ nguồn bằng lệnh này:
chronyc sources -v
Hãy tìm ký hiệu ^*. Điều này có nghĩa là Chrony đã chọn máy chủ đó làm nguồn chính. Nếu bạn thấy ^?, máy chủ đó không thể kết nối được. Ký hiệu ^x chỉ ra một “falseticker” — một máy chủ có thời gian sai lệch quá lớn không thể tin cậy.
Theo dõi độ trôi của đồng hồ
Để xem đồng hồ cục bộ của bạn đang hoạt động tốt như thế nào, hãy kiểm tra dữ liệu theo dõi:
chronyc tracking
Hãy tập trung vào giá trị RMS offset. Giá trị này đại diện cho sự chênh lệch trung bình dài hạn giữa hệ thống của bạn và thời gian thực tế. Trong một thiết lập ổn định, giá trị này nên ở mức micro giây hoặc mili giây thấp.
Trường hợp đặc biệt trên Cloud: AWS và GCP
Các nhà cung cấp đám mây thường cung cấp các nguồn thời gian độ chính xác cao của riêng họ. Ví dụ, AWS cung cấp Amazon Time Sync Service tại địa chỉ 169.254.169.123. IP nội bộ này cung cấp độ trễ cực thấp, thường dưới 1ms. Nếu bạn đang sử dụng EC2, hãy thêm dòng này vào đầu tệp cấu hình của bạn:
# Sử dụng nguồn thời gian nội bộ của AWS để đạt độ chính xác dưới 1 mili giây
server 169.254.169.123 prefer iburst minpoll 4 maxpoll 4
Tổng kết
Đồng bộ hóa thời gian không chỉ là để có giờ giấc chính xác trên thanh tác vụ. Đó là yêu cầu cơ bản đối với bảo mật, logging và tính toàn vẹn của cơ sở dữ liệu. Bằng cách chuyển sang Chrony và theo dõi các độ lệch (offset), bạn bảo vệ cơ sở hạ tầng của mình khỏi những tác động ngầm nhưng đầy tai hại của hiện tượng trôi thời gian. Hãy kiểm tra chronyc tracking ngay hôm nay; các tệp tin log sẽ cảm ơn bạn.

