نبذة عن الشركة ومنتجاتها في الصحة الرقمية

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

يعمل المنتجان على عنقود Kubernetes واحد لدى ستون، لكن لكل منتج Namespace خاص به وخدمات بيانات مستقلة. يتيح هذا الفصل إدارة عمليات النشر وتخصيص الموارد والتغييرات الخاصة بكل منتج من دون التأثير غير الضروري في المنتج الآخر.

بدأت العلاقة بتعاون Dropp مع الشركة في تطوير تطبيقات الهاتف المحمول. وبعد نجاح ذلك التعاون، وسّع العميل نطاق الشراكة ليشمل DevOps وعمليات البنية التحتية. لذلك بدأ مشروع الترحيل في ظل معرفة مسبقة وثقة قائمة بين الفريقين.

التحدي: بنية تحتية بلا ملكية تشغيلية واضحة

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

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

لم تقتصر المخاطر التجارية على التوقف. كان من الممكن أن يؤدي تجاوز الموعد النهائي، والعمل برؤية محدودة لحالة العنقود، والاعتماد على تدخلات متفرقة إلى تشتيت فريق المنتج عن تطوير منتجات الشركة في مجال الصحة الرقمية وإعادته إلى العمل التفاعلي لإخماد مشكلات البنية التحتية.

وضع البنية التحتية قبل المشروع

كان المنتجان يعملان على الجيل الأول من خدمة Kubernetes لدى ستون. شملت المنظومة خدمات Backend مبنية على Node.js، وواجهة Frontend مبنية على Next.js، وقواعد بيانات MongoDB وPostgreSQL، إلى جانب Redis وRabbitMQ وNginx وObject Storage. اشترك المنتجان في العنقود نفسه، لكنهما عملا ضمن Namespaces منفصلة وخدمات بيانات مستقلة.

اعتمدت عملية CI/CD على GitLab CI وHelm. بعد انتهاء Build، كان GitLab CI ينفّذ الأمر `helm upgrade` مباشرة على العنقود. كانت العملية تعمل، لكنها لم تفصل بوضوح بين CI والنشر إلى Production، كما لم تكن الحالة المرغوبة لعمليات النشر تُدار بصورة متكاملة من خلال Git.

كانت النسخ الاحتياطية تعمل بالفعل، كما كانت صلاحيات الوصول مُدارة. في المقابل، لم تكن المراقبة توفر رؤية كافية عبر العنقود والـNodes والـPods والخدمات، وكانت الوثائق التشغيلية بحاجة إلى استكمال. لم يبدأ المشروع من منصة متوقفة، بل من الحاجة إلى كشف المخاطر غير الظاهرة وجعل العمليات قابلة للمراقبة والتكرار والدعم.

قيود المشروع والموعد النهائي

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

تزامن تنفيذ المشروع أيضًا مع ظروف الحرب والقيود الواسعة على الوصول إلى الإنترنت في إيران. كان عدم استقرار الوصول إلى Registries ومستودعات الحزم الخارجية قادرًا على تعطيل Build وDeployment. لم تكن هذه مشكلة جانبية؛ بل أثّرت مباشرة في استراتيجية إدارة Dependencies وDocker Images.

كان المنتجان يعملان بالفعل، وكان نقلهما معًا سيزيد نطاق تأثير أي مشكلة محتملة. لذلك كان لا بد أن تكون خطة الترحيل مرحلية، قابلة للاختبار، ومدعومة بمسار Rollback واضح.

التقييم الأولي: ما الذي كان يجب تغييره؟

قبل بدء الترحيل، قيّمت Dropp Tempo حالة العنقود، وآلية النشر، والاعتماد على المصادر الخارجية، والمراقبة، والنسخ الاحتياطي، وإدارة الوصول، واستهلاك الموارد. لم يكن الهدف إعادة تصميم كل شيء، بل تحديد ما يعمل بالفعل، والمخاطر التي يجب معالجتها قبل Cutover، والتحسينات التي يمكن تنفيذها بالتوازي مع الترحيل.

