توسعه InnerLoop با پایتون

۱. مرور کلی

این آزمایشگاه ویژگی‌ها و قابلیت‌هایی را نشان می‌دهد که برای ساده‌سازی گردش کار توسعه برای مهندسان نرم‌افزاری که وظیفه توسعه برنامه‌های پایتون در یک محیط کانتینری را بر عهده دارند، طراحی شده‌اند. توسعه کانتینر معمولاً مستلزم آن است که کاربر جزئیات کانتینرها و فرآیند ساخت کانتینر را درک کند. علاوه بر این، توسعه‌دهندگان معمولاً باید جریان خود را بشکنند و از IDE خود خارج شوند تا برنامه‌های خود را در محیط‌های از راه دور آزمایش و اشکال‌زدایی کنند. با ابزارها و فناوری‌های ذکر شده در این آموزش، توسعه‌دهندگان می‌توانند بدون ترک IDE خود، به طور مؤثر با برنامه‌های کانتینری کار کنند.

آنچه یاد خواهید گرفت

در این آزمایشگاه روش‌های توسعه با کانتینرها در GCP را خواهید آموخت، از جمله:

  • ایجاد یک برنامه شروع کننده جدید پایتون
  • مراحل توسعه را قدم به قدم طی کنید
  • یک سرویس استراحت CRUD ساده توسعه دهید

۲. تنظیمات و الزامات

تنظیم محیط خودتنظیم

  1. وارد کنسول گوگل کلود شوید و یک پروژه جدید ایجاد کنید یا از یک پروژه موجود دوباره استفاده کنید. اگر از قبل حساب جیمیل یا گوگل ورک اسپیس ندارید، باید یکی ایجاد کنید .

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • نام پروژه ، نام نمایشی برای شرکت‌کنندگان این پروژه است. این یک رشته کاراکتری است که توسط APIهای گوگل استفاده نمی‌شود و می‌توانید آن را در هر زمانی به‌روزرسانی کنید.
  • شناسه پروژه باید در تمام پروژه‌های گوگل کلود منحصر به فرد باشد و تغییرناپذیر است (پس از تنظیم، قابل تغییر نیست). کنسول کلود به طور خودکار یک رشته منحصر به فرد تولید می‌کند؛ معمولاً برای شما مهم نیست که چیست. در اکثر آزمایشگاه‌های کد، باید به شناسه پروژه ارجاع دهید (و معمولاً با نام PROJECT_ID شناخته می‌شود)، بنابراین اگر آن را دوست ندارید، یک شناسه تصادفی دیگر ایجاد کنید، یا می‌توانید شناسه خودتان را امتحان کنید و ببینید آیا در دسترس است یا خیر. سپس پس از ایجاد پروژه، آن "منجمد" می‌شود.
  • یک مقدار سوم هم وجود دارد، شماره پروژه که برخی از APIها از آن استفاده می‌کنند. برای اطلاعات بیشتر در مورد هر سه این مقادیر به مستندات مراجعه کنید.
  1. در مرحله بعد، برای استفاده از منابع/APIهای ابری، باید پرداخت صورتحساب را در کنسول ابری فعال کنید . اجرای این آزمایشگاه کد، اگر اصلاً هزینه‌ای نداشته باشد، هزینه زیادی نخواهد داشت. برای خاموش کردن منابع به طوری که پس از این آموزش متحمل پرداخت صورتحساب نشوید، دستورالعمل‌های «پاکسازی» موجود در انتهای آزمایشگاه کد را دنبال کنید. کاربران جدید Google Cloud واجد شرایط برنامه آزمایشی رایگان ۳۰۰ دلاری هستند.

ویرایشگر Cloudshell را شروع کنید

این آزمایشگاه برای استفاده با ویرایشگر پوسته ابری گوگل (Google Cloud Shell Editor) طراحی و آزمایش شده است. برای دسترسی به ویرایشگر،

  1. برای دسترسی به پروژه گوگل خود به آدرس https://console.cloud.google.com مراجعه کنید.
  2. در گوشه بالا سمت راست، روی آیکون ویرایشگر پوسته ابری کلیک کنید.

