به گزارش از وبسایت cncf
هر استقرار چندمنطقهای دیر یا زود با همان مشکل ناخوشایند مواجه میشود: یک خوشه بهطور کامل از دست میرود و نسخهٔ دیگری از سرویس که در دو منطقه اجرا شده ممکن است عملاً در دسترس نباشد. Failover اغلب به یک Runbook تبدیل میشود: DNS را بازگردانی کنید، routing را بازتنظیم کنید و منتظر قطعی بمانید — اتفاقی که قبلاً برای تحمل خطا هزینهاش را پرداخت کردهاید. 🔁
افزونهٔ multicluster در Linkerd این شکاف را با اجازه دادن به چند خوشه برای ارائهٔ یک سرویس بهعنوان یک endpoint واحد و load-balanced پر میکند. نکتهٔ مهم این است که یک پلتفرم واقعی معمولاً فقط یک حالت چندخوشهای انتخاب نمیکند: برخی سرویسها فدرال میخواهند (همان سرویس در همهجا با یک endpoint و خطای خودکار)، در حالی که دیگر سرویسها نیاز به mirror شدن یا دسترسی به سرویسهای راهدور خاص دارند. اغلب لازم است هر دو الگو در یک مجموعهٔ خوشهها با هم زندگی کنند.
این مطلب سه الگو را در سه خوشهٔ GKE نشان میدهد: یک توپولوژی full-mesh بین لینکها، یک آزمایش chaos که کل یک خوشه را حذف میکند، و اسکریپتهایی که میتوانید در یک پروژهٔ جدید GCP اجرا کنید. مخزن همراه تمام اسکریپتهای اشارهشده را در اختیار دارد؛ آن را شبیهسازی کنید، شناسهٔ پروژهٔ خود را تنظیم کنید و اجرا کنید. ☁️
حالتهای multicluster در Linkerd: Gateway، Flat، و Federated
افزونهٔ multicluster در Linkerd از سه حالت پشتیبانی میکند و خوشبختانه این حالتها الزاماً متقابلاً انحصاری نیستند: حالت برای هر سرویس از طریق یک label انتخاب میشود.
ModeLabel — چه اتفاقی میافتد — شبکهٔ نیازمندی
mirror.linkerd.io/exported=true — سرویس بهصورت منعکسشده عرضه میشود؛ ترافیک از طریق یک gateway IP دسترسی پیدا میکند (IPهای قابل مسیریابی) — (دروازه)
Federated — mirror.linkerd.io/federated=member — همهٔ سرویسهای همنام بهصورت فدرال متحد شده و بار در تمام خوشهها متعادل میشود — (فدرال)
Flat — (آیپیهای pod قابل مسیریابی) — فقط IP دروازه باید قابل دسترسی باشد، در حالی که حالات Flat و Federated به اتصال واقعی pod-to-pod نیاز دارند.
در GCP، خوشههای GKE روی VPCهای همتا میتوانند بهطور طبیعی آن شبکهٔ مسطح را فراهم کنند. بنابراین معمولاً میتوانید سرویسهای فدرال را برای بارهای اصلی روی شبکهٔ مسطح اجرا کنید و همزمان یک سرویس تخصصی را از طریق یک gateway از خوشهای که در آن شبکه نیست، mirror کنید. بیشتر تیمهای پلتفرم به این ترکیب میرسند.
معماری چندمنطقهای — ثبت سه خوشهٔ GKE
در پیادهسازی نمونه، ما سه خوشهٔ GKE در سه منطقه داریم که کاملاً به هم متصلاند (در مجموع شش لینک جهتدار). سه سرویس دمو هر کدام از یک حالت multicluster متفاوت استفاده میکنند:
frontend: حالت Federated و در هر سه خوشه اجرا میشود. یک سرویس frontend محلی در هر خوشه بار را روی همهٔ کپیها (3 کپی × 3 خوشه) متعادل میکند؛ وقتی یک خوشه از دسترس خارج میشود، شش پاد باقیمانده ترافیک را بهطور شفاف سرویسدهی میکنند.
api: حالت mirror/Flat است و در «west» و «east» اجرا میشود. خوشهٔ «north» آن را بهعنوان api-west و api-east مصرف میکند — نامهای صریح سرویس راهدور — و ترافیک مستقیماً به پادهای راهدور ارسال میشود. این سبک مناسب مواقعی است که میخواهید تصمیم بگیرید کدام backend را برای حفظ locality یا داده انتخاب کنید.
analytics: حالت mirror و فقط در «east» اجرا میشود. از طریق gateway صادر میشود تا «west» و «north» بتوانند بهعنوان analytics-east-gw به آن دسترسی داشته باشند بدون نیاز به شبکهٔ مسطح مستقیم. این نمونه نشان میدهد که حالت Gateway میتواند در کنار حالات Flat و Federated روی همان لینکها همزیستی کند.
پیشنیازهای استقرار: حساب GCP و ابزارها
برای اجرای این دمو نیاز دارید به: یک حساب GCP (اعتبارات رایگان کفایت میکند)، gcloud CLI با auth، kubectl نسخه 1.28+، و ابزارهای مرتبط با GKE و Linkerd. اسکریپت نصب (گام 3) حدود چند دقیقه زمان میبرد و APIهای Compute و Container را فعال خواهد کرد تا یک پروژهٔ جدید از جعبه خارج از کار باشد.
مرحلهٔ 0: مخزن را شبیهسازی کنید و فایل .env را پیکربندی کنید
مخزن را clone کنید، یک فایل .env محلی از نمونه ایجاد کنید و شناسهٔ پروژهٔ خود را در آن تنظیم کنید. مقادیر پیشفرض برای بقیه نسخههای نمایشی مناسب هستند. مثال دستورات:
git clone https://github.com/your-repo/blog-linkerd-federation.git cd blog-linkerd-federation cp env.example .env
فایل .env را باز کنید و حداقل متغیر GCP_PROJECT را مقداردهی کنید. مثال برخی متغیرهای پیشفرض در فایل:
export GCP_PROJECT="شماره-پروژه-شما" export REGION_WEST="us-central1" export REGION_EAST="us-east1" export REGION_NORTH="europe-west1" export ZONE_WEST="us-central1-a" export ZONE_EAST="us-east1-b" export ZONE_NORTH="europe-west1-b" export CLUSTER_MACHINE_TYPE="e2-medium" export CLUSTER_NODE_COUNT="1" export FRONTEND_REPLICAS="3"
برای در دسترس قرار گرفتن متغیرها در اسکریپتها، آنها را در پوستهٔ فعلی بارگذاری کنید:
source .env
توجه داشته باشید که هر اسکریپت با
set -euo pipefail
اجرا میشود تا در صورت نبود متغیرها با خطا متوقف شود.
مرحلهٔ 1: ایجاد سه خوشهٔ GKE با VPC peering
اسکریپت زیر شبکهها و خوشهها را ایجاد میکند؛ این عملیات معمولاً 10–15 دقیقه طول میکشد (زمان خوبی برای نوشیدن یک قهوه ☕️):
./scripts/01-infra.sh
این اسکریپت کارهای زیر را انجام میدهد: فعالسازی APIهای Compute و Container، ساخت سه VPC با CIDRهای pod و service غیرهمپوشان جهت پشتیبانی از VPC peering، پیکربندی peering و ایجاد سه خوشهٔ GKE (هر کدام در یک منطقهٔ مشخص). آدرسدهی pod/service بهصورت غیرهمپوشان تعریف شده تا routing از طریق peering درست کار کند.
اگر CIDRهای pod روی VPCهای همتا همپوشانی داشته باشند، مسیریابی بهصورت خاموش و غیرقابل پیشبینی خواهد شد — پادها ممکن است پاسخ از خوشهٔ اشتباه دریافت کنند یا اتصالها بدون خطای مفید تمام شوند.
نکته دربارهٔ شمار نُودها: گزینهٔ
--num-nodes
در یک regional cluster بهصورت پیشفرض نُودها را در چند zone پراکنده میکند. این اسکریپت از
--node-locations
استفاده میکند تا هر خوشه را به یک zone pin کند، از این رو مقدار CLUSTER_NODE_COUNT=1 واقعاً به معنای یک نُود در هر خوشه است.
هزینهٔ تقریبی: سه خوشهٔ استاندارد با یک نُود e2-medium هر کدام حدود 10–15 دلار در روز برای این دمو هزینه دارند (مدیریت + نُودها + یک small load balancer در east). اسکریپت cleanup همهٔ منابع را حذف میکند.
مرحلهٔ 2: نصب Linkerd با یک trust anchor مشترک
Linkerd را در هر سه خوشه با یک trust anchor مشترک نصب کنید تا mTLS بین خوشهای فراهم شود. اسکریپت نصب گواهیها، نصب control plane و پیکربندی خوشهها برای اعتماد متقابل را انجام میدهد:
./scripts/02-linkerd-install.sh
این فرآیند یک root CA و گواهیهای issuer برای هر خوشه ایجاد میکند سپس Linkerd را نصب میکند. ساختار گواهیها بهصورت نمونه:
root.crt (shared trust anchor) ├── issuer-west.crt + issuer-west.key ├── issuer-east.crt + issuer-east.key └── issuer-north.crt + issuer-north.key
داشتن issuer مجزا برای هر خوشه یک الگوی عملیاتی خوب است: اگر issuer یک خوشه به مخاطره بیفتد، میتوانید همان issuer را جداگانه بازچرخش کنید بدون تأثیر بر بقیه. root مشترک همان چیزی است که به mTLS بین خوشهها اجازه میدهد تا کار کند.
برای کاهش مصرف منابع و هزینه، کنترلپلین بدون add-onهای Viz نصب میشود.
مرحلهٔ 3: راهاندازی multicluster و ایجاد full-mesh
مؤلفههای multicluster را پیکربندی کنید و یک توپولوژی full-mesh بین خوشهها بسازید. پس از این مرحله، هر خوشه قادر خواهد بود سرویسهای سایر خوشهها را مصرف کند.
./scripts/03-multicluster-setup.sh
در این مرحله شش لینک جهتدار ایجاد میشود (هر خوشه به هر خوشهٔ دیگر لینک دارد). نکتهٔ دروازه این است که تنها خوشهٔ east نیاز به gateway دارد (زیرا analytics از آن صادر میشود)، بنابراین gateway تنها در east فعال میشود و خوشههای دیگر بدون gateway نگه داشته میشوند.
مثال دستورات نصب multicluster (نمونه):
# west: بدون gateway linkerd --context west multicluster install --gateway=false --set controllers[0].link.ref.name=north --set controllers[1].link.ref.name=east-gw | kubectl --context west apply -f - # east: با gateway فعال linkerd --context east multicluster install --gateway=true --set controllers[0].link.ref.name=west --set controllers[1].link.ref.name=north | kubectl --context east apply -f - # north: بدون gateway linkerd --context north multicluster install --gateway=false --set controllers[0].link.ref.name=west --set controllers[1].link.ref.name=east | kubectl --context north apply -f -
پس از این تنظیمات، هر خوشه سرویسهای federated و mirrored را میتواند مصرف کند و توپولوژی full-mesh برقرار خواهد بود.
جمعبندی
این پست نشان میدهد چگونه میتوانید با Linkerd و GKE یک معماری چندمنطقهای مقاوم بسازید که ترکیبی از حالات federated، flat و gateway را با هم پشتیبانی کند — طوری که هر سرویس بر اساس نیازش انتخاب شود. همهٔ اسکریپتها در مخزن همراه موجود است؛ آنها را اجرا کنید، آزمایش Chaos را امتحان کنید و ببینید چگونه سیستم بدون دستزدن دستی به routing یا DNS ترافیک را تحمل میکند. 🔐