صحنهٔ تصویری آموزشی آکادمی ویونیکس با کیت پشت میز، دو لودبالانسر LB-01 و LB-02 و نمودار مفهومی انتقال IP مجازی؛ نام سیستم‌عامل در تصویر نیست.

WIUNIX ACADEMY

راه‌اندازی لودبالانسر HAProxy و Keepalived با VIP و VRRP

دو HAProxy را با یک IP مجازی مشترک راه‌اندازی کن، ترافیک را به بک‌اندهای سالم برسان و انتقال VIP و دسترسی کاربر را هنگام خرابی با Keepalived و VRRP بررسی کن.

متوسط40 دقیقه مطالعهبه‌روزرسانی
محیطت را انتخاب کن

آموزش متناسب با محیط تو

کجا اجرا می‌کنی؟

سیستم‌عامل و نسخه را انتخاب کن تا مراحل، دستورها و راه‌حل‌ها برای همان محیط نمایش داده شوند.

Ubuntu 24.04 LTSبررسی‌شده با مستندات رسمی ·

از اینجا شروع کن

در پایان چه چیزی خواهی داشت؟

درخواست واقعی HTTP را از یک VIP مشترک عبور بده، مالکیت یکتای آن را ثابت کن و پس از توقف لودبالانسر فعال، از دستگاه سوم انتقال VIP و پاسخ سالم برنامه را بررسی کن.

01دستگاه کاربردرخواست HTTP به یک IP مجازی · 10.20.30.100:80
02Keepalived و VRRPLB-01 با 10.20.30.11 و LB-02 با 10.20.30.12 · فقط یک مالک VIP
03HAProxyنود فعال درخواست‌ها را نوبتی به بک‌اندهایی با پاسخ سلامت 200 می‌فرستد
04برنامه‌های بک‌اندapp1 روی 10.20.30.21:8080 و app2 روی 10.20.30.22:8080
سیستم‌عامل‌ها و نسخه‌های پوشش‌داده‌شده

مسیرهای بررسی‌شده با اسناد رسمی: 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 و امنیت برنامه باید جداگانه طراحی و بررسی شوند.
01

قدم بعدی

دو سرور لودبالانسر را شناسایی کن

در این تمرین یک نقطهٔ ورود 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 داری، این سناریوی نصب تازه را بدون طراحی مهاجرت اجرا نکن.

Bash

روی هر دو نود · ترمینال همان سرور · بررسی فقط‌خواندنی؛ برای مالک پردازش‌ها دسترسی 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 مالک ناشناخته‌ای ندارد.

02

قدم بعدی

سلامت واقعی هر بک‌اند را جداگانه بررسی کن

پیش از تنظیم جابه‌جایی خودکار، دو برنامهٔ HTTP مستقل و دارای سرویس مدیریتی آماده داشته باش: app1 روی 10.20.30.21:8080 و app2 روی 10.20.30.22:8080. هر دو باید برای درخواست GET به مسیر /healthz با Host نمونهٔ lab.internal دقیقاً پاسخ 200 بدهند و در مسیر / هم پاسخ کاربردی داشته باشند. نشانی‌ها، پورت، Host و مسیر سلامت را با شرایط برنامهٔ واقعی هماهنگ کن؛ این آموزش یک وب‌سرور آزمایشی ناامن را راه‌اندازی نمی‌کند.

این درخواست‌ها را از هر دو لودبالانسر بفرست. بازبودن پورت TCP کافی نیست؛ اگر مسیر سلامت به صفحهٔ ورود، ریدایرکت یا پاسخ خطا می‌رسد، ابتدا آن را اصلاح کن. موفقیت این بخش هنوز انتقال VIP را ثابت نمی‌کند.

Bash

روی هر دو لودبالانسر · کاربر عادی · مقادیر نمونهٔ بک‌اند را با محیط خودت جایگزین کن

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 می‌دهند و پاسخ مسیر اصلی برنامه نیز دریافت می‌شود؛ با سالم‌بودن فقط یک بک‌اند، مجموعهٔ دو‌بک‌اندی آماده نیست.

