Cấu hình VIP Keepalived VRRP unicast cho VM trên OpenStack

Vì sao dùng unicast VRRP trên OpenStack?

OpenStack (Neutron) thường block multicast/LL-mcast nên VRRP mặc định (multicast 224.0.0.18, proto 112) hay bị chặn → gây split-brain (cả 2 node cùng nhận VIP). Giải pháp phổ biến: dùng VRRP unicast (Keepalived hỗ trợ) + tạo port VIP và Allowed Address Pair để cho VM bind IP không có mặt trong port ban đầu.

1) Tạo port VIP (OpenStack CLI)

Ví dụ network id, VIP 192.168.1.40 (thay bằng network/VIP bạn dùng):

openstack port create \
  --network 5ff63778-9906-4c4e-b0d6-8eacv79e162e \
  --fixed-ip ip-address=192.168.1.40 \
  vip-port

Lưu ý: port này giữ fixed IP cho VIP, tuy nhiên bạn không attach VM trực tiếp tới port vip-port — thay vào đó ta thêm VIP vào Allowed Address Pair của port VM.

2) Thêm Allowed Address Pair vào port của VM (cho phép VM bind VIP)

Giả sử port của 2 VM là PORT1PORT2:

openstack port set --allowed-address ip-address=192.168.1.40 PORT1
openstack port set --allowed-address ip-address=192.168.1.40 PORT2

Alternative: nếu muốn chỉ accept từ 1 MAC cụ thể thì có cú pháp thêm MAC, nhưng thông thường chỉ IP là đủ khi port security cho phép.

Quan trọng: nếu cloud của bạn bật port_security = True và anti-spoofing, allowed_address_pairs là cách chuẩn cho phép VM giả địa chỉ IP khác (VIP).

3) Bật ip_nonlocal_bind trên cả 2 VM

Để HAProxy/nginx/keepalived có thể bind VIP mặc dù IP đó không phải local ngay lúc khởi động:

# chỉnh file trên cả 2 VM
sudo tee -a /etc/sysctl.conf <<'EOF'
net.ipv4.ip_nonlocal_bind=1
EOF

# apply
sudo sysctl -p

4) Security Group — mở VRRP (protocol 112) & rules tối thiểu

Mở VRRP (protocol number 112) giữa 2 node (khuyến nghị giới hạn source chỉ 2 IP/ CIDR của private subnet):

Ví dụ CLI (cho security group my-sg):

# Cho phép vào (ingress) proto 112 từ subnet private hoặc 2 IP
openstack security group rule create --ingress --ethertype IPv4 \
  --protocol 112 --remote-ip 192.168.1.0/24 my-sg

# Cho phép out (egress) proto 112 nếu SG cứng ngắt egress. Nếu egress Any thì bỏ qua.
openstack security group rule create --egress --ethertype IPv4 \
  --protocol 112 --remote-ip 192.168.1.0/24 my-sg

Các rule bổ sung (recommended):

  • SSH (TCP 22) từ admin IP.

  • HTTP/HTTPS (TCP 80/443) cho client.

  • ICMP (optional) cho debug ping.

Không mở 0.0.0.0/0 nếu không cần thiết — phạm vi chỉ giữa 2 node hoặc private CIDR là an toàn hơn.

5) File keepalived.conf (unicast) — mẫu cho 2 node

Lưu ý: loại bỏ debug 3 khỏi global_defs (một số bản keepalived báo Unknown keyword 'debug').

VM01 (MASTER preference)

vi /etc/keepalived/keepalived.conf
global_defs {
    enable_script_security
    script_user keepalived_script
}

vrrp_script check_nginx {
    script "/usr/local/bin/check_nginx.sh"
    interval 2
    weight -20
    fall 2
    rise 2
}

vrrp_instance VI_1 {
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass your-strong-password
    }

    unicast_src_ip 192.168.1.10 # IP thực của node này unicast_peer { 192.168.1.20 # IP node kia } virtual_ipaddress { 192.168.1.40/32 dev eth0 } track_script { check_nginx } } 

