ตั้งค่า Keepalived บน VPS สำหรับ High Availability
Keepalived คือ software ที่ใช้ protocol VRRP (Virtual Router Redundancy Protocol) เพื่อสร้าง Virtual IP Address (VIP) ที่ลอยระหว่าง 2 เครื่องขึ้นไป เมื่อ server หลัก (MASTER) ล่ม Keepalived จะ failover VIP ไปยัง server สำรอง (BACKUP) โดยอัตโนมัติใน 1-3 วินาที ทำให้ service ของคุณยังคงออนไลน์แม้ server ตัวหนึ่งจะพัง
สถาปัตยกรรมนี้เรียกว่า Active-Passive HA — ใช้งานจริงกับ Nginx, HAProxy, MySQL, และ web application ทั่วไปที่ไม่ต้องการ downtime แม้แต่นาทีเดียว
ภาพรวมสถาปัตยกรรม Keepalived
ก่อนติดตั้ง ทำความเข้าใจ component หลัก:
- MASTER node — server หลักที่ถือ Virtual IP ในสภาวะปกติ (priority สูงกว่า)
- BACKUP node — server สำรองที่คอย monitor MASTER และรับ VIP เมื่อ MASTER ล่ม
- Virtual IP (VIP) — IP ที่ client ใช้เชื่อมต่อ จะ failover อัตโนมัติ
- VRRP Advertisement — heartbeat packet ที่ส่งทุก 1 วินาทีระหว่าง nodes
- Authentication — PASS หรือ AH เพื่อป้องกัน rogue node เข้ามาแย่ง VIP
สิ่งที่ต้องมีก่อนเริ่ม
- VPS 2 เครื่อง (Ubuntu 22.04/24.04 หรือ Debian 12) อยู่ subnet เดียวกัน
- IP ของ MASTER:
192.168.1.10, BACKUP:192.168.1.11 - Virtual IP ที่ต้องการ:
192.168.1.100(ต้องว่างอยู่ใน subnet) - ทั้ง 2 เครื่องต้องมี service เดียวกัน (เช่น Nginx) ทำงานอยู่
- Root/sudo access บนทั้ง 2 เครื่อง
ติดตั้ง Keepalived บนทั้ง 2 เครื่อง
รันคำสั่งนี้บน ทั้ง MASTER และ BACKUP:
# Ubuntu/Debian
sudo apt update
sudo apt install keepalived -y
# ตรวจสอบ version
keepalived --version
# Enable ให้เริ่มพร้อม system
sudo systemctl enable keepalived
เปิดใช้ IP forwarding และ non-local bind
Keepalived ต้องการ kernel options เหล่านี้เพื่อ bind Virtual IP ได้แม้ไม่ใช่ IP ของ interface นั้น:
# บน ทั้ง 2 เครื่อง
sudo tee /etc/sysctl.d/99-keepalived.conf <<EOF
net.ipv4.ip_nonlocal_bind = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
# ตรวจสอบ
sysctl net.ipv4.ip_nonlocal_bind
# ต้องได้: net.ipv4.ip_nonlocal_bind = 1
ip_nonlocal_bind=1 จำเป็นมากถ้าคุณรัน Nginx/HAProxy บน VIP — ไม่งั้น service จะ start ไม่ได้เมื่อ VIP ยังไม่ถูก assignตั้งค่า Keepalived บน MASTER (192.168.1.10)
สร้าง config file บน MASTER node:
sudo nano /etc/keepalived/keepalived.conf
global_defs {
notification_email {
[email protected]
}
notification_email_from [email protected]
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id MASTER_NODE
}
# Health check script สำหรับ Nginx
vrrp_script chk_nginx {
script "/usr/bin/pgrep nginx"
interval 2 # ตรวจทุก 2 วินาที
weight -20 # ถ้า fail ลด priority ลง 20
fall 2 # fail 2 ครั้งติดกัน = down
rise 2 # success 2 ครั้งติดกัน = up
}
vrrp_instance VI_1 {
state MASTER
interface eth0 # เปลี่ยนตาม interface จริง (ip a)
virtual_router_id 51 # ต้องตรงกันทั้ง 2 เครื่อง (1-255)
priority 110 # MASTER ต้องสูงกว่า BACKUP
advert_int 1 # heartbeat interval (วินาที)
authentication {
auth_type PASS
auth_pass MyS3cr3t! # เปลี่ยนเป็น password จริง (เหมือนกันทั้ง 2 เครื่อง)
}
virtual_ipaddress {
192.168.1.100/24 # Virtual IP ที่ต้องการ
}
track_script {
chk_nginx
}
}
ตั้งค่า Keepalived บน BACKUP (192.168.1.11)
Config บน BACKUP คล้ายกัน ต่างกันที่ state และ priority:
global_defs {
router_id BACKUP_NODE
}
vrrp_script chk_nginx {
script "/usr/bin/pgrep nginx"
interval 2
weight -20
fall 2
rise 2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51 # ต้องตรงกับ MASTER
priority 100 # ต่ำกว่า MASTER (110)
advert_int 1
authentication {
auth_type PASS
auth_pass MyS3cr3t! # เหมือนกับ MASTER เป๊ะ
}
virtual_ipaddress {
192.168.1.100/24
}
track_script {
chk_nginx
}
}
เริ่มใช้งาน Keepalived
Start service บน ทั้ง 2 เครื่อง (MASTER ก่อน):
# บน MASTER ก่อน
sudo systemctl start keepalived
sudo systemctl status keepalived
# บน BACKUP
sudo systemctl start keepalived
sudo systemctl status keepalived
ทดสอบ Failover
นี่คือขั้นตอนที่สำคัญที่สุด — ต้องทดสอบจริงก่อน go live:
# จาก client หรือเครื่องอื่น ตรวจว่า VIP ใช้งานได้
ping -c 3 192.168.1.100
curl http://192.168.1.100
# ดูว่า VIP อยู่ที่เครื่องไหนตอนนี้
# บน MASTER:
ip addr show eth0 | grep 192.168.1.100
# ควรเห็น: inet 192.168.1.100/24
# ทดสอบ failover: stop keepalived บน MASTER
sudo systemctl stop keepalived
# ภายใน 2-3 วินาที VIP ต้องย้ายไป BACKUP
# บน BACKUP:
ip addr show eth0 | grep 192.168.1.100
# ควรเห็น: inet 192.168.1.100/24
# ทดสอบว่า service ยังตอบสนองได้
curl http://192.168.1.100
# Start MASTER กลับ — VIP จะ preempt กลับมา MASTER อัตโนมัติ
sudo systemctl start keepalived
nopreempt ใน vrrp_instance ของ MASTER — ใช้เมื่อต้องการ stability มากกว่า strict active/passiveตั้งค่า Health Check Script แบบ Custom
นอกจาก pgrep คุณสามารถเขียน script ตรวจสอบ HTTP response ได้:
sudo tee /etc/keepalived/check_nginx.sh <<'EOF'
#!/bin/bash
# ตรวจว่า Nginx ตอบสนอง HTTP 200
response=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1/)
if [ "$response" = "200" ]; then
exit 0
else
exit 1
fi
EOF
sudo chmod +x /etc/keepalived/check_nginx.sh
แล้วแก้ vrrp_script ใน config:
vrrp_script chk_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 3
weight -30
fall 2
rise 2
timeout 5
}
ตั้งค่า Notify Script (แจ้งเตือนเมื่อ Failover)
Keepalived สามารถ call script เมื่อ state เปลี่ยน เช่น ส่ง notification:
sudo tee /etc/keepalived/notify.sh <<'EOF'
#!/bin/bash
TYPE=$1
NAME=$2
STATE=$3
case $STATE in
"MASTER")
echo "[$(date)] MASTER: $NAME became MASTER" >> /var/log/keepalived-notify.log
# เพิ่ม curl webhook Telegram/Slack ได้ที่นี่
;;
"BACKUP")
echo "[$(date)] BACKUP: $NAME became BACKUP" >> /var/log/keepalived-notify.log
;;
"FAULT")
echo "[$(date)] FAULT: $NAME entered FAULT state" >> /var/log/keepalived-notify.log
;;
esac
EOF
sudo chmod +x /etc/keepalived/notify.sh
เพิ่มใน vrrp_instance:
notify /etc/keepalived/notify.sh
ตรวจสอบว่า Keepalived ทำงานถูกต้อง
# 1. ดู status ของ service
sudo systemctl status keepalived
# 2. ดู log แบบ real-time
sudo journalctl -u keepalived -f
# 3. ตรวจว่า VIP ถูก assign อยู่ที่ MASTER
ip addr show | grep "192.168.1.100"
# 4. ดู VRRP state ปัจจุบัน
sudo journalctl -u keepalived --since "5 minutes ago" | grep -E "MASTER|BACKUP|FAULT"
# 5. ดูไฟล์ notify log
cat /var/log/keepalived-notify.log
tcpdump -i eth0 vrrp เพื่อ capture VRRP advertisement packet และตรวจสอบว่า heartbeat ส่งถึงกันจริง — มีประโยชน์มากเมื่อ debug failover ที่ไม่ทำงานแก้ปัญหาที่พบบ่อย
Error: "VRRP_Instance(VI_1) Transition to MASTER STATE"
ข้อความนี้บอกว่า BACKUP node ขึ้นเป็น MASTER เพราะไม่ได้รับ advertisement จาก MASTER ตัวจริง อาจเกิดจาก firewall block VRRP traffic (protocol 112)
# เปิด VRRP protocol บน firewall (ทั้ง 2 เครื่อง)
sudo ufw allow proto 112 from 192.168.1.0/24
# หรือ iptables:
sudo iptables -A INPUT -p 112 -j ACCEPT
sudo iptables -A OUTPUT -p 112 -j ACCEPT
# ทดสอบว่า VRRP packet ผ่านได้
sudo tcpdump -i eth0 vrrp -n
Error: "Keepalived_vrrp: ip address associated with VRID not present in MASTER advert"
เกิดเมื่อ virtual_router_id หรือ virtual_ipaddress ระหว่าง 2 node ไม่ตรงกัน
# ตรวจสอบ config บนทั้ง 2 เครื่องว่า virtual_router_id เหมือนกัน
grep virtual_router_id /etc/keepalived/keepalived.conf
# ต้องได้ค่าเดียวกันทั้ง MASTER และ BACKUP
# แก้ไขแล้ว restart:
sudo systemctl restart keepalived
Error: "Keepalived_vrrp: VRRP_Script(chk_nginx) timed out"
Health check script ทำงานช้าเกินกว่าค่า timeout ที่กำหนด ทำให้ Keepalived คิดว่า service พัง
# เพิ่ม timeout ใน vrrp_script
vrrp_script chk_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 3
timeout 10 # เพิ่มจาก default 5 เป็น 10
weight -20
fall 3
rise 2
}
sudo systemctl restart keepalived
Error: "SECURITY VIOLATION - same VRID" ใน log
มี Keepalived อื่นใน subnet เดียวกันใช้ virtual_router_id ซ้ำกัน เกิดบน Cloud/Shared environment บ่อย
# เปลี่ยน virtual_router_id เป็นค่าที่ไม่ซ้ำ (1-255)
# ตรวจสอบว่ามี VRRP traffic อื่นใน subnet:
sudo tcpdump -i eth0 vrrp -n | grep "vrid"
# เปลี่ยน virtual_router_id ใน config ทั้ง 2 เครื่อง เช่น จาก 51 เป็น 73
# แล้ว restart ทั้ง 2 เครื่อง
VIP ไม่ failover แม้ MASTER service พัง
Health check script return 0 เสมอแม้ Nginx จะหยุดทำงาน — ตรวจสอบ script logic
# ทดสอบ script manually:
sudo /etc/keepalived/check_nginx.sh
echo "Exit code: $?"
# ถ้า Nginx หยุดแต่ได้ 0 แสดงว่า script มี bug
# ลองหยุด Nginx แล้วดู priority change ใน log:
sudo systemctl stop nginx
sudo journalctl -u keepalived -f
# ควรเห็น priority drop และ transition to BACKUP
คำถามที่พบบ่อย
Keepalived ใช้งานได้บน VPS Cloud ทุก provider หรือเปล่า?
ไม่ทุก provider รองรับ VRRP/Gratuitous ARP ที่ Keepalived ต้องการ ผู้ให้บริการบางรายเช่น AWS EC2 หรือ GCP block multicast/VRRP traffic โดย default ต้องใช้วิธีอื่น เช่น Route table failover ผ่าน API แทน สำหรับ VPS ทั่วไปใน datacenter เดียวกันที่อยู่ subnet เดียวกันมักรองรับได้ดี
Keepalived กับ HAProxy ต่างกันอย่างไร?
Keepalived ทำ IP failover ระดับ network (Virtual IP) ส่วน HAProxy ทำ load balancing ระดับ application ทั้งสองเข้ากันได้ดีมาก — ใช้ Keepalived สร้าง VIP แล้วให้ HAProxy bind บน VIP นั้น จะได้ทั้ง HA และ load balancing ในคราวเดียว
ถ้า MASTER กลับมาออนไลน์ VIP จะกลับมาอัตโนมัติหรือต้องตั้งเอง?
ค่า default ของ Keepalived คือ preempt — MASTER จะแย่ง VIP คืนทันทีที่ priority สูงกว่า BACKUP ซึ่งอาจทำให้เกิด brief downtime ซ้ำ ถ้าต้องการให้ VIP อยู่ที่ BACKUP ต่อจนกว่าจะ switch manual ให้ใส่ nopreempt ใน config ของ MASTER