การพัฒนา InnerLoop ด้วย Python

1. ภาพรวม

ห้องทดลองนี้แสดงให้เห็นฟีเจอร์และความสามารถที่ออกแบบมาเพื่อปรับปรุงเวิร์กโฟลว์การพัฒนาสำหรับวิศวกรซอฟต์แวร์ที่ได้รับมอบหมายให้พัฒนาแอปพลิเคชัน Python ในสภาพแวดล้อมที่สร้างโดยใช้คอนเทนเนอร์ การพัฒนาคอนเทนเนอร์ทั่วไปกำหนดให้ผู้ใช้ทำความเข้าใจรายละเอียดของคอนเทนเนอร์และกระบวนการสร้างคอนเทนเนอร์ นอกจากนี้ นักพัฒนาซอฟต์แวร์มักต้องแยกขั้นตอนของตนเองโดยย้ายออกจาก IDE เพื่อทดสอบและแก้ไขข้อบกพร่องแอปพลิเคชันในสภาพแวดล้อมระยะไกล ด้วยเครื่องมือและเทคโนโลยีที่กล่าวถึงในบทแนะนำนี้ นักพัฒนาซอฟต์แวร์สามารถทำงานได้อย่างมีประสิทธิภาพกับแอปพลิเคชันที่สร้างโดยใช้คอนเทนเนอร์โดยไม่ต้องออกจาก IDE

สิ่งที่คุณจะได้เรียนรู้

ในห้องทดลองนี้ คุณจะได้เรียนรู้วิธีการพัฒนาด้วยคอนเทนเนอร์ใน GCP ดังต่อไปนี้

  • การสร้างแอปพลิเคชันเริ่มต้นสำหรับ Python ใหม่
  • แนะนำกระบวนการพัฒนา
  • พัฒนาบริการ CRUD REST อย่างง่าย

2. การตั้งค่าและข้อกำหนด

การตั้งค่าสภาพแวดล้อมตามเวลาที่สะดวก

  1. ลงชื่อเข้าใช้ Google Cloud Console และสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่อีกครั้ง หากยังไม่มีบัญชี Gmail หรือ Google Workspace คุณต้องสร้างบัญชี

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • ชื่อโครงการคือชื่อที่แสดงของผู้เข้าร่วมโปรเจ็กต์นี้ เป็นสตริงอักขระที่ Google APIs ไม่ได้ใช้และคุณอัปเดตได้ทุกเมื่อ
  • รหัสโปรเจ็กต์ต้องไม่ซ้ำกันในโปรเจ็กต์ Google Cloud ทั้งหมดและจะเปลี่ยนแปลงไม่ได้ (เปลี่ยนแปลงไม่ได้หลังจากตั้งค่าแล้ว) Cloud Console จะสร้างสตริงที่ไม่ซ้ำกันโดยอัตโนมัติ ปกติแล้วคุณไม่สนว่าอะไรเป็นอะไร ใน Codelab ส่วนใหญ่ คุณจะต้องอ้างอิงรหัสโปรเจ็กต์ (ซึ่งปกติระบุไว้ว่าเป็น PROJECT_ID) ดังนั้นหากไม่ชอบ ให้สร้างรหัสแบบสุ่มขึ้นมาอีกรหัสหนึ่ง หรือคุณจะลองใช้รหัสโปรเจ็กต์ของคุณเองแล้วดูว่ารหัสโปรเจ็กต์พร้อมใช้งานหรือไม่ แล้วก็ "แช่แข็ง" หลังจากสร้างโปรเจ็กต์แล้ว
  • มีค่าที่ 3 คือหมายเลขโปรเจ็กต์ที่ API บางตัวใช้ ดูข้อมูลเพิ่มเติมเกี่ยวกับค่าทั้ง 3 ค่าเหล่านี้ในเอกสารประกอบ
  1. ถัดไป คุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากร/API ของระบบคลาวด์ การใช้งาน Codelab นี้น่าจะไม่มีค่าใช้จ่ายใดๆ หากมี หากต้องการปิดทรัพยากรเพื่อไม่ให้มีการเรียกเก็บเงินนอกเหนือจากบทแนะนำนี้ ให้ทำตาม "การล้าง" ดูได้ที่ตอนท้ายของ Codelab ผู้ใช้ใหม่ของ Google Cloud จะมีสิทธิ์เข้าร่วมโปรแกรมทดลองใช้ฟรี$300 USD

เริ่มผู้แก้ไข Cloudshell

ห้องทดลองนี้ออกแบบและทดสอบเพื่อใช้กับ Google Cloud Shell Editor วิธีเข้าถึงเครื่องมือแก้ไข

  1. เข้าถึงโปรเจ็กต์ Google ที่ https://console.cloud.google.com
  2. คลิกไอคอนตัวแก้ไข Cloud Shell ที่มุมขวาบน

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-shop ใน 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 นาที คุณดำเนินการต่อได้ 2-3 ขั้นตอนขณะระบบกำลังประมวลผลการตั้งค่า

../setup.sh

3. สร้างแอปพลิเคชันเริ่มต้นสำหรับ Python ใหม่

  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 ให้คุณโหลดการเปลี่ยนแปลงโค้ดซ้ำโดยอัตโนมัติในแอปขวดแก้ว Python Dockerfile นี้อนุญาตให้คุณส่งค่านี้เป็นอาร์กิวเมนต์ของบิลด์

สร้างไฟล์ Manifest

ในเทอร์มินัลให้เรียกใช้คำสั่งต่อไปนี้เพื่อสร้าง skaffold.yaml และDeployment.yaml เริ่มต้น

  1. เริ่มต้น Skaffold ด้วยคำสั่งต่อไปนี้
skaffold init --generate-manifests

เมื่อได้รับข้อความแจ้ง ให้ใช้ลูกศรเพื่อเลื่อนเคอร์เซอร์ และแป้นเว้นวรรคเพื่อเลือกตัวเลือก

เลือก:

  • 8080 สำหรับพอร์ต
  • yเพื่อบันทึกการกำหนดค่า

อัปเดตการกำหนดค่า Skaffold

  • เปลี่ยนชื่อแอปพลิเคชันเริ่มต้น
  • เปิด skaffold.yaml
  • เลือกชื่อรูปภาพที่ตั้งเป็น dockerfile-image ในปัจจุบัน
  • คลิกขวาและเลือกเปลี่ยนรายการทั้งหมด
  • พิมพ์ชื่อใหม่เป็น 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 ในปัจจุบัน
  • คลิกขวาและเลือกเปลี่ยนรายการทั้งหมด
  • พิมพ์ชื่อใหม่เป็น python-app

4. แนะนำกระบวนการพัฒนา

เราได้เพิ่มตรรกะทางธุรกิจเข้าไปทำให้ติดตั้งใช้งานและทดสอบแอปพลิเคชันได้แล้ว ส่วนต่อไปนี้จะไฮไลต์การใช้ปลั๊กอิน Cloud Code นอกจากนี้ ปลั๊กอินนี้จะทำงานร่วมกับ Skaffold เพื่อช่วยให้ขั้นตอนการพัฒนามีประสิทธิภาพมากขึ้น เมื่อคุณทำให้ GKE ใช้งานได้ในขั้นตอนต่อไปนี้ Cloud Code และ Skaffold จะสร้างอิมเมจคอนเทนเนอร์โดยอัตโนมัติ จากนั้นพุชไปยัง Container Registry จากนั้นทำให้แอปพลิเคชันของคุณใช้งานได้บน GKE กรณีนี้จะเกิดขึ้นในเบื้องหลังโดยดึงรายละเอียดออกจากขั้นตอนของนักพัฒนาซอฟต์แวร์

ทำให้ใช้งานได้กับ Kubernetes

  1. ในแผงที่ด้านล่างของ Cloud Shell Editor ให้เลือก Cloud Code

fdc797a769040839.png

  1. ในแผงที่ปรากฏด้านบน ให้เลือกเรียกใช้บน Kubernetes หากได้รับข้อความแจ้ง ให้เลือกใช่เพื่อใช้บริบท Kubernetes ปัจจุบัน

cfce0d11ef307087.png

คำสั่งนี้จะเริ่มต้นบิลด์ของซอร์สโค้ดแล้วทำการทดสอบ บิลด์และการทดสอบจะใช้เวลา 2-3 นาที การทดสอบเหล่านี้ประกอบด้วยการทดสอบ 1 หน่วยและขั้นตอนการตรวจสอบซึ่งจะตรวจสอบกฎที่ตั้งไว้สำหรับสภาพแวดล้อมการติดตั้งใช้งาน มีการกำหนดค่าขั้นตอนการตรวจสอบความถูกต้องนี้แล้ว เพื่อให้แน่ใจว่าคุณจะได้รับคำเตือนเกี่ยวกับปัญหาการทำให้ใช้งานได้แม้ว่าคุณยังคงทำงานในสภาพแวดล้อมการพัฒนาของคุณ

  1. ครั้งแรกที่คุณเรียกใช้คำสั่ง ระบบจะแสดงข้อความแจ้งที่ด้านบนของหน้าจอเพื่อถามว่าคุณต้องการบริบท Kubernetes ปัจจุบันหรือไม่ ให้เลือก "ใช่" เพื่อยอมรับและใช้บริบทปัจจุบัน
  2. ต่อไปจะมีข้อความแจ้งถามว่าจะใช้รีจิสทรีคอนเทนเนอร์ใด กด Enter เพื่อยอมรับค่าเริ่มต้นที่ระบุ
  3. เลือกแท็บเอาต์พุตในแผงด้านล่างเพื่อดูความคืบหน้าและการแจ้งเตือน

f95b620569ba96c5.png

  1. เลือก "Kubernetes: เรียกใช้/แก้ไขข้อบกพร่อง - แบบละเอียด" ในเมนูแบบเลื่อนลงของช่องทางด้านขวาเพื่อดูรายละเอียดเพิ่มเติม และบันทึกที่สตรีมแบบสดจากคอนเทนเนอร์

94acdcdda6d2108.png

เมื่อบิลด์และทดสอบเสร็จสิ้น แท็บเอาต์พุตจะแสดงข้อความ: Attached debugger to container "python-app-8476f4bbc-h6dsl" successfully. และ URL http://localhost:8080 จะแสดงอยู่ในรายการ

  1. ในเทอร์มินัล Cloud Code ให้วางเมาส์เหนือ URL แรกในเอาต์พุต (http://localhost:8080) แล้วเลือก "เปิดตัวอย่างเว็บ" ในเคล็ดลับเครื่องมือที่ปรากฏขึ้น
  2. แท็บเบราว์เซอร์ใหม่จะเปิดขึ้นและแสดงข้อความ Hello, World!

โหลดซ้ำแบบ Hot

  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. ไปที่มุมมองการแก้ไขข้อบกพร่องและหยุดชุดข้อความปัจจุบัน 647213126d7a4c7b.png
  2. คลิกที่ Cloud Code ในเมนูด้านล่างและเลือก Debug on Kubernetes เพื่อเรียกใช้แอปพลิเคชันในโหมด debug
  • ในมุมมอง Kubernetes Run/Debug - Detailed ของหน้าต่าง Output โปรดสังเกตว่า Skaffold จะทำให้แอปพลิเคชันนี้ใช้งานได้ในโหมดแก้ไขข้อบกพร่อง
  1. เมื่อเรียกใช้เป็นครั้งแรก ข้อความแจ้งจะถามว่าแหล่งที่มาอยู่ภายในคอนเทนเนอร์ที่ใด ค่านี้เกี่ยวข้องกับไดเรกทอรีใน Dockerfile

กด Enter เพื่อยอมรับค่าเริ่มต้น

583436647752e410.png

การสร้างและทำให้ใช้งานได้ของแอปพลิเคชันจะใช้เวลา 2-3 นาที

  1. เมื่อกระบวนการเสร็จสมบูรณ์ คุณจะเห็นโปรแกรมแก้ไขข้อบกพร่องแนบอยู่
Port forwarding pod/python-app-8bd64cf8b-cskfl in namespace default, remote port 5678 -> http://127.0.0.1:5678
  1. แถบสถานะด้านล่างจะเปลี่ยนสีจากสีน้ำเงินเป็นสีส้มซึ่งแสดงว่าอยู่ในโหมดแก้ไขข้อบกพร่อง
  2. ในมุมมอง Kubernetes Run/Debug โปรดสังเกตว่าคอนเทนเนอร์ที่แก้ไขข้อบกพร่องได้เริ่มทำงานแล้ว
**************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. คลิกลงในส่วน "ตัวแปร"
  6. คลิก "ในเครื่อง" แล้วคุณจะพบตัวแปร "message"
  7. ดับเบิลคลิกชื่อตัวแปร "message" และเปลี่ยนค่าเป็นอย่างอื่น เช่น "Greetings from Python" ในป๊อปอัป
  8. คลิกปุ่ม "ดำเนินการต่อ" ในแผงควบคุมการแก้ไขข้อบกพร่อง 607c33934f8d6b39.png
  9. ตรวจสอบคำตอบในเบราว์เซอร์ ซึ่งตอนนี้จะแสดงค่าที่อัปเดตที่คุณเพิ่งป้อน
  10. หยุด "แก้ไขข้อบกพร่อง" โดยกดปุ่มหยุด 647213126d7a4c7b.png และนำเบรกพอยท์ออกโดยคลิกที่เบรกพอยท์อีกครั้ง

5. การพัฒนาบริการ CRUD REST แบบง่ายๆ

ณ จุดนี้ แอปพลิเคชันของคุณได้รับการกำหนดค่าสำหรับการพัฒนาที่สร้างโดยใช้คอนเทนเนอร์เสร็จสมบูรณ์แล้ว และคุณได้แนะนำเวิร์กโฟลว์การพัฒนาขั้นพื้นฐานด้วย Cloud Code แล้ว ในส่วนต่อไปนี้ คุณจะได้ฝึกฝนสิ่งที่ได้เรียนรู้ด้วยการเพิ่มปลายทางของบริการ REST ที่เชื่อมต่อกับฐานข้อมูลที่มีการจัดการใน Google Cloud

เขียนโค้ดบริการที่เหลือ

โค้ดด้านล่างจะสร้างบริการพักพื้นฐานที่ใช้ 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 อย่างปลอดภัย ให้ตั้งค่าแอปพลิเคชันให้ใช้ข้อมูลระบุตัวตนของภาระงาน วิธีนี้ทำให้แอปพลิเคชันของคุณทำหน้าที่เป็นบัญชีบริการของตนเองและมีสิทธิ์แต่ละรายการเมื่อเข้าถึงฐานข้อมูล

  1. อัปเดต deployment.yaml เพิ่มโค้ดต่อไปนี้ต่อท้ายไฟล์ (ดูให้แน่ใจว่ามีการเยื้องแท็บในตัวอย่างด้านล่าง)
      serviceAccountName: python-ksa
      nodeSelector:
        iam.gke.io/gke-metadata-server-enabled: "true" 

ทำให้แอปพลิเคชันใช้งานได้และตรวจสอบ

  1. ในบานหน้าต่างที่ด้านล่างของ Cloud Shell Editor ให้เลือก Cloud Code จากนั้นเลือก Debug on Kubernetes ที่ด้านบนของหน้าจอ
  2. เมื่อบิลด์และทดสอบเสร็จสิ้น แท็บเอาต์พุตจะระบุว่า Resource deployment/python-app status completed successfully และ URL ที่ส่งต่อจากบริการ Python-app: http://localhost:8080 จะแสดงขึ้น"
  3. เพิ่ม 2 รายการ

เรียกใช้คำสั่งด้านล่างจากเทอร์มินัล cloudshell Terminal

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. ทดสอบการลบ: ตอนนี้ให้ลองลบรายการโดยเรียกใช้คำสั่งต่อไปนี้ เปลี่ยนค่าของรหัสสินค้า หากจำเป็น
curl -X DELETE http://localhost:8080/singer?singer_id=6
    This throws an error message
500 Internal Server Error

ระบุและแก้ไขปัญหา

  1. โหมดแก้ไขข้อบกพร่องและค้นหาปัญหา มาดูเคล็ดลับบางส่วนกัน
  • เราทราบว่ามีบางอย่างผิดพลาดกับ DELETE เนื่องจากไม่มีการแสดงผลลัพธ์ที่ต้องการ ดังนั้นคุณจะตั้งค่าเบรกพอยท์ใน app.py ในเมธอด delete_singer
  • เรียกใช้การดำเนินการทีละขั้นตอน และดูตัวแปรในแต่ละขั้นตอนเพื่อสังเกตค่าของตัวแปรภายในในหน้าต่างด้านซ้าย
  • หากต้องการสังเกตค่าที่เฉพาะเจาะจง เช่น singer_id และ request.args ในส่วน "เพิ่มตัวแปรเหล่านี้" ลงในหน้าต่าง "ดู"
  1. โปรดสังเกตว่าค่าที่กําหนดให้กับ singer_id คือ None โปรดเปลี่ยนโค้ดเพื่อแก้ไขปัญหา

ข้อมูลโค้ดที่แก้ไขแล้วจะมีลักษณะดังนี้

@app.route('/delete-singer', methods=['DELETE', 'GET'])
def delete_singer():
    try:
        singer_id = request.args.get('singer_id')
  1. เมื่อรีสตาร์ทแอปพลิเคชันแล้ว ให้ทดสอบอีกครั้งโดยพยายามลบ
  2. หยุดเซสชันการแก้ไขข้อบกพร่องโดยคลิกสี่เหลี่ยมจัตุรัสสีแดงในแถบเครื่องมือแก้ไขข้อบกพร่อง 647213126d7a4c7b.png

6. ล้างข้อมูล

ยินดีด้วย ในห้องทดลองนี้ คุณได้สร้างแอปพลิเคชัน Python ใหม่ตั้งแต่ต้นและกำหนดค่าให้ทำงานกับคอนเทนเนอร์ได้อย่างมีประสิทธิภาพ จากนั้นคุณได้ทำให้แอปพลิเคชันใช้งานได้และแก้ไขข้อบกพร่องของแอปพลิเคชันไปยังคลัสเตอร์ GKE ระยะไกลตามกระบวนการของนักพัฒนาซอฟต์แวร์เดียวกันที่พบในสแต็กแอปพลิเคชันแบบดั้งเดิมแล้ว

วิธีทำความสะอาดหลังจบห้องทดลอง

  1. ลบไฟล์ที่ใช้ในห้องทดลอง
cd ~ && rm -rf container-developer-workshop
  1. ลบโปรเจ็กต์เพื่อนำโครงสร้างพื้นฐานและทรัพยากรที่เกี่ยวข้องทั้งหมดออก