เวลาที่ไม่ตรงกันบน Server ก่อให้เกิดปัญหาซ่อนเร้นมากมาย ตั้งแต่ Certificate ที่ถูก Reject เพราะเวลาของ Client ไม่ตรงกับ CA, Log ที่ Timestamp ไม่เรียงตามลำดับทำให้ Debug ยาก ไปจนถึง Cron Job ที่รันผิดเวลา NTP (Network Time Protocol) คือโปรโตคอลมาตรฐานในการซิงค์เวลาของ Server ให้ตรงกับ Time Source ที่เชื่อถือได้
บทความนี้อธิบายการตั้งค่า NTP บน Linux ด้วย systemd-timesyncd (ค่าเริ่มต้นบน Ubuntu/Debian), chrony (แนะนำสำหรับ Production), และ ntpd แบบ Classic รวมถึงการตั้งค่า Timezone, ตรวจสอบสถานะการซิงค์ และแนวทาง Troubleshoot เมื่อเวลาคลาดเคลื่อน
ทำไมเวลาที่แม่นยำถึงสำคัญ
# ตัวอย่างปัญหาที่เกิดจากเวลาไม่ตรง:
# 1. TLS/SSL Certificate — เวลาต่างกันเกิน 5 นาที
# ERROR: certificate is not yet valid / has expired
# 2. Kerberos Authentication — เวลาต่างกันเกิน 5 นาที
# KDC_ERR_SKEW — Clock skew too great
# 3. Log Correlation — Timestamp ไม่เรียง
# Server A: 10:00:05 — Request received
# Server B: 09:59:58 — Response sent (ดูเหมือน Response ก่อน Request!)
# 4. Distributed Systems — Race condition จากเวลาไม่ตรง
# Database Replication, Kafka Offset, Git Commit Order
# 5. Cron Jobs — รันผิดเวลา
# ถ้าเวลาเร็วกว่า 1 ชั่วโมง — Job รันก่อนกำหนด
ตรวจสอบสถานะเวลาปัจจุบัน
# ดูเวลาและ Timezone ปัจจุบัน
date
date +"%Y-%m-%d %H:%M:%S %Z"
# ดูสถานะ Time Sync อย่างละเอียด
timedatectl
timedatectl status
# ตัวอย่าง Output:
# Local time: Thu 2026-04-16 15:30:00 ICT
# Universal time: Thu 2026-04-16 08:30:00 UTC
# RTC time: Thu 2026-04-16 08:30:00
# Time zone: Asia/Bangkok (ICT, +0700)
# System clock synchronized: yes
# NTP service: active
# RTC in local TZ: no
# ดู Hardware Clock (RTC)
hwclock --show
hwclock --show --utc # แสดงเป็น UTC
ตั้งค่า Timezone
# ดู Timezone ปัจจุบัน
timedatectl | grep "Time zone"
# ค้นหา Timezone ที่ต้องการ
timedatectl list-timezones | grep Asia
timedatectl list-timezones | grep Bangkok
# ตั้ง Timezone
sudo timedatectl set-timezone Asia/Bangkok
# ตรวจสอบ
timedatectl | grep "Time zone"
# Time zone: Asia/Bangkok (ICT, +0700)
# วิธีเดิม (ไม่ใช้ timedatectl)
sudo ln -sf /usr/share/zoneinfo/Asia/Bangkok /etc/localtime
echo "Asia/Bangkok" | sudo tee /etc/timezone
# Timezone ที่ใช้บ่อยในไทย:
# Asia/Bangkok = ICT (UTC+7) — ไทย, เวียดนาม, ลาว
# Asia/Singapore = SGT (UTC+8) — สิงคโปร์
# UTC = UTC+0 — แนะนำสำหรับ Production Server
systemd-timesyncd — NTP Client เบาบาง
systemd-timesyncd เป็น NTP Client แบบ Lightweight ที่มาพร้อม systemd เหมาะสำหรับ Client Machine หรือ Server ที่ต้องการแค่ซิงค์เวลาง่าย ๆ ไม่ได้ทำหน้าที่เป็น NTP Server
# ตรวจสอบสถานะ
systemctl status systemd-timesyncd
# เปิดใช้งาน
sudo systemctl enable --now systemd-timesyncd
# ดูสถานะการซิงค์
timedatectl timesync-status
# ตัวอย่าง Output:
# Server: 162.159.200.123 (0.ubuntu.pool.ntp.org)
# Poll interval: 34min 8s (min: 32s; max 34min 8s)
# Leap: normal
# Version: 4
# Stratum: 3
# Reference: 0A0A0A0A
# Precision: 1us (-20)
# Root distance: 30.394ms (max: 5s)
# Offset: +1.234ms
# Delay: 12.567ms
# Jitter: 0.456ms
# Packet count: 7
กำหนด NTP Server ใน systemd-timesyncd
# แก้ไข /etc/systemd/timesyncd.conf
sudo nano /etc/systemd/timesyncd.conf
# ตัวอย่างการตั้งค่า
[Time]
NTP=th.pool.ntp.org 0.th.pool.ntp.org
FallbackNTP=ntp.ubuntu.com 0.ubuntu.pool.ntp.org
RootDistanceMaxSec=5
PollIntervalMinSec=32
PollIntervalMaxSec=2048
# Restart service
sudo systemctl restart systemd-timesyncd
# ตรวจสอบ
timedatectl timesync-status
chrony — NTP ที่แนะนำสำหรับ Production
chrony เป็น NTP Implementation ที่ทันสมัยกว่า ntpd รองรับการซิงค์ที่เร็วกว่าเมื่อเวลาคลาดเคลื่อนมาก และเหมาะกับ Server ที่มี Intermittent Connection หรือ VM ที่มีการ Suspend/Resume เป็นค่าเริ่มต้นบน RHEL/Rocky Linux
# ติดตั้ง chrony
sudo apt install chrony # Ubuntu/Debian
sudo dnf install chrony # RHEL/Rocky
# เปิดใช้งาน
sudo systemctl enable --now chronyd
# ตรวจสอบสถานะ
chronyc tracking
# ตัวอย่าง Output:
# Reference ID : 9F7C1C00 (th.pool.ntp.org)
# Stratum : 3
# Ref time (UTC) : Thu Apr 16 08:30:00 2026
# System time : 0.000001234 seconds slow of NTP time
# Last offset : +0.000001234 seconds
# RMS offset : 0.000002345 seconds
# Frequency : 1.234 ppm fast
# Residual freq : +0.001 ppm
# Skew : 0.234 ppm
# Root delay : 0.012345678 seconds
# Root dispersion : 0.000345678 seconds
# Update interval : 64.0 seconds
# Leap status : Normal
ตั้งค่า chrony
# แก้ไข /etc/chrony.conf (RHEL) หรือ /etc/chrony/chrony.conf (Ubuntu)
sudo nano /etc/chrony/chrony.conf
# ตัวอย่างการตั้งค่า
# NTP Server Pool ของประเทศไทย
pool th.pool.ntp.org iburst maxsources 4
# หรือระบุ Server แยกกัน
server 0.th.pool.ntp.org iburst
server 1.th.pool.ntp.org iburst
server time.cloudflare.com iburst
# อนุญาต Network ภายในใช้เป็น NTP Server (ถ้าต้องการ)
# allow 192.168.1.0/24
# Log ไฟล์
logdir /var/log/chrony
# ค่าแนะนำ
makestep 1.0 3 # ซิงค์เร็วถ้าต่างเกิน 1 วิใน 3 ครั้งแรก
rtcsync # Sync Hardware Clock ด้วย
# Restart chrony
sudo systemctl restart chronyd
# ตรวจสอบ NTP Server ที่ใช้
chronyc sources -v
# ตัวอย่าง Output:
# MS Name/IP address Stratum Poll Reach LastRx Last sample
# ===============================================================================
# ^* th.pool.ntp.org 2 6 377 35 +0.456ms[+0.567ms] +/- 15ms
# ^- 0.th.pool.ntp.org 2 7 377 135 -1.234ms[-1.123ms] +/- 20ms
#
# * = NTP Server ที่ใช้งานอยู่
# - = Acceptable แต่ไม่ได้เลือก
คำสั่ง chronyc ที่ใช้บ่อย
# ดูสถานะการซิงค์
chronyc tracking
# ดู NTP Server ทั้งหมด
chronyc sources
chronyc sources -v # Verbose
# ดูสถิติ Offset/Drift
chronyc sourcestats
chronyc sourcestats -v
# บังคับซิงค์ทันที (ถ้าต่างมาก)
sudo chronyc makestep
# ดู Activity Log
chronyc activity
# ตรวจสอบว่า NTP กำลังทำงานหรือไม่
chronyc ntpdata
ตั้ง chrony เป็น NTP Server ภายใน
บน Infrastructure ที่มีหลาย Server การตั้ง Server หนึ่งเป็น NTP Server ภายใน แล้วให้ Server อื่นซิงค์มาที่ Internal NTP Server ช่วยลด Load บน Public NTP Pool และให้ทุก Server ใช้เวลาจากแหล่งเดียวกัน
# /etc/chrony/chrony.conf — ตั้งค่า NTP Server ภายใน
# ซิงค์จาก Public NTP
pool th.pool.ntp.org iburst maxsources 4
# อนุญาต Client ภายในซิงค์จาก Server นี้
allow 192.168.1.0/24
allow 10.0.0.0/8
# ถ้า Internet ขาด ยังให้เวลาจาก Local Clock (Stratum 10)
local stratum 10
sudo systemctl restart chronyd
# เปิด Firewall Port 123/UDP
sudo ufw allow 123/udp
# หรือ
sudo firewall-cmd --add-service=ntp --permanent
sudo firewall-cmd --reload
# ตั้งค่า Client ให้ซิงค์จาก Internal NTP Server
# /etc/chrony/chrony.conf บน Client
server 192.168.1.10 iburst prefer # Internal NTP Server
pool th.pool.ntp.org iburst # Fallback
# ตรวจสอบว่า Client ซิงค์จาก Internal Server
chronyc sources | grep 192.168.1.10
ตั้ง Timezone สำหรับ Application เฉพาะ
# System Timezone ควรเป็น UTC บน Production Server
# แต่ Application สามารถกำหนด Timezone เองได้
# Environment Variable สำหรับ Process เดียว
TZ="Asia/Bangkok" date
# ตั้ง TZ ใน .bashrc/.profile
echo 'export TZ="Asia/Bangkok"' >> ~/.bashrc
# ตั้งใน systemd Service Unit
# /etc/systemd/system/myapp.service
# [Service]
# Environment=TZ=Asia/Bangkok
# PHP — ตั้งใน php.ini
# date.timezone = Asia/Bangkok
# MySQL — ตั้งใน my.cnf
# [mysqld]
# default-time-zone = '+07:00'
# PostgreSQL — ตั้งใน postgresql.conf
# timezone = 'Asia/Bangkok'
Troubleshoot ปัญหาเวลาไม่ตรง
# Step 1: ตรวจสอบสถานะ Time Sync
timedatectl status
# ถ้า "System clock synchronized: no" → ปัญหา NTP
# Step 2: ตรวจสอบ Service
systemctl status systemd-timesyncd # Ubuntu (default)
systemctl status chronyd # RHEL หรือถ้าติดตั้ง chrony
# Step 3: ตรวจสอบว่าสื่อสารกับ NTP Server ได้
# ทดสอบ UDP Port 123
nc -zuv pool.ntp.org 123
# ทดสอบด้วย ntpdate (ถ้าติดตั้ง)
sudo ntpdate -q pool.ntp.org
# Step 4: ดู Log
journalctl -u systemd-timesyncd -f
journalctl -u chronyd -f
# Step 5: ตรวจสอบ Firewall
# NTP ใช้ UDP Port 123 — ต้องไม่ถูกบล็อก Outbound
sudo iptables -L OUTPUT -n | grep 123
# Step 6: บังคับซิงค์
# systemd-timesyncd
sudo systemctl restart systemd-timesyncd
# chrony — บังคับ Step (ซิงค์ทันทีแม้ต่างมาก)
sudo chronyc makestep
# ntpdate (deprecated แต่ยังใช้ได้)
sudo ntpdate pool.ntp.org
ปัญหาที่พบบ่อย
# ปัญหา 1: VM ที่เวลาคลาดเคลื่อนหลัง Suspend/Resume
# Symptom: เวลาแช่แข็งตอน Suspend
# Fix: chrony จัดการได้ดีกว่า ntpd ในกรณีนี้
# ใน /etc/chrony/chrony.conf เพิ่ม:
# makestep 1 -1 # ซิงค์เร็วเสมอไม่จำกัดครั้ง
# ปัญหา 2: NTP กับ Firewall
# Server ใน Data Center บางแห่งบล็อก UDP 123 Outbound
# Fix: ใช้ NTP Server ภายในของ Provider
# AWS: 169.254.169.123 (Amazon Time Sync Service)
# GCP: metadata.google.internal (169.254.169.254)
# Azure: time.windows.com
# ปัญหา 3: systemd-timesyncd กับ chronyd รันพร้อมกัน
# Fix: เลือกใช้แค่ตัวเดียว
sudo systemctl stop systemd-timesyncd
sudo systemctl disable systemd-timesyncd
sudo systemctl enable --now chronyd
# ปัญหา 4: Hardware Clock (RTC) ไม่ตรง
# ดู Hardware Clock
hwclock --show
# ซิงค์ Software Clock ไปยัง Hardware Clock
sudo hwclock --systohc # System → HW
sudo hwclock --hctosys # HW → System
Script ตรวจสอบ NTP Status อัตโนมัติ
#!/bin/bash
# /usr/local/bin/check-ntp.sh
# ตรวจสอบและแจ้งเตือนถ้าเวลาคลาดเคลื่อนเกิน Threshold
MAX_OFFSET_MS=100 # แจ้งเตือนถ้าต่างเกิน 100ms
if command -v chronyc &>/dev/null; then
# ใช้ chrony
offset=$(chronyc tracking | grep "System time" | awk '{print $4}')
offset_ms=$(echo "$offset * 1000" | bc 2>/dev/null || echo "0")
source="chrony"
elif systemctl is-active --quiet systemd-timesyncd; then
# ใช้ systemd-timesyncd
offset=$(timedatectl timesync-status 2>/dev/null | grep "Offset" | awk '{print $2}' | tr -d 'ms')
offset_ms="${offset:-0}"
source="systemd-timesyncd"
else
echo "❌ ไม่พบ NTP Service ที่ทำงานอยู่"
exit 1
fi
abs_offset=$(echo "${offset_ms#-}" | cut -d. -f1)
if [ "${abs_offset:-0}" -gt "$MAX_OFFSET_MS" ]; then
echo "⚠️ NTP Offset สูง: ${offset_ms}ms (threshold: ${MAX_OFFSET_MS}ms) [${source}]"
exit 1
else
echo "✅ NTP OK: Offset=${offset_ms}ms [${source}]"
fi
# เพิ่มใน Crontab ตรวจสอบทุก 15 นาที
# */15 * * * * /usr/local/bin/check-ntp.sh | mail -s "NTP Alert $(hostname)" [email protected]
สรุป
การซิงค์เวลาบน Linux ทำได้สามวิธีหลัก Ubuntu/Debian ใหม่ใช้ systemd-timesyncd เป็นค่าเริ่มต้น ตั้งค่าผ่าน /etc/systemd/timesyncd.conf และตรวจสอบด้วย timedatectl timesync-status สำหรับ Production ที่ต้องการความแม่นยำสูงหรือต้องการทำ Internal NTP Server ให้ใช้ chrony แทน ตั้งค่า Timezone ด้วย timedatectl set-timezone Asia/Bangkok และใช้ UTC สำหรับ System Clock เสมอ แล้วให้ Application แปลง Timezone เอง
แนะนำบริการ DE
การตั้งค่า NTP และ Timezone บน Server ต้องการสิทธิ์ Root Cloud VPS ของ DE ให้ Root Access เต็มรูปแบบ สามารถติดตั้ง chrony, ตั้ง Internal NTP Server สำหรับ Cluster และกำหนด Timezone ได้ตามต้องการ รองรับทั้ง Ubuntu, Debian, และ Rocky Linux
หากต้องการโฮสต์เว็บไซต์ที่ Server มีการจัดการ Time Sync อัตโนมัติ Cloud Hosting ของ DE ดูแล NTP Configuration ให้ครบถ้วนโดยไม่ต้องตั้งค่าเอง พร้อมรองรับ Timezone Asia/Bangkok สำหรับ Application ภาษาไทย

