في True Engineering ، قمنا بإعداد عملية تسليم التحديث المستمر إلى خوادم العميل ونريد مشاركة هذه التجربة.
أولاً ، قمنا بتطوير نظام عبر الإنترنت للعميل ونشرناه في مجموعة Kubernetes الخاصة بنا. الآن انتقل حلنا المحمّل بدرجة كبيرة إلى نظام العميل ، والذي أنشأنا من أجله عملية النشر المستمر التلقائية بالكامل. بفضل هذا ، قمنا بتسريع وقت الوصول إلى السوق - تسليم التغييرات إلى بيئة المنتج.
في هذه المقالة ، سنتحدث عن جميع مراحل عملية النشر المستمر (CD) أو تقديم تحديثات لمنصة العميل:
- كيف تبدأ هذه العملية
- تزامن مع مستودع بوابة العميل ،
- الجمعية الخلفية والواجهة الأمامية
- النشر التلقائي للتطبيق في بيئة اختبار ،
- النشر التلقائي على Prod.
في هذه العملية سوف نشارك تفاصيل الإعدادات.

1. بدء CD
يبدأ التوزيع المستمر بحقيقة قيام المطور بنشر التغييرات في فرع الإصدار الخاص بمستودع Git الخاص بنا.
يعمل تطبيقنا على أساس بنية microservice ويتم تخزين جميع مكوناته في مستودع واحد. بفضل هذا ، يتم تجميع وتثبيت جميع الخدمات المصغرة ، حتى لو تغير أحدها.
قمنا بتنظيم العمل من خلال مستودع واحد لعدة أسباب:
- سهولة التطوير - يتطور التطبيق بنشاط ، حتى تتمكن من العمل على الفور مع كل الكود.
- خط أنابيب CI / CD واحد يضمن أن التطبيق كنظام واحد يجتاز جميع الاختبارات ويتم توصيله إلى بيئة الزبون.
- نستبعد التشويش في الإصدارات - ليس لدينا لتخزين خريطة لإصدارات microservice ووصف التكوين الخاص بنا لكل microservice في البرامج النصية Helm.
2. التزامن مع مستودع Git لرمز مصدر العميل
تتم مزامنة التغييرات التي تم إجراؤها تلقائيًا مع مستودع Git للعميل. هناك ، يتم تكوين تجميع التطبيق ، والذي يبدأ بعد تحديث الفرع ، ونشر على همز. تحدث كلتا العمليتين في بيئتها من مستودع Git.
لا يمكننا العمل مع مستودع العميل مباشرةً ، لأننا نحتاج إلى بيئات التطوير والاختبار الخاصة بنا. نحن نستخدم مستودع Git الخاص بنا لهذه الأغراض - تتم مزامنته مع مستودع Git الخاص بهم. بمجرد قيام المطور بنشر التغييرات على الفرع المناسب لمستودع التخزين لدينا ، ترسل GitLab هذه التغييرات على الفور إلى العميل.