03

قدم بعدی

مسیر شبکه و فایروال را آماده کن

با مسئول شبکه هماهنگ کن که VIP و شناسهٔ VRID در این شبکه تکراری نباشند. پیام‌های VRRP در حالت unicast از پروتکل IP شمارهٔ 112 استفاده می‌کنند، نه از پورت 112 در TCP یا UDP. دریافت این پروتکل را فقط بین نشانی اصلی دو نود مجاز کن. دسترسی کاربران آزمایش به TCP/80 و دسترسی هر دو لودبالانسر به TCP/8080 بک‌اندها باید برقرار باشد. اگر شبکهٔ ابری IP ثانویه یا اعلان ARP هنگام انتقال را نمی‌پذیرد، ادامه نده و از قابلیت رسمی همان ارائه‌دهنده استفاده کن.

دستورهای این بخش فقط وقتی اجرا می‌شوند که UFW نصب و فعال باشد. دسترسی HTTP مثال به زیرشبکهٔ آزمایش محدود می‌شود و اجازهٔ VRRP نیز فقط برای دو همتای نمونه روی ens18 است. در سایر فایروال‌ها چیزی خودکار تغییر نمی‌کند؛ قواعد nftables، تجهیزات شبکه و سرویس‌دهنده را جداگانه بررسی کن. فایروال موجود را خاموش نکن.

پیش از ویرایش قوانین شبکه، اتصال کنسول یا مسیر مدیریتی جایگزین داشته باش. این سرویس HTTP بدون TLS صرفاً برای شبکهٔ خصوصی آزمایش است.

Bash

روی هر دو نود · با 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 به‌تنهایی شبکهٔ بیرونی را اثبات نمی‌کند.

04

قدم بعدی

بسته‌ها را از مخزن خود سیستم‌عامل نصب کن

روی هر دو نود از مخزن رسمی همان Ubuntu یا Debian استفاده کن؛ برای این راهنما مخزن متفرقه اضافه نکن. پیش از تأیید نصب، فهرست تغییرات بسته‌ها را بخوان. نسخهٔ جزئی ممکن است با به‌روزرسانی امنیتی تغییر کند، پس نسخهٔ نصب‌شده را بررسی کن و به عدد ثابت متکی نباش.

اگر هنگام نصب یک سرویس خودکار فعال شد، آن را نشانهٔ آماده‌بودن HA در نظر نگیر. تنظیمات کامل HAProxy و VRRP در مراحل بعد نوشته می‌شود.

Bash

روی هر دو نود · ترمینال سرور با دسترسی sudo

sudo apt update
sudo apt install haproxy keepalived curl iproute2 tcpdump
haproxy -v
keepalived --version 2>&1 | head -n 2
از کجا بدانم درست انجام شد؟

نصب بدون خطا پایان می‌یابد و نسخهٔ هر دو برنامه نمایش داده می‌شود؛ این مرحله هنوز چیزی دربارهٔ سلامت بک‌اند یا VIP ثابت نمی‌کند.

05

قدم بعدی

قبل از ویرایش از تنظیمات فعلی نسخهٔ پشتیبان بگیر

این سناریو فایل‌های نمونه را روی دو سرور اختصاصی می‌نویسد. از پیکربندی فعلی HAProxy و در صورت وجود از Keepalived روی هر نود نسخهٔ پشتیبان با دسترسی محدود root بگیر. اگر سرویس دیگری در حال استفاده از این فایل‌هاست، به‌جای جایگزینی مستقیم، ابتدا طرح مهاجرت داشته باش.

پشتیبان را در فضای امن نگه دار. بازگشت به وضعیت پیشین فقط وقتی مطمئن است که فایل‌های اولیه را حفظ کرده باشی.

Bash

روی هر دو نود اختصاصی · با 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 منتقل شود اما ترافیک به برنامهٔ دیگری برسد.

