How-To Guides

بناء خط CI/CD بدون توقف باستخدام GitLab CI و ArgoCD لـ Kubernetes

تتطلب تسليم التطبيقات الحديثة ليس فقط السرعة، بل الموثوقية أيضًا. في عالم Kubernetes، لم يعد تحقيق نشرات بدون توقف رفاهية، بل أصبح توقعًا أساسيًا للأنظمة الإنتاجية. من خلال الجمع بين متانة GitLab CI لعمليات البناء والاختبار والقوة التصريحية لـ ArgoCD لتنسيق النشر، يمكنك إنشاء خط GitOps يضمن بقاء خدماتك متاحة أثناء التحديثات.

لماذا نجمع بين GitLab CI و ArgoCD؟

غالبًا ما تتعامل أدوات CI/CD التقليدية مع كل من البناء والنشر في خطوة واحدة أحادية. وعلى الرغم من فعاليتها، يمكن أن يؤدي هذا النهج إلى مشاكل معقدة في إدارة الحالة. يوفر فصل المهام مزايا مميزة:

  • GitLab CI: يتفوق في الترجمة، واختبارات الوحدة، وبناء الصور، ودفع المنتجات إلى سجل الحاويات.
  • ArgoCD: يتخصص في مزامنة الحالة المطلوبة المعرّفة في مستودع Git مع الحالة الحية لـ Kubernetes cluster الخاص بك.

يسمح هذا الفصل بفصل "كيفية البناء" عن "كيفية النشر"، مما يوفر سجلات تدقيق أوضح وآليات تراجع أبسط.

إعداد خط GitLab CI

أولاً، دعنا نعرّف سير عمل GitLab CI. الهدف الرئيسي هنا هو إنتاج صورة حاوية وتحديث manifests Kubernetes في مستودع Git الخاص بك. هذا هو المبدأ الأساسي لـ GitOps: مستودع Git هو المصدر الوحيد للحقيقة.

stages:
  - build
  - push
  - deploy

variables:
  REGISTRY_IMAGE: $CI_REGISTRY_IMAGE

build:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -t $REGISTRY_IMAGE:$CI_COMMIT_SHA .
  only:
    - main

push:
  stage: push
  image: alpine:latest
  script:
    - apk add --no-cache git
    - git config --global user.email "gitlab-ci-token@gl-sa-pipeline"
    - git config --global user.name "GitLab CI"
    - echo "$CI_REGISTRY_PASSWORD" > ~/.netrc
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker push $REGISTRY_IMAGE:$CI_COMMIT_SHA

update-manifests:
  stage: deploy
  image: alpine:latest
  script:
    - apk add --no-cache git
    - git config --global user.email "gitlab-ci-token@gl-sa-pipeline"
    - git config --global user.name "GitLab CI"
    - cd k8s-manifests
    - sed -i 's|image: .*$|image: '$REGISTRY_IMAGE':$CI_COMMIT_SHA|' deployment.yaml
    - git add .
    - git commit -m "Update image to $CI_COMMIT_SHA" || true
    - git push origin main
  only:
    - main
  after_script:
    - echo "Manifests updated. ArgoCD will now detect the change."

لاحظ مهمة update-manifests. لا تقوم بالنشر مباشرة إلى Kubernetes. بدلاً من ذلك، تقوم بتحديث ملف deployment.yaml في المستودع بوسم الصورة الجديد. هذا يحفز ArgoCD على ملاحظة التغيير في مستودع Git.

تهيئة ArgoCD لـ GitOps

يعمل ArgoCD كمُتحكّم (controller) في Kubernetes cluster الخاص بك. إنه يراقب مستودع Git الخاص بك باستمرار. عندما يكتشف تغييرًا في manifests (مثل تحديث وسم الصورة من GitLab CI)، يقوم بمزامنة العنقود مع الحالة الجديدة تلقائيًا.

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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: registry.gitlab.com/group/my-app:latest
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10

