WIUNIX ACADEMY
راهاندازی لودبالانسر HAProxy و Keepalived با VIP و VRRP
دو HAProxy را با یک IP مجازی مشترک راهاندازی کن، ترافیک را به بکاندهای سالم برسان و انتقال VIP و دسترسی کاربر را هنگام خرابی با Keepalived و VRRP بررسی کن.
محیطت را انتخاب کنآموزش متناسب با محیط تو
کجا اجرا میکنی؟
سیستمعامل و نسخه را انتخاب کن تا مراحل، دستورها و راهحلها برای همان محیط نمایش داده شوند.
از اینجا شروع کن
در پایان چه چیزی خواهی داشت؟
درخواست واقعی HTTP را از یک VIP مشترک عبور بده، مالکیت یکتای آن را ثابت کن و پس از توقف لودبالانسر فعال، از دستگاه سوم انتقال VIP و پاسخ سالم برنامه را بررسی کن.
سیستمعاملها و نسخههای پوششدادهشده
مسیرهای بررسیشده با اسناد رسمی: Ubuntu 26.10 بهعنوان پیشفرض، نسخههای LTS یعنی 26.04 و 24.04 و 22.04 و همچنین Debian 13 و 12. دستورهای apt و systemd و پیکربندی پایه در این نسخهها مشترک است و تفاوت ساختگی درج نشده. شبکه باید امکان جابهجایی VIP را داشته باشد؛ VRRP unicast از پروتکل IP شمارهٔ 112 استفاده میکند. دو بکاند HTTP از پیش آماده و دسترسی خصوصی به پورت 80 لازم است. نشانیها و ens18 نمونهاند. هیچ Failover واقعی روی سرورهای ویونیکس یا شبکهٔ تولیدی اجرا نشده و خروجیها صرفاً آموزشیاند. پشتیبانی Ubuntu 26.10 نهماهه است و برای ماندگاری بیشتر میتوان نسخهٔ LTS انتخاب کرد.
قبل از شروع
- دو سرور اختصاصی Ubuntu یا Debian با systemd، دسترسی sudo، پشتیبان و نشست مدیریتی جایگزین؛ بدون کلاستر قبلی که هنوز طرح مهاجرت ندارد.
- یک IP مجازی آزاد و تأییدشده در شبکهٔ خصوصی مشترک دو نود؛ زیرساخت باید انتقال مالکیت ARP و عبور پروتکل IP شمارهٔ 112 بین همتاها را پشتیبانی کند.
- دو سرویس HTTP موجود با مدیریت مستقل و مسیر سلامت که کد 200 برمیگرداند؛ هر دو لودبالانسر باید به برنامهها و مسیر سلامت آنها دسترسی داشته باشند.
- دسترسی مدیریت فایروال میزبان و شبکه و یک دستگاه سوم برای بررسی VIP؛ همچنین مجوز آزمون کوتاه و مختلکنندهٔ Failover.
- این نمونه HTTP بدون رمزنگاری را فقط در شبکهٔ خصوصی بهکار میبرد. برای دسترسی عمومی، TLS و امنیت برنامه باید جداگانه طراحی و بررسی شوند.
قدم بعدی
دو سرور لودبالانسر را شناسایی کن
در این تمرین یک نقطهٔ ورود HTTP با دو لودبالانسر فعال/آمادهبهکار میسازیم؛ قرار نیست قابلیت IP شناور اختصاصی سرویسدهندهٔ ابری را شبیهسازی کنیم. بررسی را جداگانه روی LB-01 و LB-02، در یک نشست مدیریتی پایدار انجام بده. هر دو سرور باید در یک شبکهٔ لایهٔ دوم باشند یا ارائهدهندهٔ شبکه انتقال VIP و بهروزرسانی همسایهها را صریحاً پشتیبانی کند.
در مثال، نشانی LB-01 برابر 10.20.30.11، نشانی LB-02 برابر 10.20.30.12 و IP مجازی برابر 10.20.30.100 است؛ ماسک /24 و نام کارت شبکه ens18 در نظر گرفته شدهاند. این مقادیر فقط نمونهاند. همهٔ نشانیها و نام کارت شبکه را در فایلهای هر دو نود هماهنگ با محیط خودت تغییر بده و VIP را بهصورت دائمی به هیچ نودی اختصاص نده.
نسخهٔ واقعی سیستمعامل را با گزینهٔ انتخابشده در بالای مقاله مقایسه کن. وجود یک ترمینال لینوکس به معنی اجراشدن systemd نیست. اگر از قبل روی این سرورها VRRP یا سرویس دیگری روی پورت 80 داری، این سناریوی نصب تازه را بدون طراحی مهاجرت اجرا نکن.
روی هر دو نود · ترمینال همان سرور · بررسی فقطخواندنی؛ برای مالک پردازشها دسترسی sudo لازم است
cat /etc/os-release
ps -p 1 -o comm=
ip -br -4 address
ip -4 route
sudo ss -ltnp | grep -E ":80[[:space:]]" || trueنسخهٔ هر نود با نسخهٔ انتخابشده یکسان است، PID 1 برابر systemd است، کارتهای شبکه در محدودهٔ درست قرار دارند و پورت 80 مالک ناشناختهای ندارد.
قدم بعدی
سلامت واقعی هر بکاند را جداگانه بررسی کن
پیش از تنظیم جابهجایی خودکار، دو برنامهٔ HTTP مستقل و دارای سرویس مدیریتی آماده داشته باش: app1 روی 10.20.30.21:8080 و app2 روی 10.20.30.22:8080. هر دو باید برای درخواست GET به مسیر /healthz با Host نمونهٔ lab.internal دقیقاً پاسخ 200 بدهند و در مسیر / هم پاسخ کاربردی داشته باشند. نشانیها، پورت، Host و مسیر سلامت را با شرایط برنامهٔ واقعی هماهنگ کن؛ این آموزش یک وبسرور آزمایشی ناامن را راهاندازی نمیکند.
این درخواستها را از هر دو لودبالانسر بفرست. بازبودن پورت TCP کافی نیست؛ اگر مسیر سلامت به صفحهٔ ورود، ریدایرکت یا پاسخ خطا میرسد، ابتدا آن را اصلاح کن. موفقیت این بخش هنوز انتقال VIP را ثابت نمیکند.
روی هر دو لودبالانسر · کاربر عادی · مقادیر نمونهٔ بکاند را با محیط خودت جایگزین کن
curl --noproxy '*' -i --max-time 4 -H 'Host: lab.internal' http://10.20.30.21:8080/healthz
curl --noproxy '*' -i --max-time 4 -H 'Host: lab.internal' http://10.20.30.22:8080/healthz
curl --noproxy '*' --fail --silent --show-error --max-time 4 -H 'Host: lab.internal' http://10.20.30.21:8080/EXAMPLE ONLY — supplied by an application, not measured on WIUNIX production:
HTTP/1.1 200 OK
Content-Type: text/plain
OKهر دو درخواست سلامت کد 200 میدهند و پاسخ مسیر اصلی برنامه نیز دریافت میشود؛ با سالمبودن فقط یک بکاند، مجموعهٔ دوبکاندی آماده نیست.
قدم بعدی
مسیر شبکه و فایروال را آماده کن
با مسئول شبکه هماهنگ کن که VIP و شناسهٔ VRID در این شبکه تکراری نباشند. پیامهای VRRP در حالت unicast از پروتکل IP شمارهٔ 112 استفاده میکنند، نه از پورت 112 در TCP یا UDP. دریافت این پروتکل را فقط بین نشانی اصلی دو نود مجاز کن. دسترسی کاربران آزمایش به TCP/80 و دسترسی هر دو لودبالانسر به TCP/8080 بکاندها باید برقرار باشد. اگر شبکهٔ ابری IP ثانویه یا اعلان ARP هنگام انتقال را نمیپذیرد، ادامه نده و از قابلیت رسمی همان ارائهدهنده استفاده کن.
دستورهای این بخش فقط وقتی اجرا میشوند که UFW نصب و فعال باشد. دسترسی HTTP مثال به زیرشبکهٔ آزمایش محدود میشود و اجازهٔ VRRP نیز فقط برای دو همتای نمونه روی ens18 است. در سایر فایروالها چیزی خودکار تغییر نمیکند؛ قواعد nftables، تجهیزات شبکه و سرویسدهنده را جداگانه بررسی کن. فایروال موجود را خاموش نکن.
پیش از ویرایش قوانین شبکه، اتصال کنسول یا مسیر مدیریتی جایگزین داشته باش. این سرویس HTTP بدون TLS صرفاً برای شبکهٔ خصوصی آزمایش است.
روی هر دو نود · با sudo و فقط در صورت مدیریت فایروال توسط UFW · پیش از اجرا کارت شبکه و نشانیها را اصلاح کن
if command -v ufw >/dev/null && sudo ufw status | grep -q '^Status: active'; then
sudo ufw allow in on ens18 from 10.20.30.0/24 to any port 80 proto tcp comment 'Academy HA HTTP lab'
sudo ufw allow in on ens18 from 10.20.30.11 to any proto vrrp comment 'Academy VRRP LB01'
sudo ufw allow in on ens18 from 10.20.30.12 to any proto vrrp comment 'Academy VRRP LB02'
sudo ufw status numbered
else
printf '%s\n' 'UFW not active: check your actual host/provider firewall manually'
fiسیاست فعال شبکه عبور پروتکل 112 بین دو نود، دسترسی کاربران مجاز به TCP/80 و دسترسی لودبالانسرها به بکاند را ممکن میکند؛ تأیید UFW بهتنهایی شبکهٔ بیرونی را اثبات نمیکند.
قدم بعدی
بستهها را از مخزن خود سیستمعامل نصب کن
روی هر دو نود از مخزن رسمی همان Ubuntu یا Debian استفاده کن؛ برای این راهنما مخزن متفرقه اضافه نکن. پیش از تأیید نصب، فهرست تغییرات بستهها را بخوان. نسخهٔ جزئی ممکن است با بهروزرسانی امنیتی تغییر کند، پس نسخهٔ نصبشده را بررسی کن و به عدد ثابت متکی نباش.
اگر هنگام نصب یک سرویس خودکار فعال شد، آن را نشانهٔ آمادهبودن HA در نظر نگیر. تنظیمات کامل HAProxy و VRRP در مراحل بعد نوشته میشود.
روی هر دو نود · ترمینال سرور با دسترسی sudo
sudo apt update
sudo apt install haproxy keepalived curl iproute2 tcpdump
haproxy -v
keepalived --version 2>&1 | head -n 2نصب بدون خطا پایان مییابد و نسخهٔ هر دو برنامه نمایش داده میشود؛ این مرحله هنوز چیزی دربارهٔ سلامت بکاند یا VIP ثابت نمیکند.
قدم بعدی
قبل از ویرایش از تنظیمات فعلی نسخهٔ پشتیبان بگیر
این سناریو فایلهای نمونه را روی دو سرور اختصاصی مینویسد. از پیکربندی فعلی HAProxy و در صورت وجود از Keepalived روی هر نود نسخهٔ پشتیبان با دسترسی محدود root بگیر. اگر سرویس دیگری در حال استفاده از این فایلهاست، بهجای جایگزینی مستقیم، ابتدا طرح مهاجرت داشته باش.
پشتیبان را در فضای امن نگه دار. بازگشت به وضعیت پیشین فقط وقتی مطمئن است که فایلهای اولیه را حفظ کرده باشی.
روی هر دو نود اختصاصی · با sudo
sudo install -d -m 0700 /root/wiunix-academy-ha-backup
sudo cp -a /etc/haproxy/haproxy.cfg /root/wiunix-academy-ha-backup/haproxy.cfg.before
if sudo test -f /etc/keepalived/keepalived.conf; then
sudo cp -a /etc/keepalived/keepalived.conf /root/wiunix-academy-ha-backup/keepalived.conf.before
fiپوشهٔ پشتیبان فقط برای root قابل دسترسی است و فایل اولیهٔ HAProxy و در صورت وجود Keepalived را دارد.
فایل HAProxy را روی هر دو نود باز کن
هر دو لودبالانسر باید پیکربندی مسیریابی HTTP یکسان داشته باشند. فایل را با ویرایشگر دارای دسترسی لازم باز کن؛ باکس بعدی محتوای فایل است و نباید مستقیم در ترمینال اجرا شود. اگر تنظیمات نامرتبطی وجود دارد، فقط با طرح ادغام آنها را حفظ کن.
مجموعهٔ بکاندها و معیار سلامت روی دو نود باید یکسان باشد؛ وگرنه ممکن است VIP منتقل شود اما ترافیک به برنامهٔ دیگری برسد.
روی هر دو نود · ترمینال با sudoedit
sudoedit /etc/haproxy/haproxy.cfgقدم بعدی
توزیع درخواست و کنترل سلامت HTTP را تعریف کن
محتوای زیر را روی هر دو لودبالانسر ذخیره کن. HAProxy روی همهٔ نشانیهای IPv4 همان میزبان گوش میدهد؛ بنابراین نود آمادهبهکار حتی قبل از مالکیت VIP میتواند پاسخ محلی بدهد. فرانتاند فقط HTTP روی پورت 80 است و توزیع درخواست میان دو برنامهٔ موجود بهصورت round-robin انجام میشود.
بررسی سلامت با درخواست GET انجام میشود و فقط پاسخ 200 پذیرفته است. نشانی و پورت دو بکاند و مقدار Host را متناسب با برنامهٔ خودت اصلاح کن؛ مسیر سلامت روی دو نود باید یکی باشد. بازبودن پورت یا فعالبودن سرویس بهتنهایی جای این بررسی را نمیگیرد.
این نمونه عمداً فقط HTTP در شبکهٔ خصوصی است. برای سرویس اینترنتی باید HTTPS، کنترل دسترسی، محدودیت درخواست و اعتماد به هدرهای پراکسی را در یک تغییر جداگانه بررسی کنی؛ این پورت آزمایشی را عمومی نکن.
محتوای فایل · در ویرایشگر هر دو نود قرار بده؛ این باکس دستور ترمینال نیست
global
log /dev/log local0
user haproxy
group haproxy
daemon
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5s
timeout client 30s
timeout server 30s
frontend public_http
bind 0.0.0.0:80
default_backend web_apps
backend web_apps
balance roundrobin
option httpchk
http-check send meth GET uri /healthz ver HTTP/1.1 hdr Host lab.internal
http-check expect status 200
server app1 10.20.30.21:8080 check inter 2s fall 3 rise 2
server app2 10.20.30.22:8080 check inter 2s fall 3 rise 2در هر دو فایل فرانتاند، بکاندها و شرط دقیق پاسخ 200 یکسان هستند و مقادیر نمونه با محیط واقعی جایگزین شدهاند.
قدم بعدی
HAProxy را اعتبارسنجی و روی هر دو نود اجرا کن
قبل از تغییر سرویس، کل پیکربندی ذخیرهشده را بررسی کن. فقط در صورت موفقیت اعتبارسنجی، سرویس را راهاندازی مجدد کن. ریاستارت سرویس در حال استفاده میتواند اتصالها را قطع کند؛ اینجا فرض بر راهاندازی اولیهٔ آزمایشگاه اختصاصی است و تغییرهای بعدی باید نوبتی انجام شوند.
از روی هر نود یک درخواست واقعی از مسیر HAProxy بفرست. وقتی بکاندها سالماند، مسیر سلامت از پراکسی هم باید 200 برگرداند. با خطای 503 یا ریدایرکت، مرحلهٔ بعد را شروع نکن.
روی هر دو نود · اعتبارسنجی و راهاندازی مجدد با sudo؛ درخواست HTTP از خود نود
sudo haproxy -c -f /etc/haproxy/haproxy.cfg && sudo systemctl restart haproxy
sudo systemctl enable haproxy
systemctl is-active haproxy
status=$(curl --noproxy '*' --silent --show-error --max-time 4 \
-o /dev/null -w '%{http_code}' -H 'Host: lab.internal' http://127.0.0.1/healthz) && {
printf 'HTTP %s\n' "$status"
[ "$status" = 200 ]
}خروجی صرفاً نمونه:
Configuration file is valid
active
HTTP 200بررسی فایل بدون خطا است، سرویس فعال است و درخواست سلامت از مسیر پراکسی محلی با پاسخ 200 موفق میشود.
اسکریپت کوچک بررسی سلامت برای Failover را آماده کن
Keepalived نباید صرفاً روشنبودن پردازش را نشانهٔ سلامت بداند. این اسکریپت از مسیر واقعی HAProxy در loopback پاسخ سلامت برنامه را میخواهد و با پاسخ غیر از حالت موفق، شکست میخورد. هیچ رمز یا توکنی در آن ذخیره نمیشود و با کاربر کمدسترسی nobody اجرا خواهد شد.
برای کنترل امنیت اسکریپت از مسیر اجرایی مطلق در پوشهای با مالکیت root استفاده کن. روی هر دو نود فایل تازهای بساز؛ باکس بعدی کل محتوای آن است.
روی هر دو نود · sudoedit · فایل تازه با مالکیت root
sudoedit /usr/local/sbin/wiunix-check-haproxyقدم بعدی
سلامت VRRP را به پاسخ واقعی HTTP وصل کن
این محتوا را در فایل اسکریپت جدید ذخیره کن. کد خروج صفر فقط وقتی برمیگردد که مسیر سلامت برنامه از طریق HAProxy محلی موفق شود. این روش نشان میدهد حداقل یک بکاند قابل استفاده است؛ سالمبودن هر دو بکاند یا دسترسپذیری VIP از بیرون را ثابت نمیکند.
مقدار Host و مسیر سلامت را با HAProxy و برنامه هماهنگ نگه دار. محدودیت دوثانیهای و آستانههای خطا در Keepalived احتمال واکنش کاذب را کمتر میکنند اما قطعی صفر را تضمین نمیکنند.
کد پاسخ دقیقاً با 200 مقایسه میشود؛ ریدایرکت و هر کد دیگری حتی با موفقیت انتقال curl، شکست محسوب میشود.
محتوای فایل · هر دو نود · نه برای اجرای مستقیم در ترمینال
#!/bin/sh
status=$(/usr/bin/curl --noproxy '*' --silent --show-error \
--connect-timeout 1 --max-time 2 -o /dev/null -w '%{http_code}' \
-H 'Host: lab.internal' http://127.0.0.1/healthz) || exit 1
[ "$status" = 200 ]اسکریپت برای پاسخ سالم برنامه کد صفر و برای درخواست HTTP ناموفق کد غیرصفر میدهد.
قدم بعدی
سطح دسترسی اسکریپت و نتیجهٔ اجرا را بررسی کن
مالک فایل باید root باشد ولی کاربر کمدسترسی اجازهٔ خواندن و اجرای آن را داشته باشد. وجود حساب nobody و گروه nogroup را بررسی کن. سپس همان آزمون را با این هویت اجرا کن؛ تا وقتی نتیجهٔ HTTP سالم نیست، VIP را فعال نکن.
پوشهٔ بالادستی اسکریپت را برای کاربران عادی قابلنوشتن نکن و برای دورزدن خطای مجوز، دسترسی root به چک سلامت نده.
روی هر دو نود · sudo برای مالکیت و اجرای آزمایشی با کاربر محدود
getent passwd nobody
getent group nogroup
sudo chown root:root /usr/local/sbin/wiunix-check-haproxy
sudo chmod 0755 /usr/local/sbin/wiunix-check-haproxy
sudo -u nobody /usr/local/sbin/wiunix-check-haproxy
printf "health-check exit=%s\n" "$?"EXAMPLE OUTPUT ONLY:
health-check exit=0اسکریپت کمدسترسی با کد صفر تمام میشود؛ در صورت شکست، تا اصلاح مسیر سلامت نباید Keepalived را شروع کرد.
فایل Keepalived را روی LB-01 باز کن
ابتدا نود ترجیحی را تنظیم کن. هر دو نود با وضعیت BACKUP شروع میشوند؛ اولویت بیشتر فقط هنگام انتخاب مالک اولیه اثر دارد. در این طرح MASTER اجباری یا بازپسگیری خودکار VIP در نظر گرفته نشده است.
اگر کارت شبکه و نشانیهای واقعی با مثال متفاوت است، همهٔ مقدارها را در هر دو فایل هماهنگ کن. شناسهٔ VRID روی دو نود باید یکسان و در شبکه یکتا باشد.
فقط روی LB-01 · sudoedit
sudoedit /etc/keepalived/keepalived.confقدم بعدی
نود ترجیحی LB-01 را تنظیم کن
این فایل را فقط روی LB-01 ذخیره کن. در زیرشبکهٔ مشترک، اولویت این نود 150 است و اعلانهای VRRP با پروتکل IP شمارهٔ 112 مستقیم برای LB-02 ارسال میشوند. چون وزن اسکریپت صفر است، سه شکست پیاپی نود را وارد وضعیت FAULT میکند و فقط عدد اولویت را کاهش نمیدهد.
گزینهٔ nopreempt مانع پسگرفتن خودکار مالکیت پس از بازگشت نود ترجیحی است. این رفتار به معنی Failback کنترلشده است، نه تضمین انتقال بدون وقفه.
محتوای فایل · فقط LB-01
global_defs {
router_id WIUNIX_LB01
enable_script_security
script_user nobody nogroup
}
vrrp_script chk_haproxy {
script "/usr/local/sbin/wiunix-check-haproxy"
interval 2
timeout 2
fall 3
rise 2
}
vrrp_instance VI_HTTP {
state BACKUP
interface ens18
virtual_router_id 51
priority 150
advert_int 1
nopreempt
unicast_src_ip 10.20.30.11
unicast_peer {
10.20.30.12
}
virtual_ipaddress {
10.20.30.100/24 dev ens18
}
track_script {
chk_haproxy
}
}نود LB-01 با نشانی واقعی خودش اعلان میفرستد، LB-02 را همتا میشناسد و VIP و VRID توافقشده را دارد.
فایل مستقل نود دوم را باز کن
فایل Keepalived در LB-02 باید مستقل نوشته شود؛ کپی بدون تغییر فایل نود اول صحیح نیست. نشانی مبدأ، نشانی همتا، هویت نود و اولویت تفاوت دارند اما VIP، شناسهٔ VRID و سیاست سلامت باید برابر باشند.
نام کارت شبکه را روی خود LB-02 بررسی کن؛ نام اینترفیس در دو سرور لزوماً یکسان نیست.
فقط روی LB-02 · sudoedit
sudoedit /etc/keepalived/keepalived.confقدم بعدی
نود آمادهبهکار LB-02 را تنظیم کن
این نسخه را فقط روی LB-02 ذخیره کن. نشانی محلی نمونه 10.20.30.12 و همتا 10.20.30.11 است. اولویت 100 آن را در حالت عادی نود آمادهبهکار میکند، اما پس از خرابی مالک فعلی میتواند VIP را بگیرد.
نشانیها نمونه هستند؛ اگر فقط فایل نود اول یا فقط نشانی مبدأ را اصلاح کنی، ممکن است ارتباط VRRP قطع شود و هر دو نود همزمان VIP را تصاحب کنند.
محتوای فایل · فقط LB-02
global_defs {
router_id WIUNIX_LB02
enable_script_security
script_user nobody nogroup
}
vrrp_script chk_haproxy {
script "/usr/local/sbin/wiunix-check-haproxy"
interval 2
timeout 2
fall 3
rise 2
}
vrrp_instance VI_HTTP {
state BACKUP
interface ens18
virtual_router_id 51
priority 100
advert_int 1
nopreempt
unicast_src_ip 10.20.30.12
unicast_peer {
10.20.30.11
}
virtual_ipaddress {
10.20.30.100/24 dev ens18
}
track_script {
chk_haproxy
}
}در LB-02 همتا LB-01 است، اولویت 100 تنظیم شده و VIP، VRID و چک سلامت با نود اول یکسان است.
قدم بعدی
پیش از تخصیص VIP هر دو فایل VRRP را اعتبارسنجی کن
Keepalived حالت بررسی پیکربندی دارد. دستور را روی هر نود اجرا کن و هشدارها را هم بخوان، نه فقط کد خروج. نام اینترفیس، مجوز اجرای اسکریپت و جهت نشانی مبدأ/همتا را بررسی کن. فایل بدون خطای نگارشی هنوز تضمین نمیکند که شبکه اعلان VRRP یا جابهجایی VIP را میپذیرد.
هشدارهای مربوط به امنیت اسکریپت و مجوز فایل باید قبل از انتخابات VRRP رفع شوند.
روی هر دو نود · اعتبارسنجی با sudo و آزمون اسکریپت کمدسترسی
sudo keepalived --config-test -f /etc/keepalived/keepalived.conf
sudo -u nobody /usr/local/sbin/wiunix-check-haproxy
printf "script exit=%s\n" "$?"خطای بازدارندهٔ پیکربندی یا امنیتی وجود ندارد و اسکریپت کد صفر میدهد؛ مالکیت یکتای VIP هنوز باید جداگانه بررسی شود.
قدم بعدی
VRRP را اجرا کن و پیامهای انتخاب مالک را ببین
وقتی HAProxy روی هر دو نود سالم است و ارتباط همتاها در شبکه آماده شده، Keepalived را روی LB-01 و LB-02 فعال و راهاندازی مجدد کن. شروع هر دو با BACKUP عمدی است. در شرایط معمول نود سالم با اولویت بالاتر مالک اولیه میشود، اما زمان شروع و وضعیت قبلی میتواند روی نتیجه اثر بگذارد.
در گزارش سرویس به تغییرهای MASTER، BACKUP و FAULT توجه کن. فعالبودن پردازش Keepalived در هر دو نود طبیعی است و به معنی مالکیت VIP در هر دو نیست.
روی هر دو نود · ترمینال همان سرور · تغییر سرویس و مشاهدهٔ لاگ با sudo
sudo systemctl enable keepalived
sudo systemctl restart keepalived
systemctl is-active keepalived
sudo journalctl -u keepalived -n 40 --no-pagerEXAMPLE OUTPUT ONLY — host names and log timestamps vary:
LB-01: (VI_HTTP) Entering MASTER STATE
LB-02: (VI_HTTP) Entering BACKUP STATEKeepalived در هر دو نود فعال است و گزارشها یک MASTER و یک BACKUP نشان میدهند. اگر نودی در FAULT ماند، علت را پیدا کن و MASTER را اجباری نکن.
قدم بعدی
مطمئن شو VIP دقیقاً روی یک نود قرار دارد
نشانیهای کارت شبکهٔ مربوط به HA را جداگانه در LB-01 و LB-02 مشاهده کن. فقط یکی باید نشانی VIP را علاوه بر IP اصلی خودش داشته باشد. فعالبودن پردازش Keepalived را بهجای این بررسی قبول نکن.
اگر هر دو نود VIP را دارند، احتمال قطع اعلانهای همتا، اشتباهبودن VRID یا اینترفیس و Split-brain وجود دارد. تا زمان رفع علت، ترافیک کاربر را به این نشانی نفرست.
جداگانه در LB-01 و LB-02 · کارت شبکهٔ واقعی خودت را بررسی کن
ip -br -4 address show dev ens18
sudo journalctl -u keepalived -n 25 --no-pagerEXAMPLE ONLY — separate observations:
LB-01: ens18 UP 10.20.30.11/24 10.20.30.100/24
LB-02: ens18 UP 10.20.30.12/24نشانی 10.20.30.100/24 تنها روی یکی از دو سرور قرار دارد و گزارش هر دو نود دربارهٔ MASTER و BACKUP سازگار است.
قدم بعدی
از دستگاه سوم به VIP درخواست HTTP بفرست
درخواست را از دستگاه سومی بفرست که دسترسی شبکهٔ مجاز دارد؛ تست روی خود نود فعال کافی نیست. یک درخواست واقعی به VIP ارسال کن و موفقبودن پاسخ HTTP و تعلق آن به برنامهٔ موردنظر را بررسی کن.
ترکیب مالکیت یکتای VIP، پاسخ موفق از دستگاه بیرونی و محتوای واقعی برنامه نشان میدهد مسیر فعلی کار میکند. این نتیجه هنوز Failover یا حفظ اتصالهای باز هنگام خرابی سرور را ثابت نمیکند.
دستگاه سوم در شبکهٔ مجاز آزمایش · کاربر عادی؛ VIP و Host را با مقادیر واقعی جایگزین کن
result=$(curl --noproxy '*' --silent --show-error --connect-timeout 3 --max-time 8 \
-H 'Host: lab.internal' -o /dev/null -w '%{http_code} %{remote_ip}' \
http://10.20.30.100/) && {
printf 'HTTP status and peer: %s\n' "$result"
case "$result" in
2[0-9][0-9]\ *) true ;;
*) printf '%s\n' 'FAIL: expected HTTP 2xx without a redirect' >&2; false ;;
esac
}خروجی صرفاً نمونه؛ حاصل آزمون عملی نیست:
HTTP status and peer: 200 10.20.30.100درخواست موفق میشود و از نشانی VIP پاسخ کاربردی 2xx برمیگردد. درخواست مستقیم به IP اصلی یک نود معادل این آزمون نیست.
قدم بعدی
خرابی لودبالانسر فعال را کنترلشده شبیهسازی کن
در زمان نگهداری هماهنگشده، ابتدا از مرحلهٔ قبل مالک واقعی VIP را پیدا کن. فقط روی همان نود HAProxy را متوقف کن، نه Keepalived را؛ در این حالت چک HTTP شکست میخورد و Keepalived میتواند VIP را به همتا منتقل کند. دستور زیر فرض میکند LB-01 مالک فعلی است؛ اگر LB-02 مالک بود، توقف را روی همان LB-02 اجرا کن.
در مدت شکستهای پیاپی چک، انتخابات VRRP و بهروزرسانی ARP ممکن است وقفهٔ کوتاه رخ دهد. این آزمایش عمداً سرویس فعال را مختل میکند؛ بدون مجوز، امکان بازگشت و مانیتورینگ روی کاربران واقعی اجرا نکن.
پس از توقف، برای گذشتن از آستانههای تشخیص کمی صبر کن. هر دو لودبالانسر را همزمان متوقف نکن.
فقط نودی که همین حالا VIP را در اختیار دارد (در مثال LB-01) · با sudo؛ تست مختلکننده
sudo systemctl stop haproxy
sleep 10
ip -br -4 address show dev ens18
sudo journalctl -u keepalived -n 30 --no-pagerپس از رسیدن به آستانهٔ شکست سلامت، VIP از نود خراب حذف میشود و همتای سالم امکان تصاحب آن را پیدا میکند؛ نتیجه را در هر دو سرور بررسی کن.
قدم بعدی
انتقال مالکیت VIP را روی هر دو لودبالانسر ثابت کن
پس از توقف HAProxy فعال قبلی، نشانیهای کارت شبکه را جداگانه روی LB-01 و LB-02 ببین. VIP باید از نود قبلی حذف و روی همتای سالم ثبت شده باشد؛ مالکیت همزمان هر دو نود نشانهٔ Split-brain است.
این بررسی فقط انتقال مالکیت IP را ثابت میکند. برای اطمینان از پاسخگویی برنامه، درخواست HTTP را از دستگاه سوم تکرار کن.
جداگانه روی LB-01 و LB-02، نه روی دستگاه سوم
ip -br -4 address show dev ens18خروجی صرفاً نمونه؛ پس از توقف LB-01:
LB-01: ens18 UP 10.20.30.11/24
LB-02: ens18 UP 10.20.30.12/24 10.20.30.100/24VIP فقط روی لودبالانسر قبلاً آمادهبهکار دیده میشود.
قدم بعدی
تداوم پاسخگویی را از دستگاه سوم بررسی کن
حالا همان درخواست برنامه را از دستگاه سومی بیرون از دو لودبالانسر بفرست. معیار موفقیت، پاسخ HTTP از خود VIP قبلی و برنامهٔ موردنظر پس از تغییر مالک است.
انتقال VIP یا تغییر وضعیت Keepalived بهتنهایی بازیابی دسترسی کاربر را ثابت نمیکند. در صورت timeout، ابتدا ARP و قابلیت انتقال نشانی در شبکهٔ بالادستی را بررسی کن.
فقط دستگاه سوم؛ Host و VIP نمونه را جایگزین کن
result=$(curl --noproxy '*' --silent --show-error --connect-timeout 3 --max-time 8 \
-H 'Host: lab.internal' -o /dev/null -w '%{http_code} %{remote_ip}' \
http://10.20.30.100/) && {
printf 'HTTP status and peer: %s\n' "$result"
case "$result" in
2[0-9][0-9]\ *) true ;;
*) printf '%s\n' 'FAIL: expected HTTP 2xx without a redirect' >&2; false ;;
esac
}خروجی صرفاً نمونه؛ حاصل آزمون عملی نیست:
HTTP status and peer: 200 10.20.30.100پس از انتقال مالکیت، دستگاه سوم پاسخ HTTP موفق برنامه را از VIP دریافت میکند.
قدم بعدی
نود قبلی را بازیابی کن؛ بازگشت مالکیت خودکار نیست
روی همان نودی که برای آزمایش متوقف کرده بودی، HAProxy را دوباره اجرا کن و سلامت محلی را تأیید کن. با nopreempt در هر دو همتا، معمولاً VIP روی MASTER سالم فعلی باقی میماند و صرفاً بهخاطر اولویت بیشتر به نود قبلی برنمیگردد.
نشانیهای هر دو نود و پاسخ دستگاه سوم را دوباره ببین. برای بازگرداندن عمدی مالکیت در آینده، زمان نگهداری مشخص کن و فقط پس از اطمینان از سلامت نود بازیابیشده، Keepalived را روی MASTER فعلی متوقف کن. راهافتادن دوبارهٔ پردازش با بازپسگیری VIP یک چیز نیست.
نودی که قبلاً HAProxy روی آن متوقف شد · بازیابی سرویس با sudo
sudo systemctl start haproxy
systemctl is-active haproxy
sudo -u nobody /usr/local/sbin/wiunix-check-haproxy
ip -br -4 address show dev ens18نود بازیابیشده پاسخ HTTP سالم دارد، اما تا زمان انتقال دستیِ برنامهریزیشده VIP روی همتای فعال میماند؛ مگر اینکه خرابی دیگری رخ داده باشد.
خطا را در لایهٔ درست پیدا کن
چهار لایه را از هم جدا بررسی کن: سلامت برنامههای بکاند، پاسخ HTTP محلی HAProxy، مالکیت یکتای VIP و در نهایت درخواست واقعی کاربر از شبکه. دستور تشخیص هر خطا در باکس کد همان مورد قرار دارد تا قابل کپی باشد. معتبر بودن فایل، روشنبودن سرویس یا وجود ARP بهتنهایی به معنی پایداری درخواست نیست.
اگر خرابی باعث مالکیت همزمان VIP شده، ابتدا مسیر ورود کاربران را ایمن کن. در خرابی یک بکاند، خود همان برنامه را تعمیر کن؛ با خرابی هر دو بکاند، سیاست سلامت این راهنما میتواند عمداً VIP را آزاد کند.
هر دو سرور VIP را دارند
احتمال Split-brain وجود دارد: پروتکل 112 مسدود است، نشانی همتا اشتباه است یا VRID و کارت شبکه هماهنگ نیست. اعلانها را در دو طرف ببین و تا یکتا شدن مالکیت، ترافیک کاربر را وصل نکن.
sudo tcpdump -n -i ens18 -c 8 'ip proto 112'
sudo journalctl -u keepalived -n 80 --no-pager
ip -br -4 address show dev ens18هیچ نودی VIP را ندارد
ممکن است چک سلامت در هر دو نود شکست خورده باشد و هر دو در FAULT مانده باشند. پاسخ محلی HTTP و نتیجهٔ هر بکاند را بررسی کن؛ وقتی همهٔ بکاندها خراباند VIP را بهزور فعال نکن.
sudo -u nobody /usr/local/sbin/wiunix-check-haproxy; printf 'exit=%s\n' "$?"
curl --noproxy '*' -i --max-time 4 -H 'Host: lab.internal' http://10.20.30.21:8080/healthz
curl --noproxy '*' -i --max-time 4 -H 'Host: lab.internal' http://10.20.30.22:8080/healthz
sudo journalctl -u keepalived -n 80 --no-pagerVIP منتقل میشود ولی درخواست کاربر timeout است
دیدهشدن VIP روی نود به معنی دسترسی بیرونی نیست. کش همسایهٔ دستگاه سوم، کارت شبکهٔ مالک، مسیر بستهها و محدودیتهای IP ثانویه یا ضد جعل آدرس در شبکهٔ بالادست را بررسی کن.
ip -4 neigh show 10.20.30.100
ip -4 route get 10.20.30.100
sudo tcpdump -n -i ens18 -c 12 'arp or (ip and tcp port 80)'HAProxy پاسخ 503 میدهد یا بکاندها DOWN هستند
پاسخ 503 معمولاً یعنی بکاند قابل استفادهای وجود ندارد. چک تنظیمشده نیازمند پاسخ دقیق 200، Host درست و پورت قابل دسترس است. این سه مورد را از هر دو نود بررسی کن و برای پنهانکردن خطا چکها را خاموش نکن.
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
curl --noproxy '*' -i --max-time 4 -H 'Host: lab.internal' http://10.20.30.21:8080/healthz
curl --noproxy '*' -i --max-time 4 -H 'Host: lab.internal' http://10.20.30.22:8080/healthz
sudo journalctl -u haproxy -n 60 --no-pagerاسکریپت خطا دارد یا Keepalived در FAULT میماند
مالکیت root، حق اجرا، وجود nobody/nogroup، نصب curl و پاسخ HTTP محلی مهماند. اسکریپت را با همان کاربر تعریفشده اجرا کن و گزارشهای امنیتی را ببین.
sudo keepalived --config-test -f /etc/keepalived/keepalived.conf
ls -l /usr/local/sbin/wiunix-check-haproxy
sudo -u nobody /usr/local/sbin/wiunix-check-haproxy; printf 'exit=%s\n' "$?"
sudo journalctl -u keepalived -n 80 --no-pagerفایل معتبر است ولی HAProxy نمیتواند روی 80 گوش بدهد
ممکن است پردازش دیگری مالک پورت یا نشانی باشد. ابتدا مالک را پیدا کن؛ برای رفع تداخل، وبسرور تولیدی را کورکورانه متوقف نکن.
sudo ss -ltnp | grep -E ':80[[:space:]]' || true
sudo journalctl -u haproxy -n 80 --no-pagerدو نود را بدون راهاندازی مجدد کورکورانه نگهداری کن
مانیتورینگ را از دستگاه سوم انجام بده، نه فقط از داخل دو لودبالانسر. مالکیت VIP، پاسخ برنامه، سلامت بکاندها، وضعیت VRRP، ازدسترفتن بسته و خطاهای قابل مشاهدهٔ کاربران را جداگانه دنبال کن. مدیریت نشست و دادهٔ مشترک برنامه مسئلهای مستقل است؛ این معماری اتصالهای TCP برقرار را الزاماً حفظ نمیکند.
بعد از بهروزرسانی بستهها یا سیستمعامل، پیکربندی را اعتبارسنجی کن و هر بار فقط یک نود را تغییر بده. استثنای VRRP در فایروال و مجوز IP شناور شبکه باید در مدیریت تغییر ثبت شود. نسخهٔ سالم تنظیمات را نگه دار و آزمون Failover را برنامهریزیشده انجام بده.
دستورهای این بخش فقط وضعیت نودها را میخوانند و اختلالی ایجاد نمیکنند؛ همچنان بررسی جداگانه از دستگاه بیرونی ضروری است.
روی هر دو نود · بررسی دورهایِ فقطخواندنی
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
sudo keepalived --config-test -f /etc/keepalived/keepalived.conf
systemctl is-active haproxy keepalived
ip -br -4 address show dev ens18
sudo journalctl -u keepalived -n 40 --no-pagerبازگشت ایمن: ابتدا VIP آزمایشی را جمع کن
این روش بازگشت فقط برای نصب تازه روی سرورهای اختصاصی همین آموزش است، نه کلاستر VRRP موجود. جمعکردن VIP دسترسی کاربر به ورودی آزمایش را قطع میکند؛ بنابراین بازهٔ نگهداری لازم است. Keepalived را روی هر دو نود متوقف کن تا هنگام بازیابی تنظیمات هیچکدام IP مجازی را اعلان نکنند.
IP اصلی سرورها، مسیر SSH یا کل فایروال را پاک نکن. اگر سرورها پیش از این آموزش عضو سرویس VRRP دیگری بودهاند، از این توقف عمومی استفاده نکن و به طرح تغییرات قبلی همان سرویس برگرد.
روی هر دو نود · در زمان نگهداری هماهنگشده · با sudo
sudo systemctl disable --now keepalived
ip -br -4 address show dev ens18VIP آزمایشی در هیچکدام از دو نود دیده نمیشود؛ ورودی آزمایش عمداً قطع است ولی دادهٔ برنامه حذف نمیشود.
فایل قبلی HAProxy را برگردان و اسکریپت آزمایش را جمع کن
در هر نود فایل قبلی HAProxy را از پشتیبان محدودشده به root برگردان؛ قبل از راهاندازی مجدد، اعتبار آن را بررسی کن. اگر پیش از تمرین فایل Keepalived وجود داشت، محتوای قبلی را برگردان اما کلاستر قدیمی را بدون بازبینی تغییرات دوباره فعال نکن.
فقط وقتی مطمئن شدی سرویس دیگری به اسکریپت تمرین وابسته نیست، آن را پاک کن. قوانین UFW یا فایروال بیرونی که برای آزمایش افزودهای باید طبق ثبت تغییرات بهصورت جداگانه بازگردند. حذف بستهها اجباری نیست و وابستگی سرویسهای دیگر نباید پاک شود. دستورها دادهٔ بکاند یا پوشهٔ پشتیبان را حذف نمیکنند.
روی هر دو نود · با sudo · فقط پس از بررسی صحت پشتیبان و وابستگی اسکریپت
sudo cp -a /root/wiunix-academy-ha-backup/haproxy.cfg.before /etc/haproxy/haproxy.cfg
sudo haproxy -c -f /etc/haproxy/haproxy.cfg && sudo systemctl restart haproxy
if sudo test -f /root/wiunix-academy-ha-backup/keepalived.conf.before; then
sudo cp -a /root/wiunix-academy-ha-backup/keepalived.conf.before /etc/keepalived/keepalived.conf
fi
sudo rm -f /usr/local/sbin/wiunix-check-haproxy
systemctl is-active haproxyتنظیمات اصلی HAProxy برمیگردد و معتبر است، VIP آزمایشی جمعشده باقی میماند و دادهٔ برنامه پاک نشده است.
این آزمایش دقیقاً چه چیزی را ثابت میکند؟
حاصل این راهنما دو پردازش مستقل برای توزیع HTTP، یک VIP با مالک یکتا از طریق VRRP unicast، شرط آزادسازی IP هنگام شکست پاسخ سلامت و روش آزمون بازگشت درخواست کاربران پس از خرابی لودبالانسر است. تنظیمات برگرفته از مستندات و خروجیهای نمونه تا وقتی در شبکهٔ خودت اجرا نشدهاند، فقط آموزش به شمار میآیند.
این آزمایش تضمین نمیکند هیچ درخواستی از دست نرود، نشستهای فعال باقی بمانند، پایگاه داده خودکار Failover کند، TLS برقرار باشد، IP شناور روی هر ابر کار کند یا بازیابی بین چند دیتاسنتر انجام شود. این نیازها طراحی و آزمون مستقل میخواهند.
پشتوانهٔ این آموزش
منابع رسمی
وضعیت بررسی هر محیط بالای صفحه مشخص است؛ بررسی مستندات به معنی اجرای عملی همهٔ نسخهها نیست.
- راهنمای رسمی پیکربندی HAProxy نسخهٔ 2.4
- راهنمای رسمی HAProxy نسخهٔ 3.4
- آموزش رسمی بررسی سلامت بکاند در HAProxy
- مرجع رسمی تنظیمات Keepalived
- راهنمای رسمی گزینههای اجرای Keepalived
- اطلاعیهٔ رسمی انتشار Ubuntu 26.10
- فهرست نسخههای HAProxy در Ubuntu
- فهرست نسخههای Keepalived در Ubuntu
- بستهٔ HAProxy در Debian 13
- بستهٔ Keepalived در Debian 13
- راهنمای رسمی UFW و پروتکل VRRP
- دامنهٔ پشتیبانی امنیتی Debian 12 LTS