8560cc8d45e8c112.png

  1. یک پنل جدید در پایین پنجره شما باز خواهد شد
  2. روی دکمه باز کردن ویرایشگر کلیک کنید

9e504cb98a6a8005.png

  1. ویرایشگر با یک کاوشگر در سمت راست و ویرایشگر در ناحیه مرکزی باز خواهد شد.
  2. یک پنجره ترمینال نیز باید در پایین صفحه نمایش موجود باشد
  3. اگر ترمینال باز نیست، از ترکیب کلیدهای `ctrl+`` برای باز کردن یک پنجره ترمینال جدید استفاده کنید.

تنظیمات محیط

در Cloud Shell، شناسه پروژه و شماره پروژه خود را تنظیم کنید. آنها را به عنوان متغیرهای PROJECT_ID و PROJECT_ID ذخیره کنید.

export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID \
    --format='value(projectNumber)')

دریافت کد منبع

  1. کد منبع این آزمایش در container-developer-workshop در GoogleCloudPlatform در GitHub قرار دارد. آن را با دستور زیر کلون کنید و سپس به دایرکتوری بروید.
git clone https://github.com/GoogleCloudPlatform/container-developer-workshop.git &&
cd container-developer-workshop/labs/python
mkdir music-service && cd music-service 
cloudshell workspace .

اگر ترمینال باز نیست، از ترکیب کلیدهای `ctrl+`` برای باز کردن یک پنجره ترمینال جدید استفاده کنید.

فراهم کردن زیرساخت‌های مورد استفاده در این آزمایشگاه

در این آزمایش، شما کد را در GKE مستقر خواهید کرد و به داده‌های ذخیره شده در پایگاه داده Spanner دسترسی خواهید داشت. اسکریپت راه‌اندازی زیر این زیرساخت را برای شما آماده می‌کند. فرآیند آماده‌سازی بیش از 10 دقیقه طول خواهد کشید. می‌توانید در حین پردازش تنظیمات، مراحل بعدی را ادامه دهید.

../setup.sh

۳. یک برنامه‌ی آغازین پایتون جدید ایجاد کنید

  1. یک فایل به نام requirements.txt ایجاد کنید و محتویات زیر را در آن کپی کنید.
Flask
gunicorn
google-cloud-spanner
ptvsd==4.3.2
  1. یک فایل با نام app.py ایجاد کنید و کد زیر را در آن قرار دهید.
import os
from flask import Flask, request, jsonify
from google.cloud import spanner

app = Flask(__name__)

@app.route("/")
def hello_world():
    message="Hello, World!"
    return message

if __name__ == '__main__':
    server_port = os.environ.get('PORT', '8080')
    app.run(debug=False, port=server_port, host='0.0.0.0')

  1. یک فایل با نام Dockerfile ایجاد کنید و کد زیر را در آن قرار دهید:
FROM python:3.8
ARG FLASK_DEBUG=0
ENV FLASK_DEBUG=$FLASK_DEBUG
ENV FLASK_APP=app.py
WORKDIR /app
COPY requirements.txt .
RUN pip install --trusted-host pypi.python.org -r requirements.txt
COPY . .
ENTRYPOINT ["python3", "-m", "flask", "run", "--port=8080", "--host=0.0.0.0"]

نکته : FLASK_DEBUG=1 به شما امکان می‌دهد تغییرات کد را به صورت خودکار در یک برنامه فلاسک پایتون بارگذاری مجدد کنید. این Dockerfile به شما امکان می‌دهد این مقدار را به عنوان آرگومان ساخت ارسال کنید.

تولید مانیفست

در ترمینال خود دستور زیر را اجرا کنید تا فایل‌های پیش‌فرض skaffold.yaml و deployment.yaml ایجاد شوند.

  1. Skaffold را با دستور زیر مقداردهی اولیه کنید
skaffold init --generate-manifests

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

انتخاب کنید:

  • 8080 برای پورت
  • y برای ذخیره پیکربندی

