نشر مستمر في Google Kubernetes Engine (GKE) باستخدام Cloud Build

1. نظرة عامة

في هذا التمرين، ستتعلم كيفية إعداد مسار تسليم متواصل لنظام GKE باستخدام Cloud Build. يعرض هذا التمرين المعملي كيفية تشغيل مهام Cloud Build لأحداث git المختلفة بالإضافة إلى نمط بسيط لإصدارات Canary الآلية في GKE.

عليك إكمال الخطوات التالية:

  • إنشاء تطبيق GKE
  • برمجة عمليات النشر في فروع git
  • أتمتة عمليات النشر في فرع git الرئيسي
  • التشغيل الآلي لعمليات النشر لعلامات git

2. قبل البدء

بالنسبة إلى هذا الدليل المرجعي، ستحتاج إلى مشروع على Google Cloud. يمكنك إنشاء مشروع جديد أو اختيار مشروع سبق أن أنشأته باتّباع الخطوات التالية:

  1. اختَر مشروعًا على Google Cloud أو أنشئ مشروعًا.

الانتقال إلى صفحة "أداة اختيار المشروع"

  1. فعِّل الفوترة لمشروعك.

تفعيل الفوترة

3- تحضير البيئة

  1. يمكنك إنشاء متغيّرات بيئية لاستخدامها في هذا البرنامج التعليمي:
    export PROJECT_ID=$(gcloud config get-value project)
    export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
    
    export ZONE=us-central1-b
    export CLUSTER=gke-progression-cluster
    export APP_NAME=myapp
    
  2. تمكين واجهات برمجة التطبيقات التالية:
    • Resource Manager
    • GKE
    • Cloud Source Repositories
    • Cloud Build
    • Container Registry
    gcloud services enable \
        cloudresourcemanager.googleapis.com \
        container.googleapis.com \
        sourcerepo.googleapis.com \
        cloudbuild.googleapis.com \
        containerregistry.googleapis.com \
        --async
    
  3. استنسِخ مصدر النموذج وبدِّل إلى دليل المختبر:
    git clone https://github.com/GoogleCloudPlatform/software-delivery-workshop.git gke-progression
    
    cd gke-progression/labs/gke-progression
    rm -rf ../../.git
    
  4. استبدِل قيم العنصر النائب في نموذج المستودع باستخدام PROJECT_ID:في هذه الخطوة، يمكنك إنشاء مثيلات لملفات الإعداد المختلفة والفريدة لبيئتك الحالية.لمراجعة مثال على النماذج التي يتم تعديلها، شغِّل الأمر التالي.
    cat k8s/deployments/dev/frontend-dev.yaml.tmpl
    
    نفذ استبدال المتغير عن طريق تنفيذ الأمر Followign.
    for template in $(find . -name '*.tmpl'); do envsubst '${PROJECT_ID} ${ZONE} ${CLUSTER} ${APP_NAME}' < ${template} > ${template%.*}; done
    
    لمراجعة مثال على ملف بعد الاستبدال، شغِّل الأمر التالي.
    cat k8s/deployments/dev/frontend-dev.yaml
    
  5. إذا لم يسبق لك استخدام Git في Cloud Shell، اضبط القيمتين user.name وuser.email اللتين تريد استخدامهما:
    git config --global user.email "YOUR_EMAIL_ADDRESS"
    git config --global user.name "YOUR_USERNAME"
    
  6. يمكنك تخزين الرمز من نموذج المستودع في مستودعات Cloud Source:
    gcloud source repos create gke-progression
    git init
    git config credential.helper gcloud.sh
    git remote add gcp https://source.developers.google.com/p/$PROJECT_ID/r/gke-progression
    git branch -m main
    git add . && git commit -m "initial commit"
    git push gcp main
    
  7. أنشِئ مجموعة GKE.
    gcloud container clusters create ${CLUSTER} \
        --project=${PROJECT_ID} \
        --zone=${ZONE}
    
  8. يمكنك منح حقوق Cloud Build للمجموعة التي أنشأتها.سينشر Cloud Build التطبيق في GKE Cluster وسيكون عليه الحصول على حقوق لتنفيذ ذلك.
    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member=serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
        --role=roles/container.developer
    

بيئتك جاهزة

4. إنشاء تطبيق GKE

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

  1. إنشاء التطبيق باستخدام Cloud Build:
    gcloud builds submit --tag gcr.io/$PROJECT_ID/$APP_NAME:1.0.0 src/
    
  2. النشر يدويًا في بيئات إصدار Canary و"الإنتاج": أنشِئ عمليات نشر وخدمات الإصدار Canary والإصدار Canary باستخدام أوامر "kubectl apply".
    kubectl create ns production
    kubectl apply -f k8s/deployments/prod -n production
    kubectl apply -f k8s/deployments/canary -n production
    kubectl apply -f k8s/services -n production
    
    ستعمل الخدمة المنشورة هنا على توجيه الزيارات إلى كل من عمليتَي نشر إصدار Canary والمنتج.
  3. مراجعة عدد مجموعات الصور المتسلسلة والتأكد من تشغيل أربعة مجموعات للواجهة الأمامية، تتضمن ثلاث مجموعات لحركة بيانات الإنتاج وأخرى لإصدارات Canary. ويعني ذلك أنّ التغييرات التي سيتم إجراؤها على إصدار Canary ستؤثّر فقط على مستخدم واحد من أصل 4 (%25) من المستخدمين.
    kubectl get pods -n production -l app=$APP_NAME -l role=frontend
    
  4. استرداد عنوان IP الخارجي لخدمات الإنتاج.
    kubectl get service $APP_NAME -n production
    
    بعد أن يعود جهاز موازنة الحمل إلى عنوان IP، يُرجى المتابعة إلى الخطوة التالية.
  5. تخزين عنوان IP الخارجي لاستخدامه في وقت لاحق
    export PRODUCTION_IP=$(kubectl get -o jsonpath="{.status.loadBalancer.ingress[0].ip}"  --namespace=production services $APP_NAME)
    
  6. مراجعة التطبيق. تحقق من إصدار الخدمة. من المفترض أن تتم قراءة Hello World v1.0
    curl http://$PRODUCTION_IP
    

تهانينا! لقد نشرت نموذج التطبيق. بعد ذلك، عليك إعداد مشغِّلات لنشر التغييرات باستمرار.

5- التشغيل الآلي لعمليات النشر لفروع git

في هذا القسم، عليك إعداد مشغِّل لتنفيذ مهمة Cloudbuild في حال إتمامها من أيّ فرع غير main. سيُنشئ ملف Cloud Build المستخدَم هنا تلقائيًا مساحة اسم ونشرًا لأي فروع حالية أو جديدة، ما يسمح للمطوّرين بمعاينة الرموز البرمجية قبل الدمج مع الفرع الرئيسي.

  1. إعداد عامل التشغيل:إنّ المكون الرئيسي لهذا المشغِّل هو استخدام مَعلمة branchName لمطابقة main والمَعلمة invertRegex التي يتمّ ضبطها على "صحيح"، كما يغيّر نمط branchName لمطابقة أي قيمة غير main. يمكنك العثور على السطور التالية في build/branch-trigger.json كمرجع لك.
      "branchName": "main",
      "invertRegex": true
    
    بالإضافة إلى ذلك، تنشئ السطور القليلة الأخيرة من ملف Cloud Build المستخدَم مع هذا المشغِّل مساحة اسم تحمل اسم الفرع الذي أدّى إلى تنفيذ المهمّة، ثمّ ينشر التطبيق والخدمة ضمن مساحة الاسم الجديدة. يمكنك العثور على السطور التالية في build/branch-cloudbuild.yaml
      kubectl get ns ${BRANCH_NAME} || kubectl create ns ${BRANCH_NAME}
      kubectl apply --namespace ${BRANCH_NAME} --recursive -f k8s/deployments/dev
      kubectl apply --namespace ${BRANCH_NAME} --recursive -f k8s/services
    
    للرجوع إليها. والآن بعد أن فهمت الآليات المستخدمة، يمكنك إنشاء مشغِّل باستخدام الأمر gcloud أدناه.
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/branch-trigger.json
    
  2. لمراجعة العامل المشغِّل، انتقِل إلى صفحة "العوامل المشغِّلة" في Cloud Build في وحدة التحكّم. انتقِل إلى "العوامل المشغِّلة".
  3. إنشاء فرع جديد:
    git checkout -b new-feature-1
    
  4. تعديل الرمز للإشارة إلى الإصدار 1.1تعديل src/app.py وتغيير الردّ من 1.0 إلى 1.1
    @app.route('/')
    def hello_world():
        return 'Hello World v1.1'
    
  5. إتمام التغيير وإرساله إلى المستودع البعيد:
    git add . && git commit -m "updated" && git push gcp new-feature-1
    
  6. لمراجعة عملية الإنشاء، انتقِل إلى صفحة سجلّ إنشاء Cloud في وحدة التحكّم.الانتقال إلى الإصداراتبعد اكتمال عملية الإنشاء، انتقِل إلى الخطوة التالية.
  7. استرداد عنوان IP الخارجي للخدمة الفرعية المنشورة حديثًا.
    kubectl get service $APP_NAME -n new-feature-1
    
    بعد أن يعود جهاز موازنة الحمل إلى عنوان IP، يُرجى المتابعة إلى الخطوة التالية.
  8. تخزين عنوان IP الخارجي لاستخدامه في وقت لاحق
    export BRANCH_IP=$(kubectl get -o jsonpath="{.status.loadBalancer.ingress[0].ip}"  --namespace=new-feature-1 services $APP_NAME)
    
  9. مراجعة التطبيق. تحقق من إصدار إصدار الخدمة. من المفترض أن تتم قراءة Hello World v1.0
    curl http://$BRANCH_IP
    