Bash

روی هر دو نود · ترمینال با sudoedit

sudoedit /etc/haproxy/haproxy.cfg
06

قدم بعدی

توزیع درخواست و کنترل سلامت HTTP را تعریف کن

محتوای زیر را روی هر دو لودبالانسر ذخیره کن. HAProxy روی همهٔ نشانی‌های IPv4 همان میزبان گوش می‌دهد؛ بنابراین نود آماده‌به‌کار حتی قبل از مالکیت VIP می‌تواند پاسخ محلی بدهد. فرانت‌اند فقط HTTP روی پورت 80 است و توزیع درخواست میان دو برنامهٔ موجود به‌صورت round-robin انجام می‌شود.

بررسی سلامت با درخواست GET انجام می‌شود و فقط پاسخ 200 پذیرفته است. نشانی و پورت دو بک‌اند و مقدار Host را متناسب با برنامهٔ خودت اصلاح کن؛ مسیر سلامت روی دو نود باید یکی باشد. بازبودن پورت یا فعال‌بودن سرویس به‌تنهایی جای این بررسی را نمی‌گیرد.

این نمونه عمداً فقط HTTP در شبکهٔ خصوصی است. برای سرویس اینترنتی باید HTTPS، کنترل دسترسی، محدودیت درخواست و اعتماد به هدرهای پراکسی را در یک تغییر جداگانه بررسی کنی؛ این پورت آزمایشی را عمومی نکن.

HAProxy · /etc/haproxy/haproxy.cfg

محتوای فایل · در ویرایشگر هر دو نود قرار بده؛ این باکس دستور ترمینال نیست

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 یکسان هستند و مقادیر نمونه با محیط واقعی جایگزین شده‌اند.

07

قدم بعدی

HAProxy را اعتبارسنجی و روی هر دو نود اجرا کن

قبل از تغییر سرویس، کل پیکربندی ذخیره‌شده را بررسی کن. فقط در صورت موفقیت اعتبارسنجی، سرویس را راه‌اندازی مجدد کن. ری‌استارت سرویس در حال استفاده می‌تواند اتصال‌ها را قطع کند؛ اینجا فرض بر راه‌اندازی اولیهٔ آزمایشگاه اختصاصی است و تغییرهای بعدی باید نوبتی انجام شوند.

از روی هر نود یک درخواست واقعی از مسیر HAProxy بفرست. وقتی بک‌اندها سالم‌اند، مسیر سلامت از پراکسی هم باید 200 برگرداند. با خطای 503 یا ریدایرکت، مرحلهٔ بعد را شروع نکن.

Bash

روی هر دو نود · اعتبارسنجی و راه‌اندازی مجدد با 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 استفاده کن. روی هر دو نود فایل تازه‌ای بساز؛ باکس بعدی کل محتوای آن است.

Bash

روی هر دو نود · sudoedit · فایل تازه با مالکیت root

sudoedit /usr/local/sbin/wiunix-check-haproxy
08

قدم بعدی

سلامت VRRP را به پاسخ واقعی HTTP وصل کن

این محتوا را در فایل اسکریپت جدید ذخیره کن. کد خروج صفر فقط وقتی برمی‌گردد که مسیر سلامت برنامه از طریق HAProxy محلی موفق شود. این روش نشان می‌دهد حداقل یک بک‌اند قابل استفاده است؛ سالم‌بودن هر دو بک‌اند یا دسترس‌پذیری VIP از بیرون را ثابت نمی‌کند.

مقدار Host و مسیر سلامت را با HAProxy و برنامه هماهنگ نگه دار. محدودیت دوثانیه‌ای و آستانه‌های خطا در Keepalived احتمال واکنش کاذب را کمتر می‌کنند اما قطعی صفر را تضمین نمی‌کنند.

کد پاسخ دقیقاً با 200 مقایسه می‌شود؛ ریدایرکت و هر کد دیگری حتی با موفقیت انتقال curl، شکست محسوب می‌شود.

Shell · /usr/local/sbin/wiunix-check-haproxy

محتوای فایل · هر دو نود · نه برای اجرای مستقیم در ترمینال

#!/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 ناموفق کد غیرصفر می‌دهد.

09

قدم بعدی

سطح دسترسی اسکریپت و نتیجهٔ اجرا را بررسی کن

مالک فایل باید root باشد ولی کاربر کم‌دسترسی اجازهٔ خواندن و اجرای آن را داشته باشد. وجود حساب nobody و گروه nogroup را بررسی کن. سپس همان آزمون را با این هویت اجرا کن؛ تا وقتی نتیجهٔ HTTP سالم نیست، VIP را فعال نکن.

پوشهٔ بالادستی اسکریپت را برای کاربران عادی قابل‌نوشتن نکن و برای دورزدن خطای مجوز، دسترسی root به چک سلامت نده.

Bash

روی هر دو نود · 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 روی دو نود باید یکسان و در شبکه یکتا باشد.

Bash

فقط روی LB-01 · sudoedit

sudoedit /etc/keepalived/keepalived.conf
10

قدم بعدی

نود ترجیحی LB-01 را تنظیم کن

این فایل را فقط روی LB-01 ذخیره کن. در زیرشبکهٔ مشترک، اولویت این نود 150 است و اعلان‌های VRRP با پروتکل IP شمارهٔ 112 مستقیم برای LB-02 ارسال می‌شوند. چون وزن اسکریپت صفر است، سه شکست پیاپی نود را وارد وضعیت FAULT می‌کند و فقط عدد اولویت را کاهش نمی‌دهد.

گزینهٔ nopreempt مانع پس‌گرفتن خودکار مالکیت پس از بازگشت نود ترجیحی است. این رفتار به معنی Failback کنترل‌شده است، نه تضمین انتقال بدون وقفه.

Keepalived · /etc/keepalived/keepalived.conf

محتوای فایل · فقط 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 بررسی کن؛ نام اینترفیس در دو سرور لزوماً یکسان نیست.

Bash

فقط روی LB-02 · sudoedit

sudoedit /etc/keepalived/keepalived.conf
11

قدم بعدی

نود آماده‌به‌کار LB-02 را تنظیم کن

این نسخه را فقط روی LB-02 ذخیره کن. نشانی محلی نمونه 10.20.30.12 و همتا 10.20.30.11 است. اولویت 100 آن را در حالت عادی نود آماده‌به‌کار می‌کند، اما پس از خرابی مالک فعلی می‌تواند VIP را بگیرد.

نشانی‌ها نمونه هستند؛ اگر فقط فایل نود اول یا فقط نشانی مبدأ را اصلاح کنی، ممکن است ارتباط VRRP قطع شود و هر دو نود هم‌زمان VIP را تصاحب کنند.

Keepalived · /etc/keepalived/keepalived.conf

محتوای فایل · فقط 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 و چک سلامت با نود اول یکسان است.

12

قدم بعدی

پیش از تخصیص VIP هر دو فایل VRRP را اعتبارسنجی کن

Keepalived حالت بررسی پیکربندی دارد. دستور را روی هر نود اجرا کن و هشدارها را هم بخوان، نه فقط کد خروج. نام اینترفیس، مجوز اجرای اسکریپت و جهت نشانی مبدأ/همتا را بررسی کن. فایل بدون خطای نگارشی هنوز تضمین نمی‌کند که شبکه اعلان VRRP یا جابه‌جایی VIP را می‌پذیرد.

هشدارهای مربوط به امنیت اسکریپت و مجوز فایل باید قبل از انتخابات VRRP رفع شوند.

Bash

روی هر دو نود · اعتبارسنجی با 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 هنوز باید جداگانه بررسی شود.

13

قدم بعدی

VRRP را اجرا کن و پیام‌های انتخاب مالک را ببین

