مدتها بود به این فکر میکردم که بهترین روش برای تست سرویسهای مختلف در هوملب چیه. هدف اصلی من از داشتن یک هوملب اینه که بتونم سرویسها رو سریع بالا بیارم، بررسی کنم و بدون معطلی نتیجه بگیرم. اما رسیدن به چنین زیرساختی همیشه ساده نیست.
تا قبل از نوشتن این مقاله، زیرساخت پیشفرض من — چه در هوملب و چه حتی در بعضی محیطهای پروداکشن — ترکیبی از K3s و Cilium بود. دلیلش هم کاملاً منطقیه: وقتی از Kubernetes استفاده میکنید، معمولاً نمیخواید تمام جزئیاتش رو یاد بگیرید؛ بیشتر دنبال یک زیرساخت پایدار و کمدردسر هستید که سرویسها و تستها رو روی اون اجرا کنید.
اما Kubernetes وانیلا یک مشکل بزرگ داره: هزینه و پیچیدگی نگهداری و آپدیت. خصوصاً وقتی فقط یک محیط سبک مثل هوملب دارید. از طرف دیگه استفاده از کلود هم برای هوملب منطقی نیست، و توی پروداکشن هم روند مهاجرت به سمت سلفهاستینگ هر روز بیشتر میشه. ابزارهایی مثل Kubespray هم با وجود مزایاشون، هنوز تجربهٔ آپدیت و نگهداری سادهٔ K3s رو ارائه نمیدن.
در این بین، K3s دقیقاً همون چیزی بود که لازم داشتم: آپدیتهای ساده، نگهداری راحت، مصرف منابع پایین.
از طرف دیگه، Cilium هم برتریهای خودش رو داشت. اینکه CNI بتونه نقش لودبالنسر رو هم بازی کنه واقعاً فیچر بزرگیه. پیکربندی Cilium علاوه بر اینکه آموزندهست، باعث میشه بهتر با eBPF و سازوکار شبکههای SDN آشنا بشید. و در نهایت هم نیاز به ابزارهای خارجی مثل میکروتیک یا لودبالنسرهای مستقل رو کم میکنه.
با گذشت زمان، برای یک تست ساده مجبور میشدم کلی وقت صرف نوشتن Value File برای یک Operator یا Chart کنم. در نهایت هم همیشه نمیدونستم دقیقاً چه چیزی روی سیستم در حال اجراست یا محدودیتهای اون Operator کجاست — تا لحظهای که با مشکل برخورد میکردم. نمونه ساده ای از مشکلاتی که میتونید در دولوپ این سیستم ها ببنید.
این تجربهها باعث شد به این فکر بیفتم که شاید اجرای مستقیم برخی سرویسها با systemd سریعتر، سادهتر و مناسبتر برای تست باشه. ولی از طرفی هم خیلی از سرویسهای جدید بدون کانتینر اصلاً طراحی نشدهان. این یعنی ما به یک راهحل ترکیبی نیاز داریم. یکی از نمونه های این موضوع هم میتونید توی اینجا پیدا کنید.
مشکل دیگه اینه که برای تست یک پارامتر ساده در یک دیتابیس باید هر بار سرویس رو از صفر نصب کنید. حتی استفاده از Ansible هم در محیط تست سرعت رو پایین میاره. پس اگر دنبال یک روش مناسب باشیم، زیرساختی لازم داریم که هم اجرای مستقیم سرویسها و هم اجرای کانتینری رو پشتیبانی کنه.
بعد از بررسی راههای مختلف، به این نتیجه رسیدم که Nomad بهترین گزینه ممکنه. دلیلش هم ساده است: Nomad تقریباً تمام درایورهای ممکن برای اجرای یک نرمافزار را پشتیبانی میکنه. یعنی هم میتونید کانتینر ران کنید، هم روی ماشین میزبان سرویس رو اجرا کنید، و هم از انواع روشهای ایزولیشن بهره ببرید.

وقتی به این قابلیتها نگاه کردم، به این نتیجه رسیدم که چقدر جذابه اگر بتونیم زیرساخت کانتینری سابق رو با Docker تست کنیم و در عین حال برای سرویسهایی که میخوایم مستقیم اجرا بشن از isolation در Nomad استفاده کنیم.
یکی از مثالهای واضح این موضوع اجرای یک Task با درایور exec هست. فرض کنید میخواید یک نسخه از MongoDB رو بدون داکر فایل و فقط با باینریش تست کنید. در Nomad میتونید باینری رو دانلود کنید و سرویس رو با پارامترهای دلخواه دقیقاً مثل systemd اجرا کنید، با این تفاوت که همچنان ایزولیشن دارید.

این یعنی برای تست سریع، نیازی به ساختن کانتینر نیست — و برای اجرا کردن سرویسهایی که مستقیم روی سیستم بهتر عمل میکنن هم محدودیتی ندارید.
ما نیاز داریم درخواستها بین سرویسها پخش بشن و بدونیم چه سرویسهایی بالا هستن و چطور باید بهشون دسترسی پیدا کنیم. اینجاست که Fabio وارد میشه.
Fabio با استفاده از یکپارچگی Nomad و Consul بهصورت خودکار میتونه سرویسها رو کشف، مسیرها رو تنظیم و ترافیک رو هدایت کنه. یعنی با هر تغییر در Jobها، Fabio هم مثل یک لودبالنسر داینامیک خودش رو آپدیت میکنه.
برای مثال، در جابی که سرویس MongoDB رو اجرا میکنه، میتونید مسیر /mongodb رو برای Fabio تعریف کنید و بعد هر زمان خواستید به سادگی تغییرش بدید یا حذفش کنید.
Fabio یک داشبورد ساده و کاربردی داره که وضعیت سرویسها، مسیرها و ترافیک رو نمایش میده. همین قابلیت باعث میشه مدیریت سرویسها در Nomad بسیار راحتتر بشه.

یکی از مزیتهای مهم Nomad اینه که دسترسی کاملی به لاگهای تمام اجرای قبلی سرویسها دارید. این یعنی برای تست، خطایابی و بررسی رفتار سرویسها، یک منبع متمرکز و قابلاعتماد دارید.

اگر علاقه دارید ساختار Ansible و زیرساخت Nomad من رو بررسی کنید، میتونید به این ریپو سر بزنید:
این مسیر برای من نتیجهی ماهها تست و تجربه بود. در نهایت، ترکیب Nomad + Consul + Fabio بهترین بالانس بین سرعت، سادگی، انعطافپذیری و قدرت رو برام فراهم کرد. حالا میتونم سرویسها رو هم به صورت کانتینری و هم به صورت مستقیم اجرا کنم و هر دو دنیا رو کنار هم داشته باشم.
ممنون از وقتی که گذاشتید 🙌