أكد التقييم أن النسخ الاحتياطية موجودة ويمكن الحفاظ عليها والتحقق منها، وأن صلاحيات الوصول كانت مُدارة. أما أبرز الفجوات فتمثلت في محدودية الرؤية التشغيلية، وعدم اكتمال الوثائق، وتطبيق CD مباشرة من GitLab CI على العنقود، والتأثر المحتمل بانقطاع الوصول إلى مصادر Dependencies وImages الخارجية.

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

القرارات الهندسية: لماذا كان الترحيل مرحليًا؟

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

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

شكّل قراران إضافيان ملامح المنصة الجديدة: نقل CD إلى نموذج GitOps مبني على ArgoCD، وإنشاء Nexus مخصص لتقليل اعتماد Build وDeployment على Registries ومستودعات الحزم الخارجية. كان الهدف إزالة الاحتكاكات التشغيلية بعد الانتقال، لا مجرد نقل الأحمال.

تنفيذ الترحيل: من Staging إلى المزامنة المستمرة

جهّز الفريق أولًا المكونات المطلوبة على الجيل الثاني من Kubernetes لدى ستون، وأعاد بناء هيكل Namespaces وIngress وStorage وDeployments لكل منتج في بيئة الوجهة. ثم نُشرت نسخة Staging من كل منتج داخل Namespace مستقل، ليتمكن فريق العميل من اختبار سلوك التطبيق وتكاملاته قبل نقل حركة Production.

نُقل منتج صحة المرأة أولًا. وإلى جانب نقل منتج فعلي، اختبرت هذه المرحلة تسلسل الترحيل وإعدادات العنقود الجديد وآلية التنسيق بين الفريقين. بعد اعتمادها، استمر العمل على المنصة الرئيسية مع تركيز خاص على قاعدة بياناتها الرئيسية.

قامت Debezium وKafka Connect بمزامنة البيانات الموجودة والتقاط التغييرات التي كانت تُنشأ في المصدر أثناء استمرار النقل. وعندما أصبح المصدر والوجهة في حالة تقارب كافية، حُددت نافذة Cutover النهائية. أجرى فريق العميل Functional Testing. لم يُنفّذ اختبار حمل باستخدام k6 في هذا المشروع، ولا تُنسب إليه أي نتيجة من هذا النوع.

Before / After Architecture
Before
  • عنقود Kubernetes الجيل الأول من ستون
  • GitLab CI بتنفيذ helm upgrade مباشرة
  • Dependencies وImages تعتمد على مصادر خارجية
  • مراقبة محدودة
  • غياب ملكية تشغيلية موحدة
After
  • عنقود Kubernetes الجيل الثاني من ستون
  • Namespace مستقل لكل منتج
  • GitLab CI للبناء (Build)
  • Nexus للـ Images والـ Dependencies
  • ArgoCD لـ GitOps CD
  • Vault لإدارة الـ Secrets
  • Prometheus وGrafana للمراقبة
  • Uptime Kuma لفحص الـ Endpoints الخارجية
  • نسخ احتياطي يومي إلى Object Storage
  • Managed DevOps بواسطة Dropp Tempo

Cutover خلال أربع ساعات مع مسار Rollback محدد

نُفّذ Cutover النهائي للمنصة الرئيسية ضمن نافذة صيانة مخططة مسبقًا. أُبلغ المستخدمون قبل الموعد، ووُضعت المنصة الرئيسية في وضع Read-only أثناء الانتقال. كان منتج صحة المرأة قد انتقل بالفعل ولم تكن جزءًا من هذا Cutover.

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

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

Migration Flow
01

ترحيل لونا

بداية الترحيل التدريجي بالمنتج الأول.

02

إعداد Staging

نشر نسخة Staging في Namespace مستقل.

03

اختبار وظيفي

اختبار وظيفي لنسخة Staging قبل أي Cutover.

04

بدء المزامنة باستخدام Debezium وKafka Connect

مزامنة البيانات الأولية والتغييرات أثناء النقل بين العنقودين.

05

