حذف فرع ميزة قديم في مجموعة Kubernetes

حذف فرع ميزة قديم في مجموعة Kubernetes

مرحبا! فرع الميزة (ويعرف أيضًا باسم نشر المعاينة ومراجعة التطبيق) - لا يحدث هذا عندما يتم نشر الفرع الرئيسي فحسب، بل يتم أيضًا نشر كل طلب سحب إلى عنوان URL فريد. يمكنك التحقق مما إذا كانت التعليمات البرمجية تعمل في بيئة الإنتاج؛ ويمكن عرض الميزة للمبرمجين الآخرين أو المتخصصين في المنتج. أثناء العمل على طلب سحب، يتم حذف كل التزام جديد، والنشر الحالي للتعليمات البرمجية القديمة، ويتم نشر النشر الجديد للتعليمات البرمجية الجديدة. قد تنشأ أسئلة عند دمج طلب السحب في الفرع الرئيسي. لم تعد بحاجة إلى فرع الميزات، لكن موارد Kubernetes لا تزال موجودة في المجموعة.

المزيد عن الفروع المميزة

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

kind: Namespace
apiVersion: v1
metadata:
  name: habr-back-end
...

kind: Deployment
apiVersion: apps/v1
metadata:
  namespace: habr-back-end
spec:
  replicas: 3
...

بالنسبة لفرع الميزة، يتم إنشاء مساحة اسم بمعرفها (على سبيل المثال، رقم طلب السحب) ونوع من البادئة/اللاحقة (على سبيل المثال، -العلاقات العامة-):

kind: Namespace
apiVersion: v1
metadata:
  name: habr-back-end-pr-17
...

kind: Deployment
apiVersion: apps/v1
metadata:
  namespace: habr-back-end-pr-17
spec:
  replicas: 1
...

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

$ kubectl get pods --all-namespaces | grep -e "-pr-"
NAMESPACE            ... AGE
habr-back-end-pr-264 ... 4d8h
habr-back-end-pr-265 ... 5d7h

يمكنك أن تقرأ عن كيفية تنفيذ فروع الميزات في المجموعة هنا и هنا.

حافز

دعونا نلقي نظرة على دورة حياة طلب السحب النموذجية مع التكامل المستمر (continuous integration):

  1. نحن ندفع التزامًا جديدًا إلى الفرع.
  2. عند الإنشاء، يتم تشغيل الفلاتر و/أو الاختبارات.
  3. يتم إنشاء تكوينات طلب سحب Kubernetes بسرعة (على سبيل المثال، يتم إدراج رقمها في القالب النهائي).
  4. باستخدام تطبيق kubectl، تتم إضافة التكوينات إلى المجموعة (النشر).
  5. يتم دمج طلب السحب في الفرع الرئيسي.

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

كيفية استخدام

قم بتثبيت المشروع باستخدام الأمر أدناه:

$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.yml

قم بإنشاء ملف بالمحتوى التالي وتثبيته عبر kubectl apply -f:

apiVersion: feature-branch.dmytrostriletskyi.com/v1
kind: StaleFeatureBranch
metadata:
  name: stale-feature-branch
spec:
  namespaceSubstring: -pr-
  afterDaysWithoutDeploy: 3

المعلمة namespaceSubstring اللازمة لتصفية مساحات الأسماء لطلبات السحب من مساحات الأسماء الأخرى. على سبيل المثال، إذا كانت المجموعة تحتوي على مساحات الأسماء التالية: habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33، فسيكون المرشحون للحذف habr-back-end-pr-17, habr-back-end-pr-33.

المعلمة afterDaysWithoutDeploy اللازمة لحذف مساحات الأسماء القديمة. على سبيل المثال، إذا تم إنشاء مساحة الاسم 3 дня 1 час مرة أخرى، وتشير المعلمة 3 дня، سيتم حذف مساحة الاسم هذه. كما أنه يعمل في الاتجاه المعاكس إذا تم إنشاء مساحة الاسم 2 дня 23 часа مرة أخرى، وتشير المعلمة 3 дня، لن يتم حذف مساحة الاسم هذه.

هناك معلمة أخرى، وهي مسؤولة عن عدد مرات فحص كافة مساحات الأسماء والتحقق من الأيام دون نشر - checkEveryMinutes. افتراضيا يساوي 30 минутам.

كيف يعمل هذا؟

في الممارسة العملية، سوف تحتاج إلى:

  1. عامل في حوض السفن للعمل في بيئة معزولة.
  2. مينيكوبي سيتم رفع مجموعة Kubernetes محليًا.
  3. kubectl — واجهة سطر الأوامر لإدارة المجموعة.

نقوم برفع مجموعة Kubernetes محليًا:

$ minikube start --vm-driver=docker
minikube v1.11.0 on Darwin 10.15.5
Using the docker driver based on existing profile.
Starting control plane node minikube in cluster minikube.

حدد kubectl استخدام المجموعة المحلية بشكل افتراضي:

$ kubectl config use-context minikube
Switched to context "minikube".

تنزيل التكوينات الخاصة ببيئة الإنتاج:

$ curl https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.yml > stale-feature-branch-production-configs.yml

نظرًا لأنه تم تكوين تكوينات الإنتاج للتحقق من مساحات الأسماء القديمة، ومجموعتنا المرفوعة حديثًا لا تحتوي عليها، فسوف نقوم باستبدال متغير البيئة IS_DEBUG في true. مع هذه القيمة المعلمة afterDaysWithoutDeploy لا يؤخذ في الاعتبار ولا يتم التحقق من مساحات الأسماء لعدة أيام دون نشر، فقط لحدوث السلسلة الفرعية (-pr-).

إذا كنت على Linux:

$ sed -i 's|false|true|g' stale-feature-branch-production-configs.yml

إذا كنت على macOS:

$ sed -i "" 's|false|true|g' stale-feature-branch-production-configs.yml

تثبيت المشروع:

$ kubectl apply -f stale-feature-branch-production-configs.yml

التحقق من ظهور أحد الموارد في المجموعة StaleFeatureBranch:

$ kubectl api-resources | grep stalefeaturebranches
NAME                 ... APIGROUP                             ... KIND
stalefeaturebranches ... feature-branch.dmytrostriletskyi.com ... StaleFeatureBranch

نتحقق من ظهور عامل التشغيل في المجموعة:

$ kubectl get pods --namespace stale-feature-branch-operator
NAME                                           ... STATUS  ... AGE
stale-feature-branch-operator-6bfbfd4df8-m7sch ... Running ... 38s

إذا نظرت إلى سجلاته، فهو جاهز لمعالجة الموارد StaleFeatureBranch:

$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Operator Version: 0.0.1"}
...
... "msg":"Starting EventSource", ... , "source":"kind source: /, Kind="}
... "msg":"Starting Controller", ...}
... "msg":"Starting workers", ..., "worker count":1}

نقوم بتثبيت الجاهزة fixtures (التكوينات الجاهزة لنمذجة موارد المجموعة) لمورد ما StaleFeatureBranch:

$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/stale-feature-branch.yml

تشير التكوينات إلى البحث عن مساحات الأسماء باستخدام سلسلة فرعية -pr- مرة واحدة في 1 минуту.:

apiVersion: feature-branch.dmytrostriletskyi.com/v1
kind: StaleFeatureBranch
metadata:
  name: stale-feature-branch
spec:
  namespaceSubstring: -pr-
  afterDaysWithoutDeploy: 1 
  checkEveryMinutes: 1

لقد استجاب عامل التشغيل وهو جاهز للتحقق من مساحات الأسماء:

$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Stale feature branch is being processing.","namespaceSubstring":"-pr-","afterDaysWithoutDeploy":1,"checkEveryMinutes":1,"isDebug":"true"}

ضبط fixtures، تحتوي على مساحتي اسم (project-pr-1, project-pr-2) وهم deployments, services, ingress، وما إلى ذلك وهلم جرا:

$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/first-feature-branch.yml -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/second-feature-branch.yml
...
namespace/project-pr-1 created
deployment.apps/project-pr-1 created
service/project-pr-1 created
horizontalpodautoscaler.autoscaling/project-pr-1 created
secret/project-pr-1 created
configmap/project-pr-1 created
ingress.extensions/project-pr-1 created
namespace/project-pr-2 created
deployment.apps/project-pr-2 created
service/project-pr-2 created
horizontalpodautoscaler.autoscaling/project-pr-2 created
secret/project-pr-2 created
configmap/project-pr-2 created
ingress.extensions/project-pr-2 created

نتحقق من إنشاء جميع الموارد المذكورة أعلاه بنجاح:

$ kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-1 && kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-2
...
NAME                              ... READY ... STATUS  ... AGE
pod/project-pr-1-848d5fdff6-rpmzw ... 1/1   ... Running ... 67s

NAME                         ... READY ... AVAILABLE ... AGE
deployment.apps/project-pr-1 ... 1/1   ... 1         ... 67s
...

منذ أن أدرجنا debugمساحات الأسماء project-pr-1 и project-pr-2لذلك يجب حذف جميع الموارد الأخرى على الفور دون مراعاة المعلمة afterDaysWithoutDeploy. يمكن رؤية ذلك في سجلات المشغل:

$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Namespace should be deleted due to debug mode is enabled.","namespaceName":"project-pr-1"}
... "msg":"Namespace is being processing.","namespaceName":"project-pr-1","namespaceCreationTimestamp":"2020-06-16 18:43:58 +0300 EEST"}
... "msg":"Namespace has been deleted.","namespaceName":"project-pr-1"}
... "msg":"Namespace should be deleted due to debug mode is enabled.","namespaceName":"project-pr-2"}
... "msg":"Namespace is being processing.","namespaceName":"project-pr-2","namespaceCreationTimestamp":"2020-06-16 18:43:58 +0300 EEST"}
... "msg":"Namespace has been deleted.","namespaceName":"project-pr-2"}

إذا قمت بالتحقق من توفر الموارد، فسوف تكون في الحالة Terminating (عملية الحذف) أو تم حذفها بالفعل (مخرج الأمر فارغ).

$ kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-1 && kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-2
...

يمكنك تكرار عملية الإنشاء fixtures عدة مرات وتأكد من إزالتها خلال دقيقة واحدة.

البدائل

ما الذي يمكن عمله بدلاً من العامل الذي يعمل في المجموعة؟ هناك عدة طرق، كلها غير كاملة (وعيوبها ذاتية)، والجميع يقرر بنفسه ما هو الأفضل لمشروع معين:

  1. حذف فرع الميزة أثناء إنشاء التكامل المستمر للفرع الرئيسي.

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

  2. استخدام خطافات الويب (مثال).

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

  3. الكتابة cronjob وأضف مجموعة Kubernetes.

    • قضاء الوقت في الكتابة والدعم.
    • يعمل المشغل بالفعل بأسلوب مماثل، وهو موثق ومدعوم.

شكرا لك على اهتمامك بالمقال. رابط المشروع على جيثب.

المصدر: www.habr.com

إضافة تعليق