بعد ذلك ، تحتاج إلى جعل التجمع. يتكون من عدة مراحل: تجميع الواجهة الخلفية والواجهة الأمامية واختبارها وتسليمها إلى المنتج.
3. بناء الخلفية والواجهة الأمامية
التجميع الخلفي والواجهة الأمامية هما مهمتان متوازيتان يتم تنفيذهما في نظام GitLab Runner. يكمن تكوينها للتجميع الأصلي في نفس المستودع.
البرنامج التعليمي لكتابة نص YAML لبناء في GitLab .
يلتقط GitLab Runner الكود من المستودع المرغوب ، ويجمع أمر إنشاء تطبيق Java ويرسله إلى سجل Docker. هنا نقوم بجمع الخلفية والواجهة الأمامية ، والحصول على صور Docker ، والتي نضعها في مستودع على جانب العميل. لإدارة صور Doker ، استخدم
المكوّن الإضافي Gradle .
نقوم بمزامنة إصدارات صورنا مع إصدار الإصدار ، الذي سيتم نشره في Docker. للتشغيل السلس ، قمنا بعمل العديد من الإعدادات:
1. بين بيئة الاختبار وحاويات البقالة لا يتم إعادة تجميعها. لقد قمنا بالترميز حتى يمكن للحاوية نفسها العمل دون إعادة الإنشاء مع كل الإعدادات ومتغيرات البيئة والخدمات في بيئة الاختبار وفي المنتج.
2. لتحديث التطبيق من خلال Helm ، يجب عليك تحديد إصداره. لدينا التجميع الخلفي ، الواجهة الأمامية وتحديث التطبيق - هذه هي ثلاث مهام مختلفة ، لذلك من المهم استخدام نفس الإصدار من التطبيق في كل مكان. بالنسبة لهذه المهمة ، نستخدم بيانات من محفوظات Git ، نظرًا لأن لدينا تكوين مجموعة K8S وتوجد تطبيقات في مستودع Git نفسه.
نحصل على إصدار التطبيق من نتائج الأمر
git describe --tags --abbrev=7
.
4. النشر التلقائي لجميع التغييرات في بيئة اختبار (UAT)
تتمثل الخطوة التالية في هذا البرنامج النصي للبناء في تحديث نظام K8S تلقائيًا. يحدث هذا شريطة أن يتم تجميع التطبيق بأكمله ونشر جميع القطع الأثرية في Docker Registry. بعد ذلك ، يبدأ تحديث بيئة الاختبار.
تم إطلاق تحديث نظام المجموعة باستخدام
Helm Update . إذا ، نتيجة لذلك ، حدث خطأ ما ، فسوف يقوم Helm تلقائيًا وبشكل مستقل باستعادة كل تغييراته. لا يحتاج عمله إلى السيطرة عليه.
جنبا إلى جنب مع التجميع ، نحن نقدم التكوين للكتلة K8S. لذلك ، فإن الخطوة التالية هي تحديثه: configMaps ، والنشر ، والخدمات ، والأسرار ، وأي تكوينات أخرى من K8S قمنا بتغييرها.
بعد ذلك ، Helm تطلق RollOut تحديث التطبيق نفسه في بيئة اختبار. قبل نشر التطبيق على همز. يتم ذلك حتى يتحقق المستخدمون يدويًا من ميزات العمل التي نشرناها في بيئة الاختبار.
5. نشر جميع التغييرات تلقائيا إلى Prod
لنشر التحديث على بيئة المنتج ، كل ما تبقى هو النقر فوق زر واحد في GitLab - ويتم تسليم الحاويات على الفور إلى بيئة المنتج.
يمكن أن يعمل التطبيق نفسه دون إعادة البناء في بيئات مختلفة - الاختبار والإنتاج. نحن نستخدم نفس القطع الأثرية دون تغيير أي شيء في التطبيق ، ونقوم بتعيين المعلمات من الخارج.
تعتمد المعلمة المرنة لإعدادات التطبيق على البيئة التي سيتم فيها تشغيل هذا التطبيق. لقد أخرجنا جميع إعدادات البيئة: كل معلمات من خلال تكوين K8S ومعلمات Helm. عندما تنشر Helm مجموعة في بيئة اختبار ، تنطبق عليها معلمات الاختبار ، وتنطبق معلمات المنتج على بيئة المنتج.
كان أصعب شيء هو تحديد جميع الخدمات والمتغيرات المستخدمة ، والتي تعتمد على البيئة ، وترجمتها إلى متغيرات بيئة ووصف لتكوين معلمات البيئة لـ Helm.
استخدام معلمات التطبيق متغيرات البيئة. يتم تعيين قيمها في حاويات باستخدام مخطط التكوين K8S ، والذي يتم تشكيله باستخدام قوالب Go. على سبيل المثال ، يمكن تعيين متغير بيئة إلى اسم مجال كما يلي:
APP_EXTERNAL_DOMAIN: {{ (pluck .Values.global.env .Values.app.properties.app_external_domain | first) }}
.Values.global.env - يتم
تخزين اسم البيئة (prod ، stage ، UAT) في هذا المتغير.
.Values.app.properties.app_external_domain - في هذا المتغير ، نقوم في ملف .Values.yaml بتعيين النطاق المطلوب
عند تحديث التطبيق ، ينشئ Helm ملف configmap.yaml من القوالب ويملأ قيمة APP_EXTERNAL_DOMAIN بالقيمة المطلوبة اعتمادًا على البيئة التي يبدأ فيها تحديث التطبيق. تم تعيين هذا المتغير بالفعل في الحاوية. يتم الوصول إليه من التطبيق ، على التوالي ، في كل بيئة من التطبيق سيكون هناك قيمة مختلفة لهذا المتغير.
حديثًا نسبيًا ، قدم Spring Cloud دعم K8S ، بما في ذلك العمل مع configMaps:
Spring Cloud Kubernetes . في حين أن المشروع يتطور بنشاط ويتغير بشكل كبير ، لا يمكننا استخدامه في الإنتاج. لكننا نراقب حالته بنشاط ونستخدمه في تكوينات DEV. بمجرد أن يستقر ، سننتقل من استخدام متغيرات البيئة إلى ذلك.
في المجموع
لذلك ، النشر المستمر هو وتشغيلها. تحدث جميع التحديثات بنقرة زر واحدة. تسليم التغييرات في بيئة الطعام تلقائي. والأهم من ذلك ، أن التحديثات لا توقف النظام.

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