6- التشغيل الآلي لعمليات النشر في فرع git الرئيسي

قبل إصدار الرمز في مرحلة الإنتاج، من الشائع إصدار الرمز لمجموعة فرعية صغيرة من الزيارات المباشرة قبل نقل جميع الزيارات إلى قاعدة الرموز الجديدة.

في هذا القسم، تقوم بتنفيذ مشغل يتم تنشيطه عندما تكون التعليمات البرمجية مرتبطة بالفرع الرئيسي. ينشر العامل المشغِّل نشر إصدار Canary الذي يتلقى 25% من جميع حركة الزيارات المباشرة إلى المراجعة الجديدة.

  1. إعداد عامل التفعيل للفرع الرئيسي:
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/main-trigger.json
    
  2. لمراجعة عامل التفعيل الجديد، انتقِل إلى صفحة "العوامل المشغِّلة" في Cloud Build في وحدة التحكّم.الانتقال إلى "العوامل المشغِّلة"
  3. ادمج الفرع في السطر الرئيسي وانقله إلى المستودع البعيد:
    git checkout main
    git merge new-feature-1
    git push gcp main
    
  4. لمراجعة عملية الإنشاء، انتقِل إلى صفحة سجلّ الإنشاء في Cloud في وحدة التحكّم.الانتقال إلى الإصداراتبعد اكتمال عملية الإنشاء، انتقِل إلى الخطوة التالية.
  5. راجع استجابات متعددة من serverRun الأمر التالي ولاحظ أن ما يقرب من 25% من الاستجابات تعرض الاستجابة الجديدة لـ Hello World v1.1
    while true; do curl -w "\n" http://$PRODUCTION_IP; sleep 1;  done
    
    عندما تكون مستعدًا للمتابعة، اضغط على Ctrl+c للخروج من الحلقة.

7. التشغيل الآلي لعمليات النشر لعلامات git

بعد التحقّق من صحة نشر إصدار Canary باستخدام مجموعة فرعية صغيرة من الزيارات، يمكنك إتاحة النشر لبقية الزيارات المباشرة.

وفي هذا القسم، يمكنك إعداد مشغِّل يتم تفعيله عند إنشاء علامة في المستودع. يصنِّف عامل التشغيل الصورة باستخدام العلامة المناسبة ثم ينشر التعديلات في المنتج لضمان وصول 100% من الزيارات إلى الصورة التي تم وضع علامات عليها.

  1. إعداد مشغِّل العلامة:
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/tag-trigger.json
    
  2. لمراجعة عامل التفعيل الجديد، انتقِل إلى صفحة "العوامل المشغِّلة" في Cloud Build في وحدة التحكّم.الانتقال إلى "العوامل المشغِّلة"
  3. أنشئ علامة جديدة وانشرها إلى المستودع البعيد:
    git tag 1.1
    git push gcp 1.1
    
  4. لمراجعة عملية الإنشاء، انتقِل إلى صفحة سجلّ Cloud Build في Console.الانتقال إلى "الإصدارات"
  5. راجِع الردود المتعددة من serverRun الأمر التالي، ولاحظ أن 100% من الاستجابات تعرض الاستجابة الجديدة لـ Hello World v1.1قد يستغرق هذا لحظة عندما يتم نشر مجموعات الإعلانات المتسلسلة الجديدة والتحقّق من سلامتها داخل GKE
    while true; do curl -w "\n" http://$PRODUCTION_IP; sleep 1;  done
    
    عندما تكون مستعدًا للمتابعة، يمكنك الضغط على Ctrl+c للخروج من الحلقة. تهانينا. لقد أنشأت مشغِّلات CI/CD في Cloud Build للفروع والعلامات لنشر تطبيقاتك على GKE.

8. تنظيف

حذف المشروع

  1. في Cloud Console، انتقِل إلى صفحة "إدارة الموارد".
  2. في قائمة المشاريع، اختَر المشروع الذي تريد حذفه، ثم انقر على حذف.
  3. في مربّع الحوار، اكتب رقم تعريف المشروع، ثم انقر على إيقاف التشغيل لحذف المشروع.