وقتی HAProxy روی هر دو نود سالم است و ارتباط همتاها در شبکه آماده شده، Keepalived را روی LB-01 و LB-02 فعال و راه‌اندازی مجدد کن. شروع هر دو با BACKUP عمدی است. در شرایط معمول نود سالم با اولویت بالاتر مالک اولیه می‌شود، اما زمان شروع و وضعیت قبلی می‌تواند روی نتیجه اثر بگذارد.

در گزارش سرویس به تغییرهای MASTER، BACKUP و FAULT توجه کن. فعال‌بودن پردازش Keepalived در هر دو نود طبیعی است و به معنی مالکیت VIP در هر دو نیست.

Bash

روی هر دو نود · ترمینال همان سرور · تغییر سرویس و مشاهدهٔ لاگ با sudo

sudo systemctl enable keepalived
sudo systemctl restart keepalived
systemctl is-active keepalived
sudo journalctl -u keepalived -n 40 --no-pager
خروجی نمونه
EXAMPLE OUTPUT ONLY — host names and log timestamps vary:
LB-01: (VI_HTTP) Entering MASTER STATE
LB-02: (VI_HTTP) Entering BACKUP STATE
از کجا بدانم درست انجام شد؟

Keepalived در هر دو نود فعال است و گزارش‌ها یک MASTER و یک BACKUP نشان می‌دهند. اگر نودی در FAULT ماند، علت را پیدا کن و MASTER را اجباری نکن.

14

قدم بعدی

مطمئن شو VIP دقیقاً روی یک نود قرار دارد

نشانی‌های کارت شبکهٔ مربوط به HA را جداگانه در LB-01 و LB-02 مشاهده کن. فقط یکی باید نشانی VIP را علاوه بر IP اصلی خودش داشته باشد. فعال‌بودن پردازش Keepalived را به‌جای این بررسی قبول نکن.

اگر هر دو نود VIP را دارند، احتمال قطع اعلان‌های همتا، اشتباه‌بودن VRID یا اینترفیس و Split-brain وجود دارد. تا زمان رفع علت، ترافیک کاربر را به این نشانی نفرست.

Bash

جداگانه در LB-01 و LB-02 · کارت شبکهٔ واقعی خودت را بررسی کن

ip -br -4 address show dev ens18
sudo journalctl -u keepalived -n 25 --no-pager
خروجی نمونه
EXAMPLE 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 سازگار است.

15

قدم بعدی

از دستگاه سوم به VIP درخواست HTTP بفرست

درخواست را از دستگاه سومی بفرست که دسترسی شبکهٔ مجاز دارد؛ تست روی خود نود فعال کافی نیست. یک درخواست واقعی به VIP ارسال کن و موفق‌بودن پاسخ HTTP و تعلق آن به برنامهٔ موردنظر را بررسی کن.

ترکیب مالکیت یکتای VIP، پاسخ موفق از دستگاه بیرونی و محتوای واقعی برنامه نشان می‌دهد مسیر فعلی کار می‌کند. این نتیجه هنوز Failover یا حفظ اتصال‌های باز هنگام خرابی سرور را ثابت نمی‌کند.

Bash

دستگاه سوم در شبکهٔ مجاز آزمایش · کاربر عادی؛ 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 اصلی یک نود معادل این آزمون نیست.

16

قدم بعدی

خرابی لودبالانسر فعال را کنترل‌شده شبیه‌سازی کن

در زمان نگهداری هماهنگ‌شده، ابتدا از مرحلهٔ قبل مالک واقعی VIP را پیدا کن. فقط روی همان نود HAProxy را متوقف کن، نه Keepalived را؛ در این حالت چک HTTP شکست می‌خورد و Keepalived می‌تواند VIP را به همتا منتقل کند. دستور زیر فرض می‌کند LB-01 مالک فعلی است؛ اگر LB-02 مالک بود، توقف را روی همان LB-02 اجرا کن.