squid02 (BACKUP)

vi /etc/keepalived/keepalived.conf
global_defs {
    enable_script_security
    script_user keepalived_script
}

vrrp_script check_nginx {
    script "/usr/local/bin/check_nginx.sh"
    interval 2
    weight -20
    fall 2
    rise 2
}

vrrp_instance VI_1 {
    interface eth0
    virtual_router_id 51
    priority 90
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass your-strong-password
    }

    unicast_src_ip 192.168.1.20 unicast_peer { 192.168.1.10 } virtual_ipaddress { 192.168.1.40/32 dev eth0 } track_script { check_nginx } } 

Giải thích một số tuỳ chọn quan trọng

  • virtual_router_id: ID cho cluster VRRP (1–255). KHÔNG trùng với bất kỳ cluster nào khác trong cùng subnet.

  • unicast_src_ip: buộc Keepalived dùng IP nguồn cụ thể (tránh 169.254.x.x link-local).

  • unicast_peer: IP thật (fixed IP) của peer — không dùng VIP ở đây.

  • virtual_ipaddress { 1.2.3.4/32 dev eth0 }: /32 + dev giúp gán chuẩn cho interface.

  • authentication.auth_pass: dùng mật khẩu đủ mạnh để tránh bị nhồi gói giả mạo.

6) Script healthcheck (ví dụ check_nginx.sh)

Tạo /usr/local/bin/check_nginx.sh:

#!/bin/bash
# Trả 0 nếu OK, 1 nếu lỗi. Dùng curl kiểm tra localhost:80
curl --silent --max-time 3 http://127.0.0.1:80/ > /dev/null
if [ $? -eq 0 ]; then
  exit 0
else
  exit 1
fi
sudo chmod +x /usr/local/bin/check_nginx.sh
sudo chown root:root /usr/local/bin/check_nginx.sh

weight -20 trong vrrp_script sẽ giảm priority khi script fail (keepalived sẽ so sánh priority để chuyển VIP).

7) Khởi động, enable service

sudo systemctl enable --now keepalived
sudo systemctl status keepalived -l

Để debug trực tiếp (foreground, verbose):

sudo systemctl stop keepalived
sudo keepalived -nld
# hoặc xem log
journalctl -u keepalived -f

8) Kiểm tra & test

Kiểm tra VIP hiện tại

Trên mỗi node:

ip a show dev eth0 | grep 192.168.1.40 || true

Chỉ 1 node phải có dòng với VIP (MASTER).

Bắt gói VRRP (xem giao tiếp unicast)

Trên node nào đó:

sudo tcpdump -i eth0 proto 112 -nn
# hoặc
sudo tcpdump -i eth0 vrrp -n -c 20

Bạn sẽ thấy gói:

IP 192.168.1.10 > 192.168.1.20: VRRPv2, Advertisement, vrid 51, prio 100 ...

Test failover (thực tế)

  • Test 1 (stop keepalived):

    • Trên MASTER: sudo systemctl stop keepalived

    • Trên BACKUP: ip a => VIP phải nhảy sang BACKUP.

  • Test 2 (stop service health):

    • Giả sử check_nginx sẽ return non-0 → MASTER giảm priority → BACKUP giành VIP.

  • Restore:

    • Start lại keepalived trên MASTER, nó sẽ reclam VIP nếu priority cao hơn.

Với OpenStack, unicast VRRP + Allowed Address Pair + ip_nonlocal_bind + SG cho VRRP là combo chuẩn để chạy VIP/HA cho LB (HAProxy/nginx) trên VM.

Tác giả: Mạnh Hoàng

Tôi là Hoàng Mạnh, người sáng lập blog SysadminSkills.com. Tôi viết về quản trị hệ thống, bảo mật máy chủ, DevOps và cách ứng dụng AI để tự động hóa công việc IT. Blog này là nơi tôi chia sẻ những gì đã học được từ thực tế – đơn giản, ngắn gọn và áp dụng được ngay.

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *