Keepalived High Availability VRRP Virtual IP บน VPS Linux

ตั้งค่า Keepalived บน VPS สำหรับ High Availability

อัปเดต: 11 ตุลาคม 2026 · High Availability · อ่าน ~14 นาที

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 หลัก:

Note: Keepalived ต้องการให้ทั้ง 2 server อยู่ใน subnet เดียวกัน (Layer 2 adjacency) — VPS จาก provider เดียวกัน datacenter เดียวกันส่วนใหญ่รองรับได้

สิ่งที่ต้องมีก่อนเริ่ม

ติดตั้ง 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
Tip: 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
Tip: ถ้าต้องการปิด preemption (MASTER กลับมาแล้วไม่แย่ง VIP คืน) ให้เพิ่ม 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
Tip: ใช้ 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