در مدت شکست‌های پیاپی چک، انتخابات VRRP و به‌روزرسانی ARP ممکن است وقفهٔ کوتاه رخ دهد. این آزمایش عمداً سرویس فعال را مختل می‌کند؛ بدون مجوز، امکان بازگشت و مانیتورینگ روی کاربران واقعی اجرا نکن.

پس از توقف، برای گذشتن از آستانه‌های تشخیص کمی صبر کن. هر دو لودبالانسر را هم‌زمان متوقف نکن.

Bash

فقط نودی که همین حالا 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 از نود خراب حذف می‌شود و همتای سالم امکان تصاحب آن را پیدا می‌کند؛ نتیجه را در هر دو سرور بررسی کن.

17

قدم بعدی

انتقال مالکیت VIP را روی هر دو لودبالانسر ثابت کن

پس از توقف HAProxy فعال قبلی، نشانی‌های کارت شبکه را جداگانه روی LB-01 و LB-02 ببین. VIP باید از نود قبلی حذف و روی همتای سالم ثبت شده باشد؛ مالکیت هم‌زمان هر دو نود نشانهٔ Split-brain است.

این بررسی فقط انتقال مالکیت IP را ثابت می‌کند. برای اطمینان از پاسخ‌گویی برنامه، درخواست HTTP را از دستگاه سوم تکرار کن.

Bash

جداگانه روی 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/24
از کجا بدانم درست انجام شد؟

VIP فقط روی لودبالانسر قبلاً آماده‌به‌کار دیده می‌شود.

18

قدم بعدی

تداوم پاسخ‌گویی را از دستگاه سوم بررسی کن

حالا همان درخواست برنامه را از دستگاه سومی بیرون از دو لودبالانسر بفرست. معیار موفقیت، پاسخ HTTP از خود VIP قبلی و برنامهٔ موردنظر پس از تغییر مالک است.

انتقال VIP یا تغییر وضعیت Keepalived به‌تنهایی بازیابی دسترسی کاربر را ثابت نمی‌کند. در صورت timeout، ابتدا ARP و قابلیت انتقال نشانی در شبکهٔ بالادستی را بررسی کن.

Bash

فقط دستگاه سوم؛ 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 دریافت می‌کند.

19

قدم بعدی

نود قبلی را بازیابی کن؛ بازگشت مالکیت خودکار نیست

روی همان نودی که برای آزمایش متوقف کرده بودی، HAProxy را دوباره اجرا کن و سلامت محلی را تأیید کن. با nopreempt در هر دو همتا، معمولاً VIP روی MASTER سالم فعلی باقی می‌ماند و صرفاً به‌خاطر اولویت بیشتر به نود قبلی برنمی‌گردد.

نشانی‌های هر دو نود و پاسخ دستگاه سوم را دوباره ببین. برای بازگرداندن عمدی مالکیت در آینده، زمان نگهداری مشخص کن و فقط پس از اطمینان از سلامت نود بازیابی‌شده، Keepalived را روی MASTER فعلی متوقف کن. راه‌افتادن دوبارهٔ پردازش با بازپس‌گیری VIP یک چیز نیست.

Bash

نودی که قبلاً 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 و کارت شبکه هماهنگ نیست. اعلان‌ها را در دو طرف ببین و تا یکتا شدن مالکیت، ترافیک کاربر را وصل نکن.

Bash
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 را به‌زور فعال نکن.

Bash
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-pager
VIP منتقل می‌شود ولی درخواست کاربر timeout است

دیده‌شدن VIP روی نود به معنی دسترسی بیرونی نیست. کش همسایهٔ دستگاه سوم، کارت شبکهٔ مالک، مسیر بسته‌ها و محدودیت‌های IP ثانویه یا ضد جعل آدرس در شبکهٔ بالادست را بررسی کن.

Bash
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 درست و پورت قابل دسترس است. این سه مورد را از هر دو نود بررسی کن و برای پنهان‌کردن خطا چک‌ها را خاموش نکن.

Bash
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 محلی مهم‌اند. اسکریپت را با همان کاربر تعریف‌شده اجرا کن و گزارش‌های امنیتی را ببین.

Bash
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 گوش بدهد

ممکن است پردازش دیگری مالک پورت یا نشانی باشد. ابتدا مالک را پیدا کن؛ برای رفع تداخل، وب‌سرور تولیدی را کورکورانه متوقف نکن.

Bash
sudo ss -ltnp | grep -E ':80[[:space:]]' || true
sudo journalctl -u haproxy -n 80 --no-pager

دو نود را بدون راه‌اندازی مجدد کورکورانه نگهداری کن

مانیتورینگ را از دستگاه سوم انجام بده، نه فقط از داخل دو لودبالانسر. مالکیت VIP، پاسخ برنامه، سلامت بک‌اندها، وضعیت VRRP، از‌دست‌رفتن بسته و خطاهای قابل مشاهدهٔ کاربران را جداگانه دنبال کن. مدیریت نشست و دادهٔ مشترک برنامه مسئله‌ای مستقل است؛ این معماری اتصال‌های TCP برقرار را الزاماً حفظ نمی‌کند.

بعد از به‌روزرسانی بسته‌ها یا سیستم‌عامل، پیکربندی را اعتبارسنجی کن و هر بار فقط یک نود را تغییر بده. استثنای VRRP در فایروال و مجوز IP شناور شبکه باید در مدیریت تغییر ثبت شود. نسخهٔ سالم تنظیمات را نگه دار و آزمون Failover را برنامه‌ریزی‌شده انجام بده.

دستورهای این بخش فقط وضعیت نودها را می‌خوانند و اختلالی ایجاد نمی‌کنند؛ همچنان بررسی جداگانه از دستگاه بیرونی ضروری است.

Bash

روی هر دو نود · بررسی دوره‌ایِ فقط‌خواندنی

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 دیگری بوده‌اند، از این توقف عمومی استفاده نکن و به طرح تغییرات قبلی همان سرویس برگرد.

Bash

روی هر دو نود · در زمان نگهداری هماهنگ‌شده · با sudo

sudo systemctl disable --now keepalived
ip -br -4 address show dev ens18
از کجا بدانم درست انجام شد؟

VIP آزمایشی در هیچ‌کدام از دو نود دیده نمی‌شود؛ ورودی آزمایش عمداً قطع است ولی دادهٔ برنامه حذف نمی‌شود.

فایل قبلی HAProxy را برگردان و اسکریپت آزمایش را جمع کن

در هر نود فایل قبلی HAProxy را از پشتیبان محدودشده به root برگردان؛ قبل از راه‌اندازی مجدد، اعتبار آن را بررسی کن. اگر پیش از تمرین فایل Keepalived وجود داشت، محتوای قبلی را برگردان اما کلاستر قدیمی را بدون بازبینی تغییرات دوباره فعال نکن.

فقط وقتی مطمئن شدی سرویس دیگری به اسکریپت تمرین وابسته نیست، آن را پاک کن. قوانین UFW یا فایروال بیرونی که برای آزمایش افزوده‌ای باید طبق ثبت تغییرات به‌صورت جداگانه بازگردند. حذف بسته‌ها اجباری نیست و وابستگی سرویس‌های دیگر نباید پاک شود. دستورها دادهٔ بک‌اند یا پوشهٔ پشتیبان را حذف نمی‌کنند.

Bash

روی هر دو نود · با 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 شناور روی هر ابر کار کند یا بازیابی بین چند دیتاسنتر انجام شود. این نیازها طراحی و آزمون مستقل می‌خواهند.

پشتوانهٔ این آموزش

منابع رسمی

وضعیت بررسی هر محیط بالای صفحه مشخص است؛ بررسی مستندات به معنی اجرای عملی همهٔ نسخه‌ها نیست.

همهٔ آموزش‌های آکادمی ↗