← All posts

الجميع قالوا اتجهوا إلى serverless. نحن أبقينا على عنقود Kubernetes الذي يظل خاملاً في معظم الوقت

Authagonal·July 5, 2026
authinfrastructurekubernetesaksserverlessazurecost

النصيحة منتشرة في كل مكان وتبدو صحيحة بشكل بديهي. أنت تشغّل المصادقة لمستأجرين حركة مرورهم متقطّعة. وتدفع مقابل عنقود Kubernetes على مدار الساعة. وستقوم Azure Container Apps بتحجيمك إلى الصفر ولن تحاسبك إلا على ما تستخدمه. توقّف عن الدفع مقابل الخمول.

أخذنا الأمر على محمل الجد. حسبنا تكلفة الترحيل إلى Azure Container Apps، ونظرنا بإمعان فيما سيجلبه لنا، ثم بقينا على AKS. وإليك المنطق وراء ذلك، لأنه ليس المنطق الذي قد تخمّنه من منحنى استغلال العنقود.

النصيحة صحيحة، لكن لعبء عمل لا نملكه

الحاويات serverless مناسبة تماماً لمعالجة الطلبات عديمة الحالة والمتفجّرة: كل طلب مستقل، والنُسخ مجرّد "ماشية"، وانعدام الحركة ينبغي أن يعني انعدام الفاتورة. هذا يصف كثيراً من الخلفيات الويبية.

لكنه لا يصف خلفية مصادقة. فخلفيتنا ليست خاملة بالطريقة التي يكون بها تطبيق عديم الحالة خاملاً. إنها تحمل قيادة العنقود وتشغّل طبقة التنسيق التي تقرّر أي نسخة تنفّذ العمل المفرد (singleton) مثل مسح الاحتفاظ ودورة الـ webhook. (نحن نَنتخب ذلك القائد الآن عبر عقد إيجار blob، لا عبر gossip بعد الآن، وتلك قصة قائمة بذاتها.) كون العنقود هادئاً لا يعني أنه لا عمل لديه؛ بل يعني أنه جاهز للتحقق من الرمز (token) التالي ولأن يبقى القائد. الهدوء والخمول ليسا الحالة ذاتها.

أزلنا فاتورة الخمول دون أن نرحل

وهنا الجزء الحاسم: التكلفة التي كنا نحاول الهروب منها كان لها إصلاح أرخص بكثير من إعادة بناء المنصة.

ما كان يستنزف المال هو عُقد تعمل على مدار الساعة طوال الأسبوع بينما تتركّز الحركة في ساعات العمل. لذا جعلنا عنقود التطوير يُلغي تخصيص موارده (deallocate) حين لا يستخدمه أحد (مُطفأ ليلاً وفي عطلات نهاية الأسبوع، ويعود عند الطلب)، وحوّلنا تجمّع العُقد إلى SKU أرخص. أزال ذلك معظم إنفاق الخمول الذي وعد serverless بإزالته، وكلّفنا تغييراً في الإعدادات لا ترحيلاً. حين يكون التوفير الذي تريده قابلاً للتحقيق في مكانك، فإن إعادة بناء المنصة لمطاردة الرقم نفسه مخاطرة كبيرة مقابل فرق سبق أن جنيته.

والدرس قابل للتعميم: سعّر الإصلاح قبل أن تسعّر إعادة بناء المنصة. "توقّف عن الدفع مقابل الخمول" هدف، لا بنية، وأرخص طريقة لبلوغه غالباً ما تكون مجدوِلاً و SKU، لا منفّذ تشغيل جديداً.

التحجيم إلى الصفر يصارع خلفية يجب أن تحتفظ بعقد إيجار

حتى لو نحّينا التكلفة جانباً، فإن التحجيم إلى الصفر خاطئ فعلياً لعبء العمل هذا من ناحيتين.

أولاً، البدايات الباردة (cold starts) تقع على أسوأ مسار ممكن. فالطلب الذي يدفع ضريبة البداية الباردة هو لشخص يحاول تسجيل الدخول، و"كان تسجيل دخولك بطيئاً لأن خدمة المصادقة لدينا كانت نائمة" ليست جملة تريد إطلاقها.

ثانياً، القيادة والتحجيم إلى الصفر في تعارض مباشر. لا يمكنك أن تحتفظ بعقد إيجار من نسخة جرى تحجيمها حتى التلاشي. فخلفية مهمتها كلها أن يكون لديها دائماً قائد حيّ واحد بالضبط لا تريد منفّذ تشغيل مهمته كلها إزالة النُسخ حين تبدو هادئة. سنكون نصارع السلوك الجوهري للمنصة كي نحافظ على سلوكنا.

منفّذ التشغيل كان سيسلبنا ثلاثة أشياء نستخدمها

الترحيل ليس مجانياً حتى حيث ينجح؛ فأنت ترث صندوق الرمل (sandbox) الخاص بمنفّذ التشغيل المُدار، وصندوقنا يحجب أشياء نعتمد عليها:

  • Twingate. نصل إلى الموارد الخاصة عبر موصّل Twingate. صندوق رمل الحاويات المُدار لن يشغّله، فسنُضطر إلى إعادة اختراع وصول شبكي خاص نملكه أصلاً.
  • مسار البناء لدينا. أجزاء من خط أنابيبنا تعتمد على Docker-in-Docker و az acr build مقابل سجلّ خاص، وكلاهما يمنعه صندوق الرمل. هذا نظام بناء كامل يجب إعادة تشييده، لا مجرد هدف نشر يجب تغييره.
  • التحكم عبر السُحب. نشغّل نسخة احتياطية على AWS تتحقق من الرموز التي أصدرها الأساسي على Azure، عبر JWKS اتحادية، مع Cloudflare كحَكَم لتجاوز الفشل. وهذا يتطلب تحكماً في الشبكة والتوضّع يُخفيه منفّذ التشغيل المُدار عمداً.

كل واحد من هذه حلٌّ التفافي سنُضطر إلى كتابته فقط لنعود إلى حيث نقف بالفعل. التكلفة الحقيقية للترحيل ليست عملية التحويل؛ بل إعادة كسب كل قدرة يسلبها صندوق الرمل.

توفير التكلفة له ذيل، وقد دفعناه

البقاء أيضاً ليس بلا عواقب، والأمانة تقتضي قول ذلك. إلغاء تخصيص العُقد ليلاً منحنا عطلاً ما كنا لنراه أبداً على عنقود يعمل دوماً: تسابق على الرمز عند أول سحب للصورة على العُقد الباردة (ذاك الخاص بمشكلة AKS رقم 4052) كان يعرقل أحياناً قيام pod بعد إعادة تشغيل العنقود. أصلحناه بمهلة طرح (rollout) أطول، وفي الإنتاج بألا نُلغي التخصيص بالطريقة التي يفعلها التطوير.

هذا هو الشكل الحقيقي للمقايضة. كل مسار له ذيل من أنماط الفشل؛ والسؤال هو هل يمكنك رؤيتها وإصلاحها. على AKS كان تسابق العُقد الباردة قابلاً للفحص والإصلاح. أما أصناف الغرابة التي ترثها من أحشاء منفّذ تشغيل مُدار فهي من النوع الذي تفتح بشأنه تذكرة دعم وتنتظر.

القاعدة التي خرجنا بها

شيئان، قابلان لإعادة الاستخدام أبعد منا. لا ترحل لتهرب من تكلفة يمكنك قتلها في مكانك؛ سعّر الإصلاح في المكان أولاً، لأن مجدوِلاً و SKU أرخص يتغلّبان على إعادة بناء المنصة في معظم الأحيان. ووفّق بين منفّذ التشغيل وشكل عبء العمل: serverless يكافئ ما هو عديم الحالة ومتفجّر ويعاقب ما هو ذو حالة ودائم العمل، وجوهر مصادقة يحمل مفاتيح توقيعك وقيادة عنقودك ينتمي بحزم إلى النوع الثاني.

نحن لسنا ضد serverless. كثير من سطحنا عديم الحالة سيكون بخير عليه. لكن الجزء الذي يحمل مفاتيحك ويقرّر من يشغّل المهام المدمّرة سيظل يعمل على بنية تحتية مملّة، دائمة العمل، قابلة للفحص. أحياناً يكون العنقود الذي يبدو خاملاً هو الخيار الرخيص، بمجرد أن تحسب كل ما ستضطر إلى إعادة بنائه كي تتركه.

البنية التحتية الدائمة العمل والقابلة للفحص أسفل عمليات تسجيل الدخول لديك ميزة وليست إغفالاً. وهي بالضبط ما تسلّمه حين تُشغّل المصادقة على Authagonal بدلاً من تشغيل الـ backplane بنفسك.