به‌روزرسانی پیکربندی‌های Skaffold

  • تغییر نام پیش‌فرض برنامه
  • skaffold.yaml را باز کنید.
  • نام تصویری که در حال حاضر به عنوان dockerfile-image تنظیم شده است را انتخاب کنید
  • کلیک راست کرده و گزینه Change All Occurrences را انتخاب کنید.
  • نام جدید را python-app تایپ کنید.
  • بخش ساخت را بیشتر ویرایش کنید تا
  • docker.buildArgs برای ارسال FLASK_DEBUG=1 اضافه کنید
  • تنظیمات را برای بارگذاری هرگونه تغییر در فایل‌های *.py از IDE به کانتینر در حال اجرا همگام‌سازی کنید

پس از ویرایش‌ها، بخش ساخت در فایل skaffold.yaml به صورت زیر خواهد بود:

build:
 artifacts:
 - image: python-app
   docker:
     buildArgs:
       FLASK_DEBUG: 1
     dockerfile: Dockerfile
   sync:
     infer:
     - '**/*.py'

تغییر فایل پیکربندی Kubernetes

  1. تغییر نام پیش‌فرض
  • فایل deployment.yaml را باز کنید
  • نام تصویری که در حال حاضر به عنوان dockerfile-image تنظیم شده است را انتخاب کنید
  • کلیک راست کرده و گزینه Change All Occurrences را انتخاب کنید.
  • نام جدید را python-app تایپ کنید.

۴. گام برداشتن در مسیر توسعه

با اضافه شدن منطق تجاری، اکنون می‌توانید برنامه خود را مستقر و آزمایش کنید. بخش بعدی به استفاده از افزونه Cloud Code می‌پردازد. در میان موارد دیگر، این افزونه با skaffold ادغام می‌شود تا فرآیند توسعه شما را ساده‌تر کند. وقتی در مراحل بعدی در GKE مستقر می‌شوید، Cloud Code و Skaffold به طور خودکار تصویر کانتینر شما را می‌سازند، آن را به یک رجیستری کانتینر منتقل می‌کنند و سپس برنامه شما را در GKE مستقر می‌کنند. این اتفاق در پشت صحنه رخ می‌دهد و جزئیات را از جریان توسعه‌دهنده جدا می‌کند.

استقرار در Kubernetes

  1. در پنل پایین ویرایشگر Cloud Shell، گزینه Cloud Code  را انتخاب کنید.

fdc797a769040839.png

  1. در پنلی که در بالا ظاهر می‌شود، گزینه Run on Kubernetes را انتخاب کنید. در صورت درخواست، برای استفاده از متن فعلی Kubernetes، گزینه Yes را انتخاب کنید.

cfce0d11ef307087.png

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

  1. اولین باری که دستور را اجرا می‌کنید، پیامی در بالای صفحه ظاهر می‌شود که از شما می‌پرسد آیا می‌خواهید از چارچوب فعلی kubernetes استفاده کنید یا خیر. برای پذیرش و استفاده از چارچوب فعلی، «بله» را انتخاب کنید.
  2. در مرحله بعد، پیامی نمایش داده می‌شود که از شما می‌پرسد از کدام رجیستری کانتینر استفاده کنید. برای پذیرش مقدار پیش‌فرض ارائه شده، Enter را فشار دهید.
  3. برای مشاهده پیشرفت و اعلان‌ها، برگه خروجی را در پنل پایین انتخاب کنید.

f95b620569ba96c5.png

  1. برای مشاهده جزئیات بیشتر و گزارش‌های زنده از کانتینرها، در منوی کشویی سمت راست، گزینه "Kubernetes: Run/Debug - Detailed" را انتخاب کنید.

94acdcdda6d2108.png

