إدارة المخرجات وهندسة الإصدارات

خطوط أنابيب الإصدار والترقية

18 دقيقة الدرس 7 من 28

خطوط أنابيب الإصدار والترقية

خط أنابيب الإصدار هو المسار الآلي الذي يسلكه الأداء (Artifact) من لحظة إنتاجه في CI حتى لحظة خدمته لحركة الإنتاج الفعلية. ترقية الأداء (Artifact Promotion) هي منهجية نقل هذا الأداء عبر سلسلة من البيئات — كل منها بوابات أكثر صرامة — دون إعادة بنائه مرة أخرى. إذا أعدت البناء بين بيئة التطوير والإنتاج، فأنت قد اثبت صحة النسخة التطويرية لا نسخة الإنتاج. هذه الفكرة الجوهرية هي ما يُميّز عملية الإصدار الاحترافية عن النصوص البرمجية العشوائية.

مبدأ عدم القابلية للتغيير (Immutability)

الأداء غير قابل للتغيير عندما يكون محتواه ثابتاً منذ لحظة إنشائه ولا يمكن الكتابة فوقه. في مصطلحات الحاويات يعني ذلك التثبيت على بصمة محددة: sha256:a3f7c9... بدلاً من وسم قابل للتغيير مثل :latest أو :v1.2.3. في مصطلحات سجلات الحزم يعني ذلك سجلاً يرفض قبول أي رفع ثانٍ لنفس إحداثيات الإصدار (تدعم Nexus وArtifactory وAWS ECR وسوم الصور غير القابلة للتغيير على مستوى كل مستودع).

أهمية عدم القابلية للتغيير:

  • تنفيذ docker pull myapp:v1.2.3 في يومين مختلفين قد يُعيد بايتات مختلفة صامتةً إذا كان الوسم قابلاً للتغيير. اختبار بيئة الاختبار ونشر الإنتاج لن يكونا على الأداء ذاته.
  • تحليل الحوادث يتطلب استرداد الثنائي المحدد. الوسم القابل للتغيير ربما طُغي عليه.
  • سطح هجوم سلسلة التوريد: وسم قابل للتغيير يسمح لرفع خبيث في السجل بترقية أسطول خفية عند إعادة تشغيل الحاويات.
تثبيت البصمة في Kubernetes: لا تنشر أبداً image: myapp:v1.2.3 في بيانات الإنتاج. انشر دائماً image: 123456789.dkr.ecr.us-east-1.amazonaws.com/myapp@sha256:a3f7c9.... أدوات مثل crane digest أو docker inspect --format '{{.RepoDigests}}' تُحوّل الوسم إلى بصمته الحالية لتسجيل مرجع ثابت في GitOps.

مراحل خط الأنابيب وبوابات الترقية

يمتلك خط أنابيب الإصدار الاحترافي أربع بيئات مُسمّاة. كل بيئة هي بوابة ترقية: إشارات جودة آلية يجب أن تجتاز قبل أن يتقدم الأداء. يُبنى الأداء مرة واحدة فقط (في CI) ثم يُروَّج عبر تحديث ما تُعلن عنه بيئة كل منصة من إعدادات.

Artifact Promotion Pipeline CI Build Unit tests SAST / scan push digest Dev Smoke tests Integration tests Auto gate no approver needed promote Staging E2E tests Perf baseline Security scan 1 human approval promote Production Canary (5%) Rollout expand SLO watch Auto-rollback 2 human approvals Artifact Registry — same immutable digest across all environments
خط أنابيب الترقية: بناء واحد، أربع بيئات، بوابات بشرية وآلية متصاعدة الصرامة.

مستودعات منفصلة لكل طبقة: التطوير والمرشح للإصدار والإصدار

تُقسّم المؤسسات الناضجة مستودع الأداء إلى طبقات منطقية. في Nexus أو Artifactory يُسمى هذا استراتيجية مجموعات المستودعات (Repository Groups)؛ في ECR هي مستودعات منفصلة بسياسات دورة حياة مختلفة. النموذج الشائع بثلاث طبقات:

  • dev / snapshots — كل بناء CI ينتهي هنا تلقائياً. الاحتفاظ قصير (7 أيام). لا موافقة بشرية. الأدوات هنا مرشحات فحسب.
  • rc (مرشح الإصدار) — تُروَّج بواسطة CI بعد اجتياز اختبارات التكامل. مراجعة بشرية اختيارية لكن الفحوصات الأمنية مطلوبة. الاحتفاظ 30 يوماً.
  • release — تُروَّج فقط بعد موافقة بيئة الاختبار وموافقة بشرية صريحة. الاحتفاظ غير محدود (أو تحكمه سياسة). هذا المستودع الوحيد الذي يُسمح للإنتاج بالسحب منه.

الترقية بين المستودعات ليست إعادة بناء — بل هي نسخ. في Artifactory هذا هو jf rt copy؛ في ECR هو aws ecr batch-get-image + aws ecr put-image بنفس البيان. تُحفظ البصمة الثابتة طوال المسار.

# ترقية صورة ECR من مستودع dev إلى مستودع release دون إعادة بناء # كلا المستودعين في نفس الحساب؛ البصمة محفوظة DEV_REPO="123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp-dev" REL_REPO="123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp-release" DIGEST="sha256:a3f7c9d2e811b..." MANIFEST=$(aws ecr batch-get-image \ --repository-name myapp-dev \ --image-ids imageDigest=${DIGEST} \ --query 'images[0].imageManifest' \ --output text) aws ecr put-image \ --repository-name myapp-release \ --image-tag v1.4.0 \ --image-manifest "${MANIFEST}" # التحقق من أن البصمة متطابقة في الوجهة aws ecr describe-images \ --repository-name myapp-release \ --image-ids imageTag=v1.4.0 \ --query 'imageDetails[0].imageDigest'

أتمتة الترقية بنص برمجي

تُطلَق خطوة الترقية بواسطة مهمة خط أنابيب تعمل فقط عند اجتياز بوابة المرحلة السابقة. في GitHub Actions يبدو هذا كسير عمل بسلسلة needs وإعلان environment (الذي يربط قواعد حماية المستودع لموافقة بشرية):

# .github/workflows/promote-staging.yml name: Promote to Staging on: workflow_dispatch: inputs: image_digest: description: "Image digest from dev (sha256:...)" required: true jobs: integration-gate: runs-on: ubuntu-latest steps: - name: Run integration test suite against dev image run: | docker pull 123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp-dev@${{ github.event.inputs.image_digest }} ./scripts/run-integration-tests.sh ${{ github.event.inputs.image_digest }} promote: needs: integration-gate runs-on: ubuntu-latest environment: staging # يفرض المراجعين المطلوبين المُعدَّين في إعدادات مستودع GitHub permissions: id-token: write # OIDC — لا مفاتيح AWS طويلة الأمد contents: read steps: - name: Configure AWS via OIDC uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::123456789012:role/github-staging-promoter aws-region: us-east-1 - name: Copy image to staging repo run: | DIGEST="${{ github.event.inputs.image_digest }}" MANIFEST=$(aws ecr batch-get-image \ --repository-name myapp-dev \ --image-ids imageDigest=${DIGEST} \ --query 'images[0].imageManifest' --output text) aws ecr put-image \ --repository-name myapp-staging \ --image-tag staging-$(date +%Y%m%d%H%M%S) \ --image-manifest "${MANIFEST}" - name: Update GitOps overlay run: | git clone https://x-access-token:${{ secrets.GITOPS_TOKEN }}@github.com/myorg/infra-config.git cd infra-config yq e ".spec.template.spec.containers[0].image = \"...myapp-staging@${DIGEST}\"" \ -i apps/myapp/overlays/staging/deployment-patch.yaml git commit -am "promote myapp to staging @ ${DIGEST}" git push
لا تمرّر بيانات اعتماد طويلة الأمد بين مراحل الترقية. استخدم OIDC (GitHub Actions OIDC ← دور AWS IAM) مُقيَّداً بالصلاحية الدنيا لكل بيئة. دور IAM الخاص بالترقية إلى بيئة الاختبار يجب أن يملك ecr:PutImage على مستودع الاختبار فقط — لا مستودع الإصدار. مُروِّج الإنتاج هو دور منفصل يتطلب موافقة إضافية ويُراجَع مستقلاً في CloudTrail.

أنماط الفشل في الإنتاج التي يجب التصميم لتجنبها

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

  • انحراف البصمة (Digest Drift): طبقة GitOps في بيئة الاختبار مُسجَّلة ببصمة معينة، لكن أحدهم رقّع نشر الإنتاج يدوياً لصورة مختلفة. الحل: مهام المصالحة (تنبيهات diff في Argo CD، أو مهمة CI ليلية تتحقق أن البصمة المنشورة تساوي المُعلَنة في GitOps).
  • تجاوز الترقية: مهندس لديه وصول مباشر لـkubectl ينشر صورة hotfix للإنتاج دون المرور بخط الأنابيب. الحل: admission webhooks ترفض الصور غير المصدرها من مستودع myapp-release مع تسجيل break-glass.
  • تذبذب البوابة (Gate Flapping): اختبارات التكامل غير مستقرة، فيُعطّل الفريق البوابة مؤقتاً. بناء معطوب يُروَّج. الحل: عامل الاختبارات غير المستقرة P1. لا تُعطّل البوابات أبداً؛ أضف قاطع دوائر يمنع الترقية إذا تجاوز معدل التذبذب حداً معيناً.
  • تعارض الإعداد مع الأداء: الأداء مُروَّج بشكل صحيح لكن ConfigMap Kubernetes للميزة الجديدة لم يُحدَّث في طبقة الإنتاج. التطبيق يبدأ ويخطئ فوراً. الحل: التزامات ترقية ذرية تُحدِّث بصمة الصورة وأي إعداد مرتبط في طلب سحب GitOps واحد يُراجَعان معاً.
أخطر نمط في خطوط الأنابيب: مهمة CI تملك صلاحية الكتابة في طبقة GitOps الخاصة بالإنتاج وتستطيع الموافقة على PR الخاص بها. أي اختراق لنظام CI (تبعية خبيثة، رمز مسرَّب) يُفضي إلى نشر إنتاج مباشر دون مراجعة بشرية. طبقات الإنتاج يجب أن تتطلب دائماً موافقة بشرية لا يمكن للروبوت منشئ الطلب تجاوزها.

قياس صحة خط الأنابيب

مقاييس DORA تعكس جودة خط الأنابيب مباشرة. تتبّع هذه المقاييس لكل خدمة:

  • تكرار النشر: كم مرة يصل بناء للإنتاج. الترقيات المحظورة تظهر كفجوات.
  • وقت الوصول للتغييرات: الوقت من الإيداع إلى الإنتاج. الأوقات الطويلة غالباً تعني بوابات يدوية يمكن أتمتتها، أو مجموعات اختبار تكامل بطيئة.
  • معدل فشل التغييرات: نسبة النشرات التي تتطلب hotfix أو تراجعاً. معدل مرتفع يعني أن بوابات ما قبل الإنتاج لا تكتشف الأعطال الحقيقية.
  • متوسط وقت الاستعادة: المدة بعد نشر معطوب حتى استعادة الخدمة. يتحسن مباشرة بالتراجع التلقائي عند خرق SLO.

المتميزون (وفق تقرير DORA State of DevOps) ينشرون عدة مرات يومياً بمعدل فشل أقل من 5% ووقت استعادة أقل من ساعة. كل قرار تصميمي في خط الترقية — عدم القابلية للتغيير، تثبيت البصمة، التزامات الإعداد والصورة الذرية، مستودعات منفصلة لكل طبقة — هو رافعة تُحرّك هذه الأرقام.