لود بالانسر ابر آریانت جلوی دو وب سرور
لود بالانسر درخواستها را بین چند سرور پخش میکند. اگر یکی از سرورها از کار بیفتد، بررسی سلامت (health check) آن را تشخیص میدهد و ترافیک فقط به سرورهای سالم میرود؛ پس میتوانید سرورها را یکییکی بهروزرسانی کنید بدون اینکه سایت قطع شود، و با بیشتر شدن بار، فقط سرور اضافه کنید.
در این آموزش دو وب سرور Nginx با برچسب role=web روی یک شبکهی خصوصی میسازید، یک لود بالانسر جلوی آنها میگذارید و توزیع ترافیک و از کار افتادن یک سرور را آزمایش میکنید.
پیشنیازها
- CLI آریانت نصب و تنظیمشده با توکن دارای
cloud:servers:readوcloud:servers:write - یک کلید SSH در
~/.ssh/id_ed25519.pub - آشنایی با شبکهی خصوصی
لود بالانسرها در پنل هم در منوی ابر «شبکه ← لود بالانسرها» ساخته و مدیریت میشوند؛ این آموزش با CLI پیش میرود تا هر مرحله دقیق و تکرارپذیر باشد.
۱. انتخاب نوع لود بالانسر
arianet cloud datacenters
arianet cloud load-balancers types
arianet cloud pricing --datacenter ovh
هر نوع (مثلاً lb11) سقف تعداد سرویسها (listener)، هدفها و اتصالهای همزمان خودش را دارد و قیمتش در لیست قیمت آمده است. نوع را بعداً با change-type عوض کنید.
۲. شبکهی خصوصی
arianet cloud networks create --name web-net --datacenter ovh \
--ip-range 10.0.0.0/16 --subnet-ip-range 10.0.1.0/24 --wait
شناسهی شبکه را یادداشت کنید (در ادامه <network-id>).
۳. دو وب سرور
یک فایل cloud-init بسازید که Nginx نصب کند و نام سرور را در صفحهی اصلی بنویسد تا ببینید هر درخواست به کدام سرور رسیده است:
cat > web.yaml <<'EOF'
#cloud-config
packages:
- nginx
runcmd:
- echo "served by $(hostname)" > /var/www/html/index.html
EOF
دو سرور با برچسب role=web بسازید:
arianet cloud servers create --name web --count 2 --datacenter ovh --plan 3 --image ubuntu-24.04 \
--ssh-key "$(cat ~/.ssh/id_ed25519.pub)" --labels role=web \
--network <network-id> --user-data-file web.yaml --wait
--count 2 دو سرور با نامهای web و web-2 میسازد. شناسهی پلن را با arianet cloud plans --datacenter ovh انتخاب کنید.
۴. ساخت لود بالانسر
arianet cloud load-balancers create --name web-lb --datacenter ovh --type lb11 --wait
arianet cloud load-balancers attach-network <lb-id> --network <network-id>
الگوریتم پیشفرض round_robin است (درخواستها به نوبت). برای برنامههایی که درخواستهای طولانی دارند least_connections (سروری که کمترین اتصال باز را دارد) مناسبتر است:
arianet cloud load-balancers change-algorithm <lb-id> --algorithm least_connections
۵. سرویس HTTP با بررسی سلامت
arianet cloud load-balancers add-service <lb-id> \
--protocol http --listen-port 80 --destination-port 80 \
--health-protocol http --health-port 80 --health-path / \
--health-interval 10 --health-timeout 5 --health-retries 3
listen-port: پورتی که لود بالانسر روی آن درخواست میگیرد.destination-port: پورت برنامه روی سرورها.- بررسی سلامت هر
intervalثانیه مسیر/را روی هر سرور میخواند؛ سروری که پس ازretriesبار پاسخ درست ندهد، از چرخه خارج میشود تا دوباره سالم شود. بررسی سلامتtcpهم ممکن است (فقط باز بودن پورت). با--health-status-codeکدهای قابل قبول و با--health-domainهدر Host درخواست بررسی را تعیین کنید.
۶. افزودن هدفها با برچسب
arianet cloud load-balancers add-target <lb-id> --label-selector role=web --use-private-ip
هدف label selector همهی سرورهای دارای role=web را شامل میشود؛ سرور جدیدی که با همین برچسب بسازید خودکار به لود بالانسر اضافه میشود. --use-private-ip ترافیک را از شبکهی خصوصی به سرورها میرساند. هدف میتواند یک سرور مشخص (--server <id>) یا یک IP (--ip) هم باشد.
۷. بررسی
وضعیت سلامت هدفها:
arianet cloud load-balancers health <lb-id>
arianet cloud load-balancers get <lb-id> # shows the public ipv4 / ipv6
هر دو هدف باید healthy باشند. حالا چند درخواست بفرستید:
for i in 1 2 3 4; do curl -s http://LB_IP/; done
با round_robin پاسخها به نوبت نام میزبان یکی از دو سرور را نشان میدهند (مثلاً served by web و served by web-2).
آزمایش از کار افتادن یک سرور: روی web-2 با sudo systemctl stop nginx وب سرور را متوقف کنید. پس از چند بررسی سلامت، health آن را unhealthy نشان میدهد و همهی درخواستها به web میرسند. با sudo systemctl start nginx برگردانید.
۸. بستن دسترسی مستقیم به سرورها
حالا که ترافیک از شبکهی خصوصی میرسد، پورت ۸۰ سرورها لازم نیست از اینترنت باز باشد. یک فایروال ابر با برچسب role=web بسازید که فقط SSH را از IP شما بپذیرد، و روی هر سرور در ufw پورت ۸۰ را فقط از شبکهی خصوصی باز کنید:
sudo ufw allow OpenSSH
sudo ufw allow from 10.0.0.0/16 to any port 80 proto tcp
sudo ufw --force enable
پس از هر تغییر فایروال، دوباره health را بررسی کنید؛ اگر هدفها unhealthy شدند، فایروال ترافیک لود بالانسر را بسته است.
HTTPS
سرویس با پروتکل https در لود بالانسر آریانت عبور مستقیم TLS (TLS passthrough) است: لود بالانسر اتصال رمزشده را بدون باز کردن به سرورها میرساند و گواهی روی خود سرورها نصب میشود.
arianet cloud load-balancers add-service <lb-id> \
--protocol https --listen-port 443 --destination-port 443 \
--health-protocol tcp --health-port 443
sudo ufw allow from 10.0.0.0/16 to any port 443 proto tcp # on each server
- همهی سرورها باید گواهی معتبر همان دامنه را داشته باشند. چون درخواستهای Let's Encrypt ممکن است به هر یک از سرورها برسد، گواهی را با روش DNS-01 بگیرید یا روی یک سرور بگیرید و به بقیه کپی کنید (Nginx و Let's Encrypt).
- در API، سرویس
httpsگزینهیredirect_httpدارد که درخواستهای HTTP پورت ۸۰ را با کد 301 بهredirect_hostمیفرستد، و بررسی سلامت HTTP گزینهیtlsدارد (بررسی روی HTTPS، بدون اعتبارسنجی گواهی). جزئیات در مرجع تعاملی API ابر.
گزینههای دیگر سرویس
- Sticky sessions (
--sticky-sessions،--cookie-name): در سرویسhttpدرخواستهای هر کاربر به همان سرور قبلی میرود؛ برای برنامههایی که session را روی دیسک سرور نگه میدارند. - Proxy protocol (
--proxyprotocol): IP واقعی کاربر را با پروتکل PROXY به سرور میرساند. وب سرور هم باید آن را بپذیرد (در Nginx:listen 80 proxy_protocol;همراهset_real_ip_fromوreal_ip_header proxy_protocol;)؛ وگرنه همهی درخواستها خطا میگیرند. این گزینه را فقط وقتی روشن کنید که پیکربندی وب سرور را هم تغییر دادهاید. - لود بالانسر فقط خصوصی: با
--no-public-interfaceهنگام ساخت، لود بالانسر IP عمومی نمیگیرد؛ برای سرویسهای داخلی.
خطاهای رایج
| مشکل | راهحل |
|---|---|
همهی هدفها unhealthy هستند | مسیر و پورت بررسی سلامت را با curl -I http://10.0.1.x/ از سرور دیگری در شبکه آزمایش کنید؛ ufw یا فایروال ابر ممکن است ترافیک شبکهی خصوصی را ببندد. |
| بررسی سلامت HTTP شکست میخورد ولی سایت باز میشود | مسیر بررسی کد غیر ۲xx (مثلاً 301 یا 404) برمیگرداند. مسیر دیگری بدهید یا --health-status-code را تنظیم کنید. |
| هدف label selector سروری پیدا نمیکند | برچسب سرورها را با arianet cloud servers list --label-selector role=web بررسی کنید. با --use-private-ip سرورها باید به شبکهی لود بالانسر وصل باشند. |
خطای lb_locked (کد 423) | لود بالانسر درگیر عملیات قبلی است؛ چند ثانیه بعد دوباره امتحان کنید. |
گواهی نامعتبر در مرورگر با سرویس https | گواهی روی یکی از سرورها قدیمی یا متفاوت است؛ همهی سرورها باید گواهی یکسان و معتبر داشته باشند. |
همین معماری با Terraform
نمونهی کامل Terraform دقیقاً همین ساختار را دارد: شبکهی خصوصی، سه وب سرور با برچسب role=web، فایروال، لود بالانسر با سرویس HTTP و بررسی سلامت، و هدف label selector روی IP خصوصی. آموزش ساخت سرور با Terraform و CLI را هم ببینید.
قدم بعدی
لود بالانسر خود را بسازید
لود بالانسر ابر آریانت با بررسی سلامت، هدفهای برچسبی و شبکهی خصوصی، ساعتی حساب میشود. در پنل آریانت به «سرور ابری / Cloud Computing ← شبکه ← لود بالانسرها» بروید یا همین دستورها را با CLI اجرا کنید.