وقتی ساخت و آزمایش‌ها انجام شد، در تب خروجی نوشته می‌شود: Attached debugger to container "python-app-8476f4bbc-h6dsl" successfully. و آدرس اینترنتی http://localhost:8080 نیز فهرست شده است.

  1. در ترمینال Cloud Code، نشانگر ماوس را روی اولین URL در خروجی (http://localhost:8080) نگه دارید و سپس در ابزار نمایش داده شده، گزینه Open Web Preview را انتخاب کنید.
  2. یک تب جدید در مرورگر باز می‌شود و پیام Hello, World! را نمایش می‌دهد.

بارگیری مجدد داغ

  1. فایل app.py را باز کنید.
  2. پیام خوشامدگویی را Hello from Python تغییر دهید

فوراً توجه کنید که در پنجره Output ، نمای Kubernetes: Run/Debug ، ناظر فایل‌های به‌روزرسانی‌شده را با کانتینر در Kubernetes همگام‌سازی می‌کند.

Update initiated
Build started for artifact python-app
Build completed for artifact python-app

Deploy started
Deploy completed

Status check started
Resource pod/python-app-6f646ffcbb-tn7qd status updated to In Progress
Resource deployment/python-app status updated to In Progress
Resource deployment/python-app status completed successfully
Status check succeeded
...
  1. اگر به Kubernetes: Run/Debug - Detailed ، متوجه خواهید شد که تغییرات فایل را تشخیص می‌دهد، سپس برنامه را می‌سازد و دوباره مستقر می‌کند.
files modified: [app.py]
Syncing 1 files for gcr.io/veer-pylab-01/python-app:3c04f58-dirty@sha256:a42ca7250851c2f2570ff05209f108c5491d13d2b453bb9608c7b4af511109bd
Copying files:map[app.py:[/app/app.py]]togcr.io/veer-pylab-01/python-app:3c04f58-dirty@sha256:a42ca7250851c2f2570ff05209f108c5491d13d2b453bb9608c7b4af511109bd
Watching for changes...
[python-app] * Detected change in '/app/app.py', reloading
[python-app] * Restarting with stat
[python-app] * Debugger is active!
[python-app] * Debugger PIN: 744-729-662
  1. برای مشاهده نتایج به‌روزرسانی‌شده، مرورگر خود را به‌روزرسانی کنید.

اشکال‌زدایی

  1. به نمای اشکال‌زدایی (Debug view) بروید و رشته فعلی را متوقف کنید. ۶۴۷۲۱۳۱۲۶d7a4c7b.png .
  2. در منوی پایین روی Cloud Code کلیک کنید و Debug on Kubernetes را انتخاب کنید تا برنامه در حالت debug اجرا شود.
  • در پنجره Kubernetes Run/Debug - Detailed از پنجره Output ، توجه داشته باشید که skaffold این برنامه را در حالت اشکال‌زدایی مستقر خواهد کرد.
  1. اولین باری که این اجرا می‌شود، یک اعلان از شما می‌پرسد که منبع درون کانتینر کجاست. این مقدار مربوط به دایرکتوری‌های موجود در Dockerfile است.

برای پذیرش پیش‌فرض، Enter را فشار دهید

۵۸۳۴۳۶۶۴۷۷۵۲e۴۱۰.png

ساخت و استقرار برنامه چند دقیقه طول خواهد کشید.

  1. وقتی فرآیند کامل شد، متوجه خواهید شد که یک اشکال‌زدا (دیباگر) پیوست شده است.
Port forwarding pod/python-app-8bd64cf8b-cskfl in namespace default, remote port 5678 -> http://127.0.0.1:5678
  1. نوار وضعیت پایین، رنگ خود را از آبی به نارنجی تغییر می‌دهد که نشان می‌دهد در حالت اشکال‌زدایی (Debug mode) است.
  2. در نمای Kubernetes Run/Debug ، توجه کنید که یک کانتینر Debuggable آغاز شده است.
**************URLs*****************
Forwarded URL from service python-app: http://localhost:8080
Debuggable container started pod/python-app-8bd64cf8b-cskfl:python-app (default)
Update succeeded
***********************************

استفاده از نقاط شکست

  1. فایل app.py را باز کنید.
  2. دستوری که return message می‌خواند، پیدا کنید.
  3. با کلیک کردن روی فضای خالی سمت چپ شماره خط، یک نقطه توقف به آن خط اضافه کنید. یک نشانگر قرمز نشان داده می‌شود که نشان می‌دهد نقطه توقف تنظیم شده است.
  4. مرورگر خود را مجدداً بارگذاری کنید و توجه داشته باشید که اشکال‌زدا فرآیند را در نقطه توقف متوقف می‌کند و به شما امکان می‌دهد متغیرها و وضعیت برنامه‌ای را که از راه دور در GKE اجرا می‌شود، بررسی کنید.
  5. روی قسمت VARIABLES کلیک کنید.
  6. روی Locals کلیک کنید تا متغیر "message" را پیدا کنید.
  7. روی متغیر «message» دوبار کلیک کنید و در پنجره باز شده، مقدار آن را به چیزی متفاوت مانند "Greetings from Python" تغییر دهید.
  8. روی دکمه ادامه در پنل کنترل اشکال‌زدایی کلیک کنید 607c33934f8d6b39.png
  9. پاسخ را در مرورگر خود بررسی کنید که اکنون مقدار به‌روزرسانی‌شده‌ای را که وارد کرده‌اید نشان می‌دهد.
  10. با فشار دادن دکمه توقف، حالت «اشکال‌زدایی» را متوقف کنید ۶۴۷۲۱۳۱۲۶d7a4c7b.png و با کلیک مجدد روی نقطه شکست، آن را حذف کنید.

۵. توسعه یک سرویس ساده CRUD Rest

در این مرحله، برنامه شما به طور کامل برای توسعه کانتینری پیکربندی شده است و شما گردش کار اولیه توسعه را با Cloud Code طی کرده‌اید. در بخش‌های بعدی، با اضافه کردن نقاط پایانی سرویس rest که به یک پایگاه داده مدیریت شده در Google Cloud متصل می‌شوند، آموخته‌های خود را تمرین می‌کنید.

سرویس استراحت را کدگذاری کنید

کد زیر یک سرویس rest ساده ایجاد می‌کند که از Spanner به عنوان پایگاه داده پشتیبان برنامه استفاده می‌کند. با کپی کردن کد زیر در برنامه خود، برنامه را ایجاد کنید.

  1. برنامه اصلی را با جایگزینی app.py با محتوای زیر ایجاد کنید.
import os
from flask import Flask, request, jsonify
from google.cloud import spanner


app = Flask(__name__)


instance_id = "music-catalog"

database_id = "musicians"

spanner_client = spanner.Client()
instance = spanner_client.instance(instance_id)
database = instance.database(database_id)


@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"

@app.route('/singer', methods=['POST'])
def create():
    try:
        request_json = request.get_json()
        singer_id = request_json['singer_id']
        first_name = request_json['first_name']
        last_name = request_json['last_name']
        def insert_singers(transaction):
            row_ct = transaction.execute_update(
                f"INSERT Singers (SingerId, FirstName, LastName) VALUES" \
                f"({singer_id}, '{first_name}', '{last_name}')"
            )
            print("{} record(s) inserted.".format(row_ct))

        database.run_in_transaction(insert_singers)

        return {"Success": True}, 200
    except Exception as e:
        return e



@app.route('/singer', methods=['GET'])
def get_singer():

    try:
        singer_id = request.args.get('singer_id')
        def get_singer():
            first_name = ''
            last_name = ''
            with database.snapshot() as snapshot:
                results = snapshot.execute_sql(
                    f"SELECT SingerId, FirstName, LastName FROM Singers " \
                    f"where SingerId = {singer_id}",
                    )
                for row in results:
                    first_name = row[1]
                    last_name = row[2]
                return (first_name,last_name )
        first_name, last_name = get_singer()  
        return {"first_name": first_name, "last_name": last_name }, 200
    except Exception as e:
        return e


@app.route('/singer', methods=['PUT'])
def update_singer_first_name():
    try:
        singer_id = request.args.get('singer_id')
        request_json = request.get_json()
        first_name = request_json['first_name']
        
        def update_singer(transaction):
            row_ct = transaction.execute_update(
                f"UPDATE Singers SET FirstName = '{first_name}' WHERE SingerId = {singer_id}"
            )

            print("{} record(s) updated.".format(row_ct))

        database.run_in_transaction(update_singer)
        return {"Success": True}, 200
    except Exception as e:
        return e


@app.route('/singer', methods=['DELETE'])
def delete_singer():
    try:
        singer_id = request.args.get('singer')
    
        def delete_singer(transaction):
            row_ct = transaction.execute_update(
                f"DELETE FROM Singers WHERE SingerId = {singer_id}"
            )
            print("{} record(s) deleted.".format(row_ct))

        database.run_in_transaction(delete_singer)
        return {"Success": True}, 200
    except Exception as e:
        return e

port = int(os.environ.get('PORT', 8080))
if __name__ == '__main__':
    app.run(threaded=True, host='0.0.0.0', port=port)

اضافه کردن تنظیمات پایگاه داده

برای اتصال ایمن به Spanner، برنامه را طوری تنظیم کنید که از Workload Identities استفاده کند. این کار به برنامه شما اجازه می‌دهد تا به عنوان حساب کاربری سرویس خود عمل کند و هنگام دسترسی به پایگاه داده، مجوزهای جداگانه‌ای داشته باشد.

  1. deployment.yaml را به‌روزرسانی کنید. کد زیر را در انتهای فایل اضافه کنید (در مثال زیر، حتماً تورفتگی تب‌ها را رعایت کنید).
      serviceAccountName: python-ksa
      nodeSelector:
        iam.gke.io/gke-metadata-server-enabled: "true" 

استقرار و اعتبارسنجی برنامه

  1. در پنل پایین ویرایشگر Cloud Shell، گزینه Cloud Code و سپس Debug on Kubernetes را در بالای صفحه انتخاب کنید.
  2. وقتی ساخت و آزمایش‌ها انجام شد، در تب خروجی عبارت زیر نمایش داده می‌شود: Resource deployment/python-app status completed successfully و یک آدرس اینترنتی نیز فهرست شده است: "URL ارسال شده از سرویس python-app: http://localhost:8080"
  3. یکی دو تا مدخل اضافه کن.

از ترمینال cloudshell، دستور زیر را اجرا کنید

curl -X POST http://localhost:8080/singer -H 'Content-Type: application/json' -d '{"first_name":"Cat","last_name":"Meow", "singer_id": 6}'
  1. با اجرای دستور زیر در ترمینال، GET را آزمایش کنید.
curl -X GET http://localhost:8080/singer?singer_id=6
  1. حذف آزمایشی: اکنون با اجرای دستور زیر سعی کنید یک ورودی را حذف کنید. در صورت لزوم، مقدار item-id را تغییر دهید.
curl -X DELETE http://localhost:8080/singer?singer_id=6
    This throws an error message
500 Internal Server Error

شناسایی و رفع مشکل

  1. حالت اشکال‌زدایی (Debug mode) و پیدا کردن مشکل. در اینجا چند نکته وجود دارد:
  • ما می‌دانیم که مشکلی در DELETE وجود دارد زیرا نتیجه دلخواه را برنمی‌گرداند. بنابراین، شما باید نقطه توقف را در app.py در متد delete_singer تنظیم کنید.
  • اجرای گام به گام را اجرا کنید و متغیرها را در هر مرحله زیر نظر داشته باشید تا مقادیر متغیرهای محلی را در پنجره سمت چپ مشاهده کنید.
  • برای مشاهده مقادیر خاص مانند singer_id و request.args در پنجره Watch، این متغیرها را اضافه کنید.
  1. توجه داشته باشید که مقداری که به singer_id اختصاص داده شده None است. برای رفع مشکل، کد را تغییر دهید.

قطعه کد ثابت به این شکل خواهد بود.

@app.route('/delete-singer', methods=['DELETE', 'GET'])
def delete_singer():
    try:
        singer_id = request.args.get('singer_id')
  1. پس از راه‌اندازی مجدد برنامه، دوباره با تلاش برای حذف، آن را امتحان کنید.
  2. با کلیک روی مربع قرمز در نوار ابزار اشکال‌زدایی، جلسه اشکال‌زدایی را متوقف کنید. ۶۴۷۲۱۳۱۲۶d7a4c7b.png

۶. پاکسازی

تبریک! در این آزمایش شما یک برنامه پایتون جدید را از ابتدا ایجاد و آن را برای کار مؤثر با کانتینرها پیکربندی کرده‌اید. سپس برنامه خود را طبق همان جریان توسعه‌دهنده‌ای که در پشته‌های برنامه سنتی یافت می‌شود، در یک کلاستر GKE از راه دور مستقر و اشکال‌زدایی کرده‌اید.

برای تمیز کردن پس از اتمام آزمایشگاه:

  1. فایل‌های استفاده شده در آزمایشگاه را حذف کنید
cd ~ && rm -rf container-developer-workshop
  1. پروژه را حذف کنید تا تمام زیرساخت‌ها و منابع مرتبط حذف شوند.