استقرار مداوم به موتور Google Kubernetes (GKE) با Cloud Build

۱. مرور کلی

در این آزمایشگاه، یاد خواهید گرفت که یک خط لوله تحویل مداوم برای GKE با Cloud Build راه‌اندازی کنید. این آزمایشگاه نحوه راه‌اندازی کارهای Cloud Build برای رویدادهای مختلف گیت و همچنین یک الگوی ساده برای انتشار خودکار نسخه‌های Canary در GKE را برجسته می‌کند.

مراحل زیر را انجام خواهید داد:

  • ایجاد برنامه GKE
  • خودکارسازی استقرارها برای شاخه‌های گیت
  • خودکارسازی استقرارها برای شاخه اصلی git
  • خودکارسازی استقرارها برای تگ‌های git

۲. قبل از شروع

برای این راهنمای مرجع، به یک پروژه Google Cloud نیاز دارید. می‌توانید یک پروژه جدید ایجاد کنید یا پروژه‌ای را که قبلاً ایجاد کرده‌اید انتخاب کنید:

  1. یک پروژه Google Cloud انتخاب یا ایجاد کنید.

به صفحه انتخاب پروژه بروید

  1. فعال کردن صورتحساب برای پروژه شما

فعال کردن صورتحساب

۳. آماده‌سازی محیط

  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. API های زیر را فعال کنید:
    • مدیر منابع
    • جی کی ای
    • مخازن منبع ابری
    • ساخت ابری
    • رجیستری کانتینر
    gcloud services enable \
        cloudresourcemanager.googleapis.com \
        container.googleapis.com \
        sourcerepo.googleapis.com \
        cloudbuild.googleapis.com \
        containerregistry.googleapis.com \
        --async
    
  3. منبع نمونه را کپی کنید و به دایرکتوری lab بروید:
    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. کد را از مخزن نمونه در مخازن منبع ابری ذخیره کنید:
    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 شما مستقر خواهد کرد و برای این کار به دسترسی‌های لازم نیاز دارد.
    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member=serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
        --role=roles/container.developer
    

محیط شما آماده است!

۴. ایجاد درخواست GKE شما

در این بخش، شما برنامه‌ی کاربردی اولیه‌ای را که در طول این آموزش استفاده خواهید کرد، می‌سازید و مستقر می‌کنید.

  1. ساخت برنامه با Cloud Build:
    gcloud builds submit --tag gcr.io/$PROJECT_ID/$APP_NAME:1.0.0 src/
    
  2. استقرار دستی در محیط‌های Canary و Production: استقرارها و سرویس‌های مربوط به محیط‌های Production و 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
    
    سرویسی که در اینجا مستقر می‌شود، ترافیک را به هر دو استقرار قناری و پرود هدایت می‌کند.
  3. تعداد پادهای در حال اجرا را بررسی کنید. تأیید کنید که چهار پاد برای بخش فرانت‌اند در حال اجرا دارید، از جمله سه پاد برای ترافیک عملیاتی و یکی برای نسخه‌های قناری. این بدان معناست که تغییرات در نسخه قناری شما فقط روی ۱ از ۴ (۲۵٪) کاربران تأثیر می‌گذارد.
    kubectl get pods -n production -l app=$APP_NAME -l role=frontend
    
  4. آدرس IP خارجی را برای سرویس‌های عملیاتی بازیابی کنید.
    kubectl get service $APP_NAME -n production
    
    به محض اینکه متعادل کننده بار آدرس IP را برگرداند، به مرحله بعدی بروید.
  5. آی‌پی خارجی را برای استفاده‌های بعدی ذخیره کنید.
    export PRODUCTION_IP=$(kubectl get -o jsonpath="{.status.loadBalancer.ingress[0].ip}"  --namespace=production services $APP_NAME)
    
  6. برنامه را مرور کنید. خروجی نسخه سرویس را بررسی کنید. باید Hello World نسخه ۱.۰ را نشان دهد.
    curl http://$PRODUCTION_IP
    

تبریک! شما برنامه نمونه را مستقر کردید! در مرحله بعد، محرک‌هایی را برای استقرار مداوم تغییرات خود تنظیم خواهید کرد.

۵. خودکارسازی استقرارها برای شاخه‌های گیت

در این بخش، ماشه ای تنظیم خواهید کرد که یک کار Cloudbuild را در هنگام کامیت هر شاخه ای غیر از شاخه main اجرا کند. فایل Cloud Build که در اینجا استفاده می شود، به طور خودکار یک فضای نام و استقرار برای هر شاخه موجود یا جدید ایجاد می کند و به توسعه دهندگان اجازه می دهد قبل از ادغام با شاخه اصلی، کد خود را پیش نمایش کنند.

  1. راه‌اندازی تریگر: مؤلفه کلیدی این تریگر، استفاده از پارامتر branchName برای تطبیق main و پارامتر invertRegex است که روی true تنظیم شده و الگوی branchName را برای تطبیق با هر چیزی غیر از main تغییر می‌دهد. برای مرجع می‌توانید خطوط زیر را در build/branch-trigger.json پیدا کنید.
      "branchName": "main",
      "invertRegex": true
    
    علاوه بر این، چند خط آخر فایل Cloud Build که با این trigger استفاده می‌شود، یک فضای نام به نام شاخه‌ای که job را فعال کرده است ایجاد می‌کند، سپس برنامه و سرویس را در فضای نام جدید مستقر می‌کند. برای مرجع می‌توانید خطوط زیر را در 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 Triggers در کنسول بروید. به Triggers بروید
  3. ایجاد یک شاخه جدید:
    git checkout -b new-feature-1
    
  4. کد را طوری تغییر دهید که v1.1Edit src/app.py را نشان دهد و پاسخ را از ۱.۰ به ۱.۱ تغییر دهید.
    @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 Build History در کنسول بروید. به Builds بروید. پس از اتمام ساخت، به مرحله بعدی بروید.
  7. آدرس IP خارجی را برای سرویس شعبه تازه مستقر شده بازیابی کنید.
    kubectl get service $APP_NAME -n new-feature-1
    
    به محض اینکه متعادل کننده بار آدرس IP را برگرداند، به مرحله بعدی بروید.
  8. آی‌پی خارجی را برای استفاده‌های بعدی ذخیره کنید.
    export BRANCH_IP=$(kubectl get -o jsonpath="{.status.loadBalancer.ingress[0].ip}"  --namespace=new-feature-1 services $APP_NAME)
    
  9. برنامه را مرور کنید. خروجی نسخه سرویس را بررسی کنید. باید Hello World نسخه ۱.۰ را نشان دهد.
    curl http://$BRANCH_IP
    

۶. خودکارسازی استقرارها برای شاخه اصلی گیت

قبل از انتشار کد برای محیط عملیاتی، معمولاً کد را برای زیرمجموعه‌ی کوچکی از ترافیک زنده منتشر می‌کنند و سپس تمام ترافیک را به پایگاه کد جدید منتقل می‌کنند.

در این بخش، شما یک تریگر (trigger) پیاده‌سازی می‌کنید که هنگام کامیت شدن کد به شاخه اصلی فعال می‌شود. تریگر، نسخه Canary را که ۲۵٪ از کل ترافیک زنده به نسخه جدید را دریافت می‌کند، مستقر می‌کند.

  1. تریگر را برای شاخه اصلی تنظیم کنید:
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/main-trigger.json
    
  2. برای بررسی تریگر جدید، به صفحه Cloud Build Triggers در کنسول بروید. به Triggers بروید
  3. شاخه را با خط اصلی ادغام کنید و به مخزن راه دور ارسال کنید:
    git checkout main
    git merge new-feature-1
    git push gcp main
    
  4. برای بررسی مراحل ساخت، به صفحه Cloud Build History در کنسول بروید. به Builds بروید. پس از اتمام ساخت، به مرحله بعدی بروید.
  5. چندین پاسخ از سرور را بررسی کنید. دستور زیر را اجرا کنید و توجه داشته باشید که تقریباً 25٪ از پاسخ‌ها، پاسخ جدید Hello World v1.1 را نشان می‌دهند.
    while true; do curl -w "\n" http://$PRODUCTION_IP; sleep 1;  done
    
    وقتی آماده ادامه بودید، برای خروج از حلقه، Ctrl+c را فشار دهید.

۷. خودکارسازی استقرارها برای تگ‌های گیت

پس از اینکه استقرار قناری با زیرمجموعه کوچکی از ترافیک تأیید شد، استقرار را برای بقیه ترافیک زنده آزاد می‌کنید.

در این بخش، شما یک تریگر (trigger) تنظیم می‌کنید که هنگام ایجاد یک تگ در مخزن فعال می‌شود. تریگر، تصویر را با تگ مناسب برچسب‌گذاری می‌کند، سپس به‌روزرسانی‌ها را برای تولید اعمال می‌کند و تضمین می‌کند که ۱۰۰٪ ترافیک به تصویر برچسب‌گذاری شده دسترسی پیدا می‌کند.

  1. تریگر تگ را تنظیم کنید:
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/tag-trigger.json
    
  2. برای بررسی تریگر جدید، به صفحه Cloud Build Triggers در کنسول بروید. به Triggers بروید
  3. یک تگ جدید ایجاد کنید و آن را به مخزن راه دور ارسال کنید:
    git tag 1.1
    git push gcp 1.1
    
  4. برای بررسی مراحل ساخت، به صفحه Cloud Build History در کنسول بروید. به Builds بروید
  5. چندین پاسخ از سرور را بررسی کنید. دستور زیر را اجرا کنید و توجه داشته باشید که ۱۰۰٪ پاسخ‌ها، پاسخ جدید Hello World نسخه ۱.۱ را نشان می‌دهند. این ممکن است کمی طول بکشد زیرا پادهای جدید مستقر شده و سلامت آنها در GKE بررسی می‌شود.
    while true; do curl -w "\n" http://$PRODUCTION_IP; sleep 1;  done
    
    وقتی آماده ادامه شدید، برای خروج از حلقه، Ctrl+c را فشار دهید. تبریک می‌گویم! شما محرک‌های CI/CD را در Cloud Build برای شاخه‌ها و برچسب‌های استقرار برنامه‌های خود در GKE ایجاد کردید.

۸. پاکسازی

پروژه را حذف کنید

  1. در کنسول ابری، به صفحه مدیریت منابع بروید.
  2. در لیست پروژه‌ها، پروژه‌ای را که می‌خواهید حذف کنید انتخاب کنید و سپس روی «حذف» کلیک کنید.
  3. در کادر محاوره‌ای، شناسه پروژه را تایپ کنید و سپس برای حذف پروژه، روی خاموش کردن کلیک کنید.