إعدادات رئيسية لعدم وجود توقف:

  • maxUnavailable: 0: يضمن عدم وجود أكثر من صفر pods غير متاحة أثناء التحديث. هذا يضمن أن تكون على الأقل replicas (3 في هذه الحالة) pods تعمل دائمًا وجاهزة لخدمة حركة المرور.
  • readinessProbe: يعتمد ArgoCD و Kubernetes على هذا الاستطلاع لتحديد ما إذا كان pod "جاهزًا". لن يُعتبر pod الجديد صحيًا ويُضاف عنوان IP الخاص به إلى Endpoints الخدمة إلا بعد نجاح هذا الاستطلاع. يمنع هذا توجيه حركة المرور إلى pods غير مهيأة بالكامل.

تدفق عدم وجود توقف

إليك العملية خطوة بخطوة عندما يدمج المطور الكود في فرع main:

  1. التحريض: يبدأ خط GitLab CI.
  2. البناء والدفع: يتم بناء صورة Docker جديدة ودفعها إلى السجل مع وسم commit SHA فريد.
  3. تحديث Manifests: تقوم مهمة CI بتحديث deployment.yaml في مستودع Git للإشارة إلى وسم الصورة الجديد وتلزمه (commit).
  4. مزامنة ArgoCD: يكتشف ArgoCD تغيير commit في Git. يقارن بين الحالة المطلوبة (الصورة الجديدة) والحالة الحية (الصورة القديمة).
  5. التحديث المتدحرج: يطبق ArgoCD manifest الجديد على Kubernetes.
    • ينشئ Kubernetes ReplicaSet جديدًا بالصورة الجديدة.
    • تبدأ pods الجديدة في التشغيل وتنجح في استطلاعات الجاهزية الخاصة بها.
    • فقط بعد أن تكون pods الجديدة جاهزة، يبدأ Kubernetes بإنهاء pods القديمة.
    • يواصل LoadBalancer/Service توجيه حركة المرور إلى pods الصحية طوال هذه الفترة الانتقالية.
  6. الاكتمال: جميع pods الجديدة تعمل، وpods القديمة منتهية، والتطبيق محدث بالكامل بدون توقف.

أفضل الممارسات للمرونة

  • استخدام الإصدارات الدلالية للصور: على الرغم من أن commit SHAs دقيقة، إلا أن استخدام الوسوم الدلالية (مثل v1.2.0) يجعل التراجع أسهل في واجهة ArgoCD. يمكنك ببساطة عكس commit في Git لتغيير وسم الصورة مرة أخرى إلى الإصدار المستقر السابق.
  • فحوصات الصحة حاسمة: تأكد من أن livenessProbe و readinessProbe الخاصة بك مضبوطة بشكل صحيح. إذا فشل pod جديد في فحص الجاهزية، سيعتبر ArgoCD المزامنة غير صحية، مما يتيح لك التدخل قبل إزالة pods القديمة.
  • نوافذ مزامنة ArgoCD: للتحكم الأقسى، قم بتكوين نوافذ مزامنة ArgoCD لمنع النشر التلقائي خلال ساعات العمل الحرجة.
  • المراقبة: قم بدمج مقاييس ArgoCD مع Prometheus/Grafana لمراقبة حالة المزامنة، والصحة، ومدة النشر.

الخلاصة

من خلال الاستفادة من GitLab CI لأتمتة البناء و ArgoCD للنشر التصريحي، تقوم بإنشاء خط CI/CD متين وقابل للتدقيق ومرن. المفتاح لعدم وجود توقف لا يكمن في الأدوات نفسها، بل في التهيئة الصحيحة لاستراتيجيات التحديث المتدحرج في Kubernetes واستطلاعات الصحة الصارمة. يضمن نهج GitOps هذا أن تكون نشراتك متوقعة وقابلة للعكس ومتزامنة دائمًا مع مصدر الحقيقة الخاص بك: مستودع Git الخاص بك.

Share: