GitOps والتسليم المستمر

التسليم التدريجي

3 دقيقة للقراءة

التسليم التدريجي يوسع التسليم المستمر مع استراتيجيات نشر متحكم بها. باستخدام Argo Rollouts، يمكن لفرق المنصة توفير أنماط نشر أكثر أمانًا تكتشف وتتراجع تلقائيًا عن الإصدارات المشكلة.

لماذا التسليم التدريجي؟

النشر التقليدي هو كل شيء أو لا شيء:

النشر التقليدي:
┌─────────────────────────────────────────────────────────┐
│                                                         │
│   v1 (100%) ───────────────────► v2 (100%)             │
│                                                         │
│   المشكلة: إذا كان v2 به مشاكل، 100% من المستخدمين متأثرون │
│                                                         │
└─────────────────────────────────────────────────────────┘

التسليم التدريجي:
┌─────────────────────────────────────────────────────────┐
│                                                         │
│   v1 (100%) → v1 (90%) → v1 (50%) → v1 (0%)            │
│              → v2 (10%) → v2 (50%) → v2 (100%)         │
│                    │                                    │
│              فحص المقاييس، التراجع التلقائي إذا لزم     │
│                                                         │
└─────────────────────────────────────────────────────────┘

تثبيت Argo Rollouts

# تثبيت وحدة تحكم Argo Rollouts
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml

# تثبيت إضافة kubectl
brew install argoproj/tap/kubectl-argo-rollouts
# أو: curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/kubectl-argo-rollouts-linux-amd64

# التحقق من التثبيت
kubectl argo rollouts version

# فتح لوحة التحكم
kubectl argo rollouts dashboard
# زيارة http://localhost:3100

نشر Canary

تحويل حركة المرور تدريجيًا للإصدار الجديد:

# rollout-canary.yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: user-service
  namespace: production
spec:
  replicas: 10
  selector:
    matchLabels:
      app: user-service
  template:
    metadata:
      labels:
        app: user-service
    spec:
      containers:
        - name: user-service
          image: user-service:v2.0.0
          ports:
            - containerPort: 8080
          resources:
            requests:
              memory: "256Mi"
              cpu: "250m"
            limits:
              memory: "512Mi"
              cpu: "500m"

  strategy:
    canary:
      # توجيه حركة المرور عبر service mesh أو ingress
      canaryService: user-service-canary
      stableService: user-service-stable

      # تقسيم حركة المرور (يتطلب إدارة حركة المرور)
      trafficRouting:
        nginx:
          stableIngress: user-service-ingress

      steps:
        # الخطوة 1: 10% حركة مرور لـ canary
        - setWeight: 10
        - pause: { duration: 5m }

        # الخطوة 2: تشغيل التحليل
        - analysis:
            templates:
              - templateName: success-rate
            args:
              - name: service-name
                value: user-service-canary

        # الخطوة 3: 30% حركة مرور
        - setWeight: 30
        - pause: { duration: 5m }

        # الخطوة 4: 50% حركة مرور
        - setWeight: 50
        - pause: { duration: 10m }

        # الخطوة 5: نشر كامل
        - setWeight: 100

نشر Blue-Green

تبديل كل حركة المرور دفعة واحدة بعد التحقق:

# rollout-bluegreen.yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: order-service
  namespace: production
spec:
  replicas: 5
  selector:
    matchLabels:
      app: order-service
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
        - name: order-service
          image: order-service:v3.0.0
          ports:
            - containerPort: 8080

  strategy:
    blueGreen:
      # الخدمة تشير للإنتاج الحالي
      activeService: order-service-active

      # الخدمة تشير للإصدار الجديد (للاختبار)
      previewService: order-service-preview

      # الترقية التلقائية بعد التحليل الناجح
      autoPromotionEnabled: true

      # انتظار التحليل قبل الترقية
      prePromotionAnalysis:
        templates:
          - templateName: smoke-tests
        args:
          - name: service-url
            value: http://order-service-preview.production.svc

      # تقليص الإصدار القديم بعد الترقية
      scaleDownDelaySeconds: 300

قوالب التحليل

تحديد المقاييس لقرارات النشر التلقائية:

# analysis-template-success-rate.yaml
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate
  namespace: production
spec:
  args:
    - name: service-name
  metrics:
    - name: success-rate
      # استعلام Prometheus لمعدل النجاح
      provider:
        prometheus:
          address: http://prometheus.monitoring:9090
          query: |
            sum(rate(http_requests_total{
              service="{{args.service-name}}",
              status=~"2.."
            }[5m])) /
            sum(rate(http_requests_total{
              service="{{args.service-name}}"
            }[5m])) * 100
      # معايير النجاح
      successCondition: result[0] >= 99
      failureLimit: 3
      interval: 60s
      count: 5

    - name: error-rate
      provider:
        prometheus:
          address: http://prometheus.monitoring:9090
          query: |
            sum(rate(http_requests_total{
              service="{{args.service-name}}",
              status=~"5.."
            }[5m])) /
            sum(rate(http_requests_total{
              service="{{args.service-name}}"
            }[5m])) * 100
      successCondition: result[0] <= 1
      failureLimit: 3
      interval: 60s
      count: 5

    - name: latency-p99
      provider:
        prometheus:
          address: http://prometheus.monitoring:9090
          query: |
            histogram_quantile(0.99,
              sum(rate(http_request_duration_seconds_bucket{
                service="{{args.service-name}}"
              }[5m])) by (le)
            )
      successCondition: result[0] <= 0.5
      failureLimit: 3
      interval: 60s
      count: 5

إدارة النشر

# مراقبة حالة النشر
kubectl argo rollouts get rollout user-service -w

# ترقية canary للخطوة التالية
kubectl argo rollouts promote user-service

# تخطي التحليل الحالي
kubectl argo rollouts promote user-service --skip-current-step

# إلغاء النشر (التراجع)
kubectl argo rollouts abort user-service

# إعادة محاولة النشر الفاشل
kubectl argo rollouts retry rollout user-service

# عرض تاريخ النشر
kubectl argo rollouts history user-service

# التراجع للمراجعة السابقة
kubectl argo rollouts undo user-service

التكامل مع ArgoCD

Argo Rollouts يعمل بسلاسة مع ArgoCD:

# application-with-rollout.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: user-service
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/acme/gitops-repo.git
    path: apps/user-service
    targetRevision: main
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

# ArgoCD يكتشف موارد Rollout ويعرض
# حالة التسليم التدريجي في الواجهة

مقارنة استراتيجيات النشر

# دليل اختيار الاستراتيجية
strategies:

  canary:
    when_to_use:
      - "تحويل حركة المرور التدريجي مطلوب"
      - "تريد الاختبار مع مجموعة فرعية من المستخدمين"
      - "متطلبات تحليل معقدة"
    traffic_pattern: "تدريجي (10% → 30% → 50% → 100%)"
    rollback_speed: "فوري (تحويل حركة المرور مرة أخرى)"

  bluegreen:
    when_to_use:
      - "تحتاج اختبار البيئة الكاملة قبل التبديل"
      - "تغييرات مخطط قاعدة البيانات"
      - "إدارة حركة مرور أبسط"
    traffic_pattern: "تبديل كل شيء أو لا شيء"
    rollback_speed: "فوري (التبديل إلى blue)"

  recreate:
    when_to_use:
      - "بيئات التطوير"
      - "أحمال العمل غير الحرجة"
      - "تغييرات جذرية لا يمكن تشغيلها جنبًا إلى جنب"
    traffic_pattern: "إيقاف، ثم تشغيل"
    rollback_speed: "إعادة نشر كاملة"

في الدرس التالي، سندمج GitOps مع Crossplane وBackstage لسير عمل IDP كامل. :::

اختبار

الوحدة 4: GitOps والتسليم المستمر

خذ الاختبار