توسعه InnerLoop با استفاده از ایستگاه های کاری ابری با پایتون

۱. مرور کلی

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

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

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

  • ایجاد یک برنامه شروع کننده جدید پایتون
  • مراحل توسعه را قدم به قدم طی کنید
  • یک سرویس استراحت CRUD ساده توسعه دهید
  • استقرار در GKE
  • اشکال‌زدایی یک حالت خطا
  • استفاده از نقاط شکست/گزارش‌ها
  • تغییرات استقرار سریع (Hot Deploying) به GKE برمی‌گردند

58a4cdd3ed7a123a.png

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

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

  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)')

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

در این آزمایش، شما کد را در GKE مستقر خواهید کرد و به داده‌های ذخیره شده در پایگاه داده Spanner دسترسی خواهید داشت. همچنین از ایستگاه‌های کاری ابری به عنوان IDE استفاده خواهید کرد. اسکریپت راه‌اندازی زیر این زیرساخت را برای شما آماده می‌کند.

  1. اسکریپت نصب را دانلود کنید و آن را قابل اجرا کنید.
wget https://raw.githubusercontent.com/GoogleCloudPlatform/container-developer-workshop/main/labs/python/setup_with_cw.sh
chmod +x setup_with_cw.sh
  1. فایل setup_with_cw.sh را باز کنید و مقادیر رمزهای عبوری که در حال حاضر روی CHANGEME تنظیم شده‌اند را ویرایش کنید.
  2. اسکریپت راه‌اندازی را اجرا کنید تا یک کلاستر GKE و یک پایگاه داده Spanner که در این آزمایش از آنها استفاده خواهید کرد، راه‌اندازی شوند.
./setup_with_cw.sh &

خوشه ایستگاه‌های کاری ابری

  1. ایستگاه‌های کاری ابری را در کنسول ابری باز کنید. منتظر بمانید تا کلاستر در وضعیت READY قرار گیرد.

305e1a3d63ac7ff6.png

ایجاد پیکربندی ایستگاه‌های کاری

  1. اگر اتصال Cloud Shell شما قطع شده است، روی "Reconnect" کلیک کنید و سپس دستور gcloud cli را برای تنظیم شناسه پروژه اجرا کنید. قبل از اجرای دستور، شناسه نمونه پروژه زیر را با شناسه پروژه qwiklabs خود جایگزین کنید.
gcloud config set project qwiklabs-gcp-project-id
  1. اسکریپت زیر را دانلود و در ترمینال اجرا کنید تا پیکربندی Cloud Workstations ایجاد شود.
wget https://raw.githubusercontent.com/GoogleCloudPlatform/container-developer-workshop/main/labs/python/workstation_config_setup.sh
chmod +x workstation_config_setup.sh
./workstation_config_setup.sh
  1. نتایج را در بخش تنظیمات تأیید کنید. 2 دقیقه طول می‌کشد تا به وضعیت آماده (READY) برسید.

2e23c2e9983d1ccf.png

  1. Cloud Workstations را در کنسول باز کنید و یک نمونه جدید ایجاد کنید.

a53adeeac81a78c8.png

  1. نام را به my-workstation تغییر دهید و پیکربندی موجود را انتخاب کنید: codeoss-python .

f052cd47701ec774.png

  1. نتایج را در بخش Workstations تأیید کنید.

ایستگاه کاری را راه اندازی کنید

  1. ایستگاه کاری را شروع و اجرا کنید. شروع به کار ایستگاه کاری چند دقیقه طول خواهد کشید.

682f8a307032cba3.png

  1. با کلیک روی نماد در نوار آدرس، کوکی‌های شخص ثالث را مجاز کنید. ۱b8923e2943f9bc4.png

fcf9405b6957b7d7.png

  1. روی «سایت کار نمی‌کند؟» کلیک کنید.

36a84c0e2e3b85b.png

  1. روی «اجازه دادن به کوکی‌ها» کلیک کنید.

۲۲۵۹۶۹۴۳۲۸۶۲۸fba.png

  1. پس از راه‌اندازی ایستگاه کاری، خواهید دید که Code OSS IDE ظاهر می‌شود. در صفحه شروع به کار، روی «Mark Done» در صفحه اول IDE ایستگاه کاری کلیک کنید.

۹۴۸۷۴fba9b74cc22.png

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

در این بخش، یک برنامه جدید پایتون ایجاد خواهید کرد.

  1. یک ترمینال جدید باز کنید.

c31d48f2e4938c38.png

  1. یک دایرکتوری جدید ایجاد کنید و آن را به عنوان یک فضای کاری باز کنید
mkdir music-service && cd music-service

code-oss-cloud-workstations -r --folder-uri="$PWD"

اگر این پیام را مشاهده کردید، روی دکمه‌ی «اجازه دادن» کلیک کنید تا بتوانید در ایستگاه کاری کپی پیست کنید.

58149777e5cc350a.png

  1. یک فایل به نام requirements.txt ایجاد کنید و محتویات زیر را در آن کپی کنید.

789e8389170bd900.png

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 به طور خودکار تصویر کانتینر شما را می‌سازند، آن را به یک رجیستری کانتینر منتقل می‌کنند و سپس برنامه your را در GKE مستقر می‌کنند. این اتفاق در پشت صحنه رخ می‌دهد و جزئیات را از جریان توسعه‌دهنده جدا می‌کند.

وارد فضای ابری گوگل شوید

  1. روی آیکون Cloud Code کلیک کنید و گزینه «ورود به سیستم Google Cloud» را انتخاب کنید:

۱۷۶۹afd39be372ff.png

  1. روی «ادامه برای ورود» کلیک کنید.

۹۲۳bb1c8f63160f9.png

  1. خروجی را در ترمینال بررسی کنید و لینک را باز کنید:

517fdd579c34aa21.png

  1. با اعتبارنامه‌های دانشجویی Qwiklabs خود وارد شوید.

db99b345f7a8e72c.png

  1. گزینه "مجاز" را انتخاب کنید:

a5376553c430ac84.png

  1. کد تأیید را کپی کنید و به برگه Workstation برگردید.

6719421277b92eac.png

  1. کد تأیید را جایگذاری کنید و Enter را بزنید.

e9847cfe3fa8a2ce.png

اضافه کردن کلاستر Kubernetes

  1. اضافه کردن یک خوشه

62a3b97bdbb427e5.png

  1. موتور گوگل کوبرنتیز را انتخاب کنید:

9577de423568bbaa.png

  1. انتخاب پروژه.

c5202fcbeebcd41c.png

  1. "python-cluster" که در تنظیمات اولیه ایجاد شده بود را انتخاب کنید.

719c2fc0a7f9e84f.png

  1. اکنون این کلاستر در فهرست کلاسترهای Kubernetes در زیر Cloud Code نمایش داده می‌شود. از اینجا می‌توانید به آن دسترسی پیدا کرده و آن را بررسی کنید.

7e5f50662d4eea3c.png

تنظیم شناسه پروژه فعلی با استفاده از gcloud cli

  1. شناسه پروژه این آزمایشگاه را از صفحه qwiklabs کپی کنید.

fcff2d10007ec5bc.png

  1. از ترمینال، دستور gcloud cli را برای تنظیم شناسه پروژه اجرا کنید. قبل از اجرای دستور، شناسه پروژه نمونه را جایگزین کنید. قبل از اجرای دستور زیر، شناسه پروژه را جایگزین کنید.
gcloud config set project qwiklabs-gcp-project-id

استقرار در Kubernetes

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

d99a88992e15fea9.png

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

bfd65e9df6d4a6c.png

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

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

9c87ccbf5d06f50a.png

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

804abc8833ffd571.png

وقتی ساخت و آزمایش‌ها انجام شد، در برگه گزارش‌های خروجی، آدرس اینترنتی http://localhost:8080 در نمای "Kubernetes: Run/Debug" نمایش داده می‌شود.

  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. 70d6bd947d04d1e6.png
  3. در منوی پایین روی Cloud Code کلیک کنید و Debug on Kubernetes را انتخاب کنید تا برنامه در حالت debug اجرا شود.
  • در پنجره Kubernetes Run/Debug - Detailed از پنجره Output ، توجه داشته باشید که skaffold این برنامه را در حالت اشکال‌زدایی مستقر خواهد کرد.
  1. وقتی فرآیند کامل شد، متوجه خواهید شد که یک اشکال‌زدا (دیباگر) متصل شده و در تب خروجی نوشته شده است: Attached debugger to container "python-app-8476f4bbc-h6dsl" successfully. و آدرس اینترنتی http://localhost:8080 نیز در فهرست آمده است.
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. اولین باری که این اجرا می‌شود، یک اعلان از شما می‌پرسد که منبع درون کانتینر کجاست. این مقدار مربوط به دایرکتوری‌های موجود در Dockerfile است.

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

fccc866f32b5ed86.png

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

  1. مرورگر خود را مجدداً بارگذاری کنید و توجه داشته باشید که اشکال‌زدا فرآیند را در نقطه توقف متوقف می‌کند و به شما امکان می‌دهد متغیرها و وضعیت برنامه‌ای را که از راه دور در GKE اجرا می‌شود، بررسی کنید.
  2. روی قسمت VARIABLES کلیک کنید.
  3. روی Locals کلیک کنید تا متغیر "message" را پیدا کنید.
  4. روی متغیر «message» دوبار کلیک کنید و در پنجره باز شده، مقدار آن را به چیزی متفاوت مانند "Greetings from Python" تغییر دهید.
  5. روی دکمه ادامه در پنل کنترل اشکال‌زدایی کلیک کنید 607c33934f8d6b39.png
  6. پاسخ را در مرورگر خود بررسی کنید که اکنون مقدار به‌روزرسانی‌شده‌ای را که وارد کرده‌اید نشان می‌دهد.
  7. با فشار دادن دکمه توقف، حالت «اشکال‌زدایی» را متوقف کنید ۶۴۷۲۱۳۱۲۶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" 

بعد از تغییرات، بخش مشخصات باید به این شکل باشد

   spec:
     containers:
     - name: python-app
       image: python-app
     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 ~/music-service
  1. پروژه را حذف کنید تا تمام زیرساخت‌ها و منابع مرتبط حذف شوند.