نافذة Read-only

وضع الخدمة في وضع القراءة فقط قبل الـ Cutover النهائي.

06

الترحيل النهائي (Cutover)

التحويل النهائي إلى العنقود الجديد خلال نافذة أربع ساعات.

07

التحقق (Validation)

التحقق من سلامة البيانات وصحة الخدمة بعد الـ Cutover.

08

الاحتفاظ بالعنقود القديم لمدة أسبوع

إبقاء العنقود القديم دون تغيير لإتاحة إمكانية الـ Rollback.

09

نهاية نافذة الـ Rollback

إنهاء الترحيل بعد أسبوع دون الحاجة للعودة.

من Helm المباشر إلى GitOps باستخدام ArgoCD

في البنية السابقة، كان GitLab CI يتولى Build وتنفيذ `helm upgrade` مباشرة على العنقود. فصلت Dropp Tempo بين هاتين المسؤوليتين. ظل GitLab CI مسؤولًا عن Build وتجهيز Artifacts وImages، بينما أصبح ArgoCD مسؤولًا عن تطبيق الحالة المرغوبة على Kubernetes.

مع تطبيق GitOps، تُحفظ الحالة المتوقعة لكل خدمة في Git، ويقوم ArgoCD بمطابقة العنقود معها. جعل ذلك عمليات النشر أكثر وضوحًا وقابلية للتتبع، وقلّل الحاجة إلى تطبيق تغييرات Production مباشرة من داخل CI Pipeline.

لم تكن النتيجة مجرد إضافة أداة أخرى. حصل فريق العمليات على رؤية أوضح لحالة المزامنة، والفارق بين Desired State والحالة الفعلية للعنقود، وسجل التغييرات؛ وهي قدرات مهمة عند تشغيل عدة منتجات على منصة Production مشتركة.

Nexus وتقليل الاعتماد على المصادر الخارجية

يمكن لمشكلات الوصول إلى Registries ومستودعات الحزم الخارجية أن توقف Build أو Deployment حتى عندما يكون عنقود Kubernetes نفسه سليمًا. أصبح هذا الخطر أكثر وضوحًا خلال المشروع مع اشتداد قيود الإنترنت.

أنشأت Dropp Tempo مستودع Nexus مخصصًا للمنصة الرئيسية لاستضافة Dependencies وDocker Images المطلوبة وتخزينها مؤقتًا. في البنية الجديدة، تحصل عمليات Build وDeployment على مواردها من Nexus التابع للمنصة الرئيسية كلما كان ذلك ممكنًا.

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

مراقبة وتنبيهات متعددة الطبقات

كانت الحاجة إلى رؤية تشغيلية أشمل من أهم نتائج التقييم الأولي. استُخدم Prometheus وGrafana لجمع Metrics وإظهار صحة البنية التحتية، وامتدت المراقبة من مستوى Nodes وPods إلى الخدمات وقواعد البيانات وEndpoints.

تُفحص الـEndpoints العامة أيضًا عبر نظام المراقبة المستقل لدى Dropp Tempo وUptime Kuma. تقيس هذه الطبقة الخارجية توافر الخدمة من خارج العنقود المُدار، حتى لا يعتمد اكتشاف المشكلات حصريًا على أدوات تعمل داخل البيئة نفسها.

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

Uptime Kuma

إدارة الأسرار وتعزيز أمان الخوادم

أُضيف HashiCorp Vault إلى البيئة الجديدة لتوحيد إدارة Secrets وتقليل الاعتماد على الإعدادات المتفرقة أو المعالجة اليدوية. لا تُنشر تفاصيل السياسات والصلاحيات لأسباب أمنية، لكن الهدف كان إنشاء نقطة تحكم واضحة لدورة حياة القيم الحساسة.

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

نسخ احتياطي يومي واختبار استعادة فعلي

كانت لدى المنصة الرئيسية عمليات نسخ احتياطي قائمة قبل بدء المشروع، وأكد التقييم الأولي وجودها وسلامتها. في البنية النهائية، تُنشأ النسخ الاحتياطية يوميًا وتُنقل إلى Object Storage.

لم تكتفِ Dropp Tempo بنجاح Job أو بوجود ملفات النسخ الاحتياطي. نفّذ الفريق Restore Test فعليًا للتحقق من إمكانية استعادة النسخ المتاحة عند الحاجة. أثبت ذلك الفرق بين الاحتفاظ ببيانات احتياطية وامتلاك مسار استعادة يمكن الاعتماد عليه.

تظل عملية النسخ الاحتياطي ومراقبتها جزءًا من خدمة البنية التحتية المستمرة إلى جانب Observability وIncident Response.

خفض Worker Nodes بنسبة 20٪ عبر تحسين الموارد

بعد توفير رؤية أدق لاستهلاك الموارد، جرى تقييم Resource Requests وLimits الخاصة بالـDeployments وفق الاستخدام الفعلي. لم يكن الهدف حذف خوادم فحسب، بل فهم السعة التي تحتاجها كل خدمة وتحديد المواضع التي يمكن خفض الموارد فيها من دون إضافة مخاطر تشغيلية غير ضرورية.

نتيجة لذلك، انخفض عدد Worker Nodes في عنقود Kubernetes من 15 إلى 12، أي بنسبة 20٪. كما أدى الحجم الأصغر للبنية التحتية إلى خفض تكلفتها التشغيلية المستمرة.

تكمن أهمية هذه النتيجة في طريقة تحقيقها: المراقبة والضبط بدلًا من التخمين أو خفض السعة بصورة عشوائية. وتوفر منظومة Monitoring الجديدة أساسًا لمواصلة تحسين الموارد خلال خدمة الدعم المستمرة.

النتائج التقنية والأثر التجاري

اكتمل ترحيل المنصة خلال نحو ثلاثة أشهر. نُفّذ Cutover النهائي للمنصة الرئيسية خلال نافذة Read-only استمرت أربع ساعات ومن دون فقدان البيانات، بينما ظل العنقود السابق متاحًا لمدة أسبوع كخيار Rollback. ساعد نقل المنتجين في مرحلتين منفصلتين على إبقاء نطاق كل خطوة ومخاطرها تحت السيطرة.

تقنيًا، استُبدل CD المباشر من GitLab CI بنموذج GitOps قائم على ArgoCD، وخفّض Nexus اعتماد Build وDeployment على المصادر الخارجية، ووفّر Vault إدارة مركزية للأسرار، وامتدت المراقبة من Nodes وPods إلى قواعد البيانات وEndpoints، كما جرى التحقق من النسخ الاحتياطية اليومية عبر Restore Test فعلي.

أدى ضبط الموارد إلى خفض Worker Nodes من 15 إلى 12. وعلى مستوى الأعمال، انتقلت المنصة الرئيسية من فجوة في الملكية التشغيلية إلى نموذج يتولى فيه فريق واضح المسؤولية عن المراقبة والاستجابة للحوادث والنشر والنسخ الاحتياطي والتحسين المستمر. لم تكن النتيجة الأهم إنهاء الترحيل فقط، بل تمكين فريق المنتج من مواصلة التركيز على منتجات الشركة في مجال الصحة الرقمية بدل العودة إلى عمليات البنية التحتية التفاعلية.

من مشروع ترحيل إلى Managed DevOps مستمر

لم ينتهِ تعاون Dropp Tempo مع العميل عند Cutover. بعد اكتمال الترحيل، استمرت إدارة Kubernetes، ومتابعة Monitoring والتنبيهات، وIncident Response، وعمليات Deployment، والنسخ الاحتياطي، ومعالجة مشكلات البنية التحتية، وتحسين الموارد ضمن خدمة Managed DevOps.

هذه هي مرحلة Retain في نموذج Dropp Tempo عمليًا: لا تُسلّم المنصة لتعود بلا مالك تشغيلي. يواصل الفريق الذي يعرف سياق الترحيل وأسباب القرارات المعمارية تولّي العمليات اليومية والتحسين التدريجي.

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