1. Tổng quan.
Script được thiết kế để triển khai giải pháp High Availability (HA) cho F-Stack. Nó giúp giám sát và đảm bảo rằng địa chỉ IP ảo (VIP) luôn hoạt động trên một trong hai server Master hoặc Backup.
Một trong những lý do mình phải tự thiết kế script này thay vì sử dụng các giải pháp phổ biến như Keepalived là do DPDK (Data Plane Development Kit) hoạt động theo cách khác biệt so với các giao thức mạng thông thường trong Linux Kernel.
2. Lý do chính Keepalived hoặc các giải pháp HA tương tự không hoạt động trên nền DPDK.
- DPDK hoạt động ở tầng user-space:
- Keepalived, VRRP và các công cụ HA phổ biến dựa vào cơ chế quản lý network ở tầng kernel (như sử dụng
ip addr
hoặcnetlink
API). - Trong khi đó, DPDK quản lý trực tiếp các NIC (Network Interface Card) ở tầng user-space, bỏ qua hoàn toàn kernel network stack. Điều này làm các công cụ như Keepalived không thể nhìn thấy hay quản lý các card mạng (NIC) do DPDK điều khiển.
- Keepalived, VRRP và các công cụ HA phổ biến dựa vào cơ chế quản lý network ở tầng kernel (như sử dụng
- Thiếu hỗ trợ VRRP tích hợp trên DPDK:
- VRRP (Virtual Router Redundancy Protocol) là cốt lõi của Keepalived để quản lý VIP. Tuy nhiên, DPDK không có cơ chế tích hợp sẵn để thực hiện VRRP hoặc các giao thức tương tự, nên bạn phải tự triển khai logic này trong script của mình.
- Không thể thao tác trực tiếp với IP hoặc VIP qua
iproute2
:- Trên hệ thống thông thường, Keepalived sử dụng lệnh như
ip addr add
để gán VIP. Nhưng trên DPDK, bạn cần dùng API hoặc các công cụ riêng như F-Stack để thao tác trực tiếp với giao diện DPDK (nhưdpdk0
).
- Trên hệ thống thông thường, Keepalived sử dụng lệnh như
- Quản lý giao diện DPDK phải thông qua ứng dụng:
- Trong trường hợp của bạn, F-Stack chịu trách nhiệm quản lý giao diện DPDK và xử lý VIP. Điều này yêu cầu một giải pháp HA được tích hợp vào ứng dụng hoặc được điều phối thông qua các script tự xây dựng.
3. Tại sao cần script thay vì Keepalived?
- Không tương thích: Keepalived không thể thao tác hoặc kiểm tra trạng thái card mạng DPDK.
- Tùy biến cao: Bạn cần logic chuyên biệt cho việc kiểm tra dịch vụ F-Stack Nginx, chuyển đổi VIP và khởi động lại card mạng.
- Xử lý HA phức tạp: Trong môi trường DPDK, chỉ có một ứng dụng như F-Stack có quyền kiểm soát NIC. Do đó, bạn cần tự xây dựng logic failover phù hợp để đảm bảo:
- Chỉ một server giữ VIP.
- Khôi phục trạng thái dịch vụ khi cả hai server gặp sự cố.
4. Ưu điểm của việc dùng script tùy chỉnh.
- Tích hợp chặt chẽ với F-Stack:
Script có thể kiểm tra và điều khiển trực tiếp trạng thái của Nginx F-Stack thông qua các lệnh cụ thể như/usr/local/nginx_fstack/sbin/nginx
. - Kiểm soát linh hoạt:
Bạn có thể tùy chỉnh logic xử lý khi phát hiện lỗi, ví dụ: ưu tiên Master, kiểm tra trạng thái card mạng, hoặc ghi log chi tiết. - Khả năng mở rộng:
Script có thể mở rộng thêm các tính năng khác, như kiểm tra dịch vụ bên ngoài (HTTP, database) hoặc quản lý thêm nhiều server.
5. Các thành phần chính.
- Kiểm tra trạng thái VIP:
- Script liên tục kiểm tra trạng thái của VIP bằng cách gửi lệnh
ping
đến VIP. - Nếu VIP hoạt động (phản hồi từ
ping
), server sẽ không làm gì thêm và tiếp tục giám sát sau một khoảng thời gian (HEARTBEAT_INTERVAL
).
- Script liên tục kiểm tra trạng thái của VIP bằng cách gửi lệnh
- Xử lý theo role (Master/Backup):
- Trên Master:
- Khi Master phát hiện VIP không hoạt động, nó sẽ cố gắng kích hoạt VIP trên chính nó bằng cách khởi chạy lại F-Stack (
/usr/local/nginx_fstack/sbin/nginx
). - Nếu kích hoạt thành công, nó ghi log xác nhận thành công. Nếu không, nó sẽ tiếp tục thử.
- Khi Master phát hiện VIP không hoạt động, nó sẽ cố gắng kích hoạt VIP trên chính nó bằng cách khởi chạy lại F-Stack (
- Trên Backup:
- Backup luôn kiểm tra xem Master có đang giữ VIP không.
- Nếu Master không kích hoạt được VIP, Backup sẽ tự động thử kích hoạt VIP để đảm bảo tính liên tục của dịch vụ.
- Trên Master:
- Phục hồi VIP nếu cả hai server mất IP:
- Khi cả Master và Backup đều mất VIP (do lỗi hoặc tắt dịch vụ
nginx
trên cả hai), script sẽ cố gắng khôi phục theo thứ tự:- Master trước: Nếu Master không thể kích hoạt VIP, Backup sẽ được phép thử kích hoạt.
- Điều này đảm bảo VIP luôn được phục hồi với ưu tiên Master.
- Khi cả Master và Backup đều mất VIP (do lỗi hoặc tắt dịch vụ
- Xuất log để theo dõi:
- Mọi hành động, cảnh báo, và lỗi đều được ghi lại và hiển thị trên terminal với timestamp, giúp dễ dàng theo dõi trạng thái và phát hiện vấn đề.
6. Quy trình hoạt động.
- Khởi chạy script:
- Script khởi động trên cả Master và Backup với cấu hình vai trò (
IS_MASTER = True
cho Master,False
cho Backup). - Cả hai server sẽ bắt đầu kiểm tra trạng thái của VIP.
- Script khởi động trên cả Master và Backup với cấu hình vai trò (
- Nếu VIP đang hoạt động:
- Script ghi nhận rằng VIP đang chạy bình thường và không làm gì thêm ngoài việc giám sát.
- Nếu VIP không hoạt động:
- Trên Master:
- Master sẽ cố gắng kích hoạt lại VIP bằng cách chạy lệnh
/usr/local/nginx_fstack/sbin/nginx
. - Nếu thành công, script ghi log xác nhận. Nếu không, nó tiếp tục thử.
- Master sẽ cố gắng kích hoạt lại VIP bằng cách chạy lệnh
- Trên Backup:
- Backup sẽ theo dõi trạng thái của Master.
- Nếu Master không kích hoạt được VIP, Backup sẽ tự động kích hoạt VIP.
- Trên Master:
- Phục hồi khi cả hai server mất VIP:
- Script phát hiện cả Master và Backup đều mất VIP.
- Master sẽ thử kích hoạt trước. Nếu không thành công, Backup sẽ thử.
7. Tình huống xử lý cụ thể.
- Master tắt dịch vụ F-Stack:
- Backup phát hiện VIP không phản hồi và tự động kích hoạt VIP trên chính nó.
- Backup tắt dịch vụ F-Stack:
- Không có thay đổi, vì VIP vẫn đang hoạt động trên Master.
- Cả Master và Backup đều tắt F-Stack:
- Script tự động khôi phục VIP theo thứ tự:
- Master thử kích hoạt trước.
- Nếu Master thất bại, Backup sẽ thử kích hoạt.
- Script tự động khôi phục VIP theo thứ tự:
- VIP không phản hồi do lỗi mạng:
- Script sẽ ghi log lỗi và tiếp tục thử khôi phục VIP cho đến khi thành công.
8. Ưu điểm của script.
- Tự động hóa hoàn toàn:
- Script tự động xử lý các tình huống lỗi mà không cần can thiệp thủ công.
- Ưu tiên Master:
- Master luôn được ưu tiên giữ VIP nếu khả thi.
- Phục hồi linh hoạt:
- Nếu Master không hoạt động, Backup có thể đảm nhiệm vai trò giữ VIP.
- Log thời gian thực:
- Giúp theo dõi dễ dàng các trạng thái, lỗi, và hành động trong terminal.
9. Cách triển khai Script Python cho Master và Backup.
9.1. Script chung (run trên cả Master và Backup).
Tạo file /usr/local/nginx_fstack/sbin/fstack_ha
với script có nội dung dưới.
cat > /usr/local/nginx_fstack/sbin/fstack_ha << 'OEF'
import os
import subprocess
import time
# Configurations
MASTER_IP = "10.237.7.79" # VIP
HEARTBEAT_INTERVAL = 5 # Interval to check (seconds)
IS_MASTER = True # Set to True for Master, False for Backup
INTERFACE_COMMAND = "/usr/local/nginx_fstack/sbin/nginx" # Command to activate interface
def log(message):
"""Log messages to terminal."""
timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
print(f"[{timestamp}] {message}")
def check_ip_reachability(ip):
"""Check if an IP is reachable."""
try:
subprocess.check_output(["ping", "-c", "1", "-W", "1", ip], stderr=subprocess.DEVNULL)
return True
except subprocess.CalledProcessError:
return False
def activate_interface():
"""Activate the F-Stack interface."""
log("Activating interface...")
result = os.system(INTERFACE_COMMAND)
if result == 0:
log("Interface activated successfully.")
return True
else:
log("[ERROR] Failed to activate interface.")
return False
def deactivate_interface():
"""Deactivate the F-Stack interface."""
log("Deactivating interface...")
os.system(f"{INTERFACE_COMMAND} -s stop")
def main():
global IS_MASTER
while True:
vip_reachable = check_ip_reachability(MASTER_IP)
if vip_reachable:
log(f"VIP {MASTER_IP} is active.")
time.sleep(HEARTBEAT_INTERVAL)
continue
log(f"[WARNING] VIP {MASTER_IP} is not reachable!")
if IS_MASTER:
log("This is the Master server. Trying to activate VIP...")
if not activate_interface():
log("[ERROR] Master failed to activate VIP. Will keep retrying.")
else:
log("[SUCCESS] Master successfully activated VIP.")
else:
log("This is the Backup server. Monitoring for Master recovery...")
time.sleep(HEARTBEAT_INTERVAL)
if not check_ip_reachability(MASTER_IP):
log("[INFO] Master is down. Trying to activate VIP as Backup...")
if not activate_interface():
log("[ERROR] Backup failed to activate VIP. Will keep retrying.")
else:
log("[SUCCESS] Backup successfully activated VIP.")
# If both servers lose VIP, prioritize Master first, then Backup
log("[RECOVERY] Both servers lost VIP. Prioritizing Master...")
if IS_MASTER:
if activate_interface():
log("[RECOVERY SUCCESS] Master recovered VIP.")
else:
log("[RECOVERY FAILED] Master could not recover VIP.")
else:
if not check_ip_reachability(MASTER_IP) and activate_interface():
log("[RECOVERY SUCCESS] Backup recovered VIP.")
else:
log("[RECOVERY FAILED] Backup could not recover VIP.")
time.sleep(HEARTBEAT_INTERVAL)
if __name__ == "__main__":
main()
OEF
Chỉnh sửa cấu hình Master và Backup.
- Master:
- Đặt
IS_MASTER = True
trong script Python. - Chạy script để quản lý trạng thái VIP.
- Đặt
- Backup:
- Đặt
IS_MASTER = False
trong script Python. - Chạy script để giám sát Master.
- Đặt
Cấp quyền thực thi cho script.
chmod +x /usr/local/nginx_fstack/sbin/fstack_ha
Chạy thử script trên cả Master và Backup.
python3 /usr/local/nginx_fstack/sbin/fstack_ha
Output sẽ có dạng thế này nhé.
[2024-12-11 03:14:36] [WARNING] VIP 10.237.7.79 is not reachable!
[2024-12-11 03:14:36] This is the Backup server. Monitoring for Master recovery...
[2024-12-11 03:14:42] [INFO] Master is down. Trying to activate VIP as Backup...
[2024-12-11 03:14:42] Activating interface...
[2024-12-11 03:14:42] Interface activated successfully.
[2024-12-11 03:14:42] [SUCCESS] Backup successfully activated VIP.
[2024-12-11 03:14:42] [RECOVERY] Both servers lost VIP. Prioritizing Master...
[2024-12-11 03:14:43] Activating interface...
[2024-12-11 03:14:43] Interface activated successfully.
[2024-12-11 03:14:43] [RECOVERY SUCCESS] Backup recovered VIP.
[2024-12-11 03:14:48] VIP 10.237.7.79 is active.
[2024-12-11 03:14:53] VIP 10.237.7.79 is active.
[2024-12-11 03:14:58] VIP 10.237.7.79 is active.
9.2. Tạo service systemd quản lý fstack_ha.
Nếu không có log lỗi, bạn có thể tạo service dạng systemd như dưới.
cat > /etc/systemd/system/fstack_ha.service << 'OEF'
[Unit]
Description=F-Stack High Availability Script
After=network.target
[Service]
User=root
Group=root
WorkingDirectory=/home
ExecStart=/usr/bin/python3 /usr/local/nginx_fstack/sbin/fstack_ha
ExecStop=/usr/local/nginx_fstack/sbin/nginx -s stop
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
OEF
Reload và khởi động fstack_ha.service.
systemctl daemon-reload
systemctl enable fstack_ha.service
systemctl restart fstack_ha.service
systemctl status fstack_ha.service
Bạn có thể xem log của dịch vụ này bằng lệnh dưới.
journalctl -u fstack_ha.service -f -n 100
Ví dụ output của log.
Dec 11 03:16:35 node77 systemd[1]: Started F-Stack High Availability Script.
Dec 11 03:18:17 node77 f-stack[22100]: EAL: VFIO support initialized
Dec 11 03:18:17 node77 f-stack[22100]: EAL: Probe PCI driver: net_vmxnet3 (15ad:07b0) device: 0000:0b:00.0 (socket -1)
Dec 11 03:18:17 node77 f-stack[22100]: TELEMETRY: No legacy callbacks, legacy socket not created
Để dừng fstack_ha.service
, hãy chạy lệnh dưới.
systemctl stop fstack_ha.service
10. Giả lập lỗi down card mạng hoặc mất dịch vụ để kiểm tra hoạt động của script.
Hiện tại kết quả curl vào 10.237.7.79 đang thành công như dưới.
shell> curl 10.237.7.79
Chào mừng bạn đến với website 1 của tôi
Dừng nginx trên Master bằng lệnh systemctl stop fstack_ha.service
.
Dec 11 03:22:01 node77 systemd[1]: Stopping F-Stack High Availability Script...
Dec 11 03:22:01 node77 nginx[22171]: nginx: [alert] kill(22152, 15) failed (3: No such process)
Dec 11 03:22:01 node77 systemd[1]: fstack_ha.service: Control process exited, code=exited, status=1/FAILURE
Dec 11 03:22:01 node77 systemd[1]: fstack_ha.service: Failed with result 'exit-code'.
Dec 11 03:22:01 node77 systemd[1]: Stopped F-Stack High Availability Script.
Dec 11 03:22:01 node77 systemd[1]: fstack_ha.service: Consumed 58.083s CPU time.
Xem kết quả trên Backup, nó sẽ tự động kích hoạt IP 10.237.7.79
khi phát hiện lỗi.
Dec 11 03:22:11 node78 f-stack[39390]: EAL: VFIO support initialized
Dec 11 03:22:12 node78 f-stack[39390]: EAL: Probe PCI driver: net_vmxnet3 (15ad:07b0) device: 0000:0b:00.0 (socket -1)
Dec 11 03:22:12 node78 f-stack[39390]: TELEMETRY: No legacy callbacks, legacy socket not created
Hoặc tắt interface mạng trên Master.
ifconfig f-stack-0 down
Kết quả khi curl, bây giờ Backup Server đang phục vụ webserver.
shell> curl 10.237.7.79
Chào mừng bạn đến với website 2 của tôi
11. Kết luận.
Giải pháp như Keepalived không thể hoạt động trong môi trường DPDK vì không có khả năng tương tác với network sử dụng user-space. Script mình thiết kế chính là một cách thủ công nhưng hiệu quả để đảm bảo HA trong môi trường này. Đây là giải pháp tốt nhất khi bạn muốn tích hợp HA cho F-Stack trên nền tảng DPDK.