การเชื่อมต่อ Cloud Spanner กับ GKE Autopilot

1. บทนำ

Cloud Spanner เป็นบริการฐานข้อมูลเชิงสัมพันธ์ที่รองรับการปรับขนาดในวงกว้างและกระจายไปทั่วโลกที่มีการจัดการครบวงจร ซึ่งมอบธุรกรรม ACID และความหมายของ SQL โดยไม่สูญเสียประสิทธิภาพการทำงานและความพร้อมใช้งานสูง

GKE Autopilot คือโหมดการดำเนินงานใน GKE ที่ Google จัดการการกำหนดค่าคลัสเตอร์ของคุณ รวมถึงโหนด การปรับขนาด ความปลอดภัย และการตั้งค่าที่กำหนดค่าไว้ล่วงหน้าอื่นๆ ให้เป็นไปตามแนวทางปฏิบัติแนะนำ ตัวอย่างเช่น GKE Autopilot จะเปิดใช้ Workload Identity เพื่อจัดการสิทธิ์ของบริการ

เป้าหมายของ Lab นี้คือการแนะนำกระบวนการเชื่อมต่อบริการแบ็กเอนด์หลายรายการที่ทำงานบน GKE Autopilot กับฐานข้อมูล Cloud Spanner

3d810aa9ec80a271.png

ในห้องทดลองนี้ คุณจะต้องตั้งค่าโปรเจ็กต์และเปิดใช้ Cloud Shell ก่อน จากนั้นคุณจะทำให้โครงสร้างพื้นฐานใช้งานได้โดยใช้ Terraform

เมื่อการดำเนินการนี้เสร็จสิ้น คุณจะโต้ตอบกับ Cloud Build และ Cloud Deploy เพื่อทำการย้ายข้อมูลสคีมาเริ่มต้นสำหรับฐานข้อมูลเกม ทำให้บริการแบ็กเอนด์ใช้งานได้ จากนั้นทำให้ภาระงานใช้งานได้

บริการใน Codelab นี้เหมือนกันจาก Codelab ของการเริ่มต้นใช้งาน Cloud Spanner กับการพัฒนาเกม การดำเนินการผ่าน Codelab ไม่ได้มีขึ้นเพื่อให้บริการทำงานบน GKE และเชื่อมต่อกับ Spanner ได้ แต่หากคุณต้องการรายละเอียดเพิ่มเติมเกี่ยวกับบริการเหล่านั้นที่สามารถใช้กับ Spanner ได้ ให้ลองดู

เมื่อภาระงานและบริการแบ็กเอนด์ทำงานอยู่ คุณจะเริ่มสร้างภาระงานและสังเกตการณ์ว่าบริการทำงานร่วมกันอย่างไร

ขั้นตอนสุดท้าย คุณจะล้างทรัพยากรที่สร้างขึ้นในห้องทดลองนี้

สิ่งที่คุณจะสร้าง

ในห้องทดลองนี้ คุณจะทำสิ่งต่อไปนี้ได้

  • การจัดสรรโครงสร้างพื้นฐานโดยใช้ Terraform
  • สร้างสคีมาฐานข้อมูลโดยใช้ขั้นตอนการย้ายข้อมูลสคีมาใน Cloud Build
  • ติดตั้งใช้งานบริการแบ็กเอนด์ของ Golang ทั้ง 4 รายการที่ใช้ประโยชน์จาก Workload Identity เพื่อเชื่อมต่อกับ Cloud Spanner
  • ทำให้บริการภาระงาน 4 รายการซึ่งใช้เพื่อจำลองภาระงานสำหรับบริการแบ็กเอนด์ใช้งานได้

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

  • วิธีจัดสรรไปป์ไลน์ GKE Autopilot, Cloud Spanner และ Cloud Deploy โดยใช้ Terraform
  • วิธีที่ Workload Identity อนุญาตให้บริการบน GKE เลียนแบบบัญชีบริการเพื่อเข้าถึงสิทธิ์ IAM เพื่อทำงานกับ Cloud Spanner
  • วิธีสร้างโหลดที่คล้ายกับการใช้งานจริงบน GKE และ Cloud Spanner โดยใช้ Locust.io

สิ่งที่คุณต้องมี

  • โปรเจ็กต์ Google Cloud ที่เชื่อมต่อกับบัญชีสำหรับการเรียกเก็บเงิน
  • เว็บเบราว์เซอร์ เช่น Chrome หรือ Firefox

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

สร้างโปรเจ็กต์

หากยังไม่มีบัญชี Google (Gmail หรือ Google Apps) คุณต้องสร้างบัญชีก่อน ลงชื่อเข้าใช้คอนโซล Google Cloud Platform ( console.cloud.google.com) และสร้างโปรเจ็กต์ใหม่

หากคุณมีโปรเจ็กต์อยู่แล้ว ให้คลิกเมนูแบบเลื่อนลงสำหรับการเลือกโปรเจ็กต์ที่ด้านซ้ายบนของคอนโซล

6c9406d9b014760.png

และคลิก "โครงการใหม่" ในกล่องโต้ตอบที่ปรากฏขึ้นเพื่อสร้างโปรเจ็กต์ใหม่ ดังนี้

949d83c8a4ee17d9.png

หากคุณยังไม่มีโปรเจ็กต์ คุณจะเห็นกล่องโต้ตอบลักษณะนี้ให้สร้างโปรเจ็กต์แรก

870a3cbd6541ee86.png

กล่องโต้ตอบการสร้างโปรเจ็กต์ที่ตามมาจะให้คุณป้อนรายละเอียดของโปรเจ็กต์ใหม่:

6a92c57d3250a4b3.png

จดจำรหัสโปรเจ็กต์ ซึ่งเป็นชื่อที่ไม่ซ้ำกันในโปรเจ็กต์ Google Cloud ทั้งหมด (ระบบใช้ชื่อด้านบนนี้ไปแล้ว และจะใช้ไม่ได้ ขออภัย) และจะมีการอ้างอิงใน Codelab ว่า PROJECT_ID ในภายหลัง

ขั้นตอนถัดไป คุณจะต้องเปิดใช้การเรียกเก็บเงินใน Developers Console เพื่อใช้ทรัพยากร Google Cloud และเปิดใช้ Cloud Spanner API หากยังไม่ได้ดำเนินการ

15d0ef27a8fbab27.png

การใช้งาน Codelab นี้น่าจะมีค่าใช้จ่ายไม่เกิน 2-3 ดอลลาร์ แต่อาจมากกว่านี้หากคุณตัดสินใจใช้ทรัพยากรเพิ่มหรือปล่อยให้ทำงาน (ดูส่วน "ล้างข้อมูล" ในตอนท้ายของเอกสารนี้) ดูราคาของ Google Cloud Spanner ได้ที่นี่ และ GKE Autopilot ได้รับการบันทึกไว้ที่นี่

ผู้ใช้ใหม่ของ Google Cloud Platform จะมีสิทธิ์ทดลองใช้ฟรี$300 ซึ่งจะทำให้ Codelab นี้ไม่มีค่าใช้จ่ายทั้งหมด

การตั้งค่า Cloud Shell

แม้ว่า Google Cloud และ Spanner จะทำงานจากระยะไกลได้จากแล็ปท็อป แต่ใน Codelab นี้ เราจะใช้ Google Cloud Shell ซึ่งเป็นสภาพแวดล้อมแบบบรรทัดคำสั่งที่ทำงานในระบบคลาวด์

เครื่องเสมือนแบบ Debian นี้เต็มไปด้วยเครื่องมือการพัฒนาทั้งหมดที่คุณต้องการ โดยมีไดเรกทอรีหลักขนาด 5 GB ที่ทำงานอย่างต่อเนื่องใน Google Cloud ซึ่งจะช่วยเพิ่มประสิทธิภาพของเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก ซึ่งหมายความว่าสิ่งที่คุณต้องมีสำหรับ Codelab นี้คือเบราว์เซอร์ (ใช่แล้ว ทั้งหมดนี้ทำงานได้บน Chromebook)

  1. หากต้องการเปิดใช้งาน Cloud Shell จาก Cloud Console เพียงคลิกเปิดใช้งาน Cloud Shell gcLMt5IuEcJJNnMId-Bcz3sxCd0rZn7IzT_r95C8UZeqML68Y1efBG_B0VRp7hc7qiZTLAF-TXD7SsOadxn8uadgHhaLeASnVS3ZHK39eOlKJOgj9SJua_oeGhMxRrbOg3qigddS2A (การจัดสรรและเชื่อมต่อกับสภาพแวดล้อมซึ่งจะใช้เวลาเพียงไม่นาน)

JjEuRXGg0AYYIY6QZ8d-66gx_Mtc-_jDE9ijmbXLJSAXFvJt-qUpNtsBsYjNpv2W6BQSrDc1D-ARINNQ-1EkwUhz-iUK-FUCZhJ-NtjvIEx9pIkE-246DomWuCfiGHK78DgoeWkHRw

Screen Shot 14-06-2017 เวลา 22.13.43 น.

เมื่อเชื่อมต่อกับ Cloud Shell คุณควรเห็นว่าตนเองผ่านการตรวจสอบสิทธิ์แล้วและโปรเจ็กต์ได้รับการตั้งค่าเป็น PROJECT_ID แล้ว

gcloud auth list

เอาต์พุตจากคำสั่ง

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

เอาต์พุตจากคำสั่ง

[core]
project = <PROJECT_ID>

หากโปรเจ็กต์ไม่ได้ตั้งค่าไว้ด้วยเหตุผลบางประการ ให้ใช้คำสั่งต่อไปนี้

gcloud config set project <PROJECT_ID>

กำลังมองหา PROJECT_ID ของคุณอยู่ใช่ไหม ตรวจสอบรหัสที่คุณใช้ในขั้นตอนการตั้งค่าหรือดูในแดชบอร์ด Cloud Console

158fNPfwSxsFqz9YbtJVZes8viTS3d1bV4CVhij3XPxuzVFOtTObnwsphlm6lYGmgdMFwBJtc-FaLrZU7XHAg_ZYoCrgombMRR3h-eolLPcvO351c5iBv506B3ZwghZoiRg6cz23Qw

Cloud Shell ยังตั้งค่าตัวแปรสภาพแวดล้อมโดยค่าเริ่มต้นด้วย ซึ่งอาจเป็นประโยชน์เมื่อคุณเรียกใช้คำสั่งในอนาคต

echo $GOOGLE_CLOUD_PROJECT

เอาต์พุตจากคำสั่ง

<PROJECT_ID>

ดาวน์โหลดโค้ด

ใน Cloud Shell คุณสามารถดาวน์โหลดโค้ดสำหรับห้องทดลองนี้ได้

git clone https://github.com/cloudspannerecosystem/spanner-gaming-sample.git

เอาต์พุตจากคำสั่ง

Cloning into 'spanner-gaming-sample'...
*snip*

Codelab นี้อิงตามรุ่น v0.1.3 ดังนั้นโปรดตรวจสอบแท็กดังกล่าว ดังนี้

cd spanner-gaming-sample
git fetch --all --tags

# Check out v0.1.3 release
git checkout tags/v0.1.3 -b v0.1.3-branch

เอาต์พุตจากคำสั่ง

Switched to a new branch 'v0.1.3-branch'

ตอนนี้ให้ตั้งค่าไดเรกทอรีการทำงานปัจจุบันเป็นตัวแปรสภาพแวดล้อม DEMO_HOME วิธีนี้จะช่วยให้ไปยังส่วนต่างๆ ได้ง่ายขึ้นเมื่อคุณทำงานในส่วนต่างๆ ของ Codelab

export DEMO_HOME=$(pwd)

สรุป

ในขั้นตอนนี้ คุณได้ตั้งค่าโปรเจ็กต์ใหม่ เปิดใช้งาน Cloud Shell และดาวน์โหลดโค้ดสำหรับห้องทดลองนี้แล้ว

รายการถัดไป

ต่อไป คุณจะจัดสรรโครงสร้างพื้นฐานโดยใช้ Terraform

3. โครงสร้างพื้นฐานสำหรับการจัดสรร

ภาพรวม

เมื่อโปรเจ็กต์พร้อมแล้ว ก็ถึงเวลาใช้งานโครงสร้างพื้นฐาน ซึ่งรวมถึงเครือข่าย VPC, Cloud Spanner, GKE Autopilot, Artifact Registry ที่จะจัดเก็บอิมเมจที่จะเรียกใช้บน GKE, ไปป์ไลน์ Cloud Deploy สำหรับบริการแบ็กเอนด์และภาระงาน และสุดท้ายคือบัญชีบริการและสิทธิ์ IAM ที่จะใช้บริการเหล่านั้นได้

เยอะมากๆ แต่โชคดีที่ Terraform สามารถทำให้การตั้งค่าง่ายขึ้น Terraform เป็น "Infrastructure as Code" ที่ทำให้เราสามารถระบุสิ่งที่เราต้องการสำหรับโครงการนี้เป็นชุด ".tf" วิธีนี้ทำให้การจัดสรรโครงสร้างพื้นฐานเป็นเรื่องง่าย

คุณไม่จำเป็นต้องทำความคุ้นเคยกับ Terraform ในการทำ Codelab นี้ แต่หากต้องการดูขั้นตอนถัดไปที่ต้องดำเนินการ คุณสามารถดูสิ่งที่ระบบสร้างทั้งหมดในไฟล์เหล่านี้ได้ในไดเรกทอรีโครงสร้างพื้นฐาน

  • vpc.tf
  • backend_gke.tf
  • spanner.tf
  • artifact_registry.tf
  • pipelines.tf
  • iam.tf

กำหนดค่า Terraform

ใน Cloud Shell คุณจะต้องเปลี่ยนเป็นไดเรกทอรี infrastructure และเริ่มต้น Terraform:

cd $DEMO_HOME/infrastructure
terraform init

เอาต์พุตจากคำสั่ง

Initializing the backend...

Initializing provider plugins...
*snip*
Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

ถัดไป ให้กำหนดค่า Terraform โดยการคัดลอก terraform.tfvars.sample และแก้ไขค่าของโปรเจ็กต์ ตัวแปรอื่นๆ สามารถเปลี่ยนแปลงได้เช่นกัน แต่มีเพียงโปรเจ็กต์เดียวที่ต้องเปลี่ยนแปลงเพื่อให้เหมาะกับสภาพแวดล้อมของคุณ

cp  terraform.tfvars.sample terraform.tfvars
# edit gcp_project using the project environment variable
sed -i "s/PROJECT/$GOOGLE_CLOUD_PROJECT/" terraform.tfvars

การจัดสรรโครงสร้างพื้นฐาน

ตอนนี้ได้เวลาจัดสรรโครงสร้างพื้นฐานแล้ว!

terraform apply
# review the list of things to be created
# type 'yes' when asked

เอาต์พุตจากคำสั่ง

Plan: 46 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

google_project_service.project["container.googleapis.com"]: Creating...
*snip*
Apply complete! Resources: 46 added, 0 changed, 0 destroyed.

ตรวจสอบสิ่งที่สร้าง

หากต้องการยืนยันสิ่งที่สร้างขึ้น คุณจะต้องตรวจสอบผลิตภัณฑ์ใน Cloud Console

Cloud Spanner

ขั้นแรก ให้ตรวจสอบ Cloud Spanner โดยไปที่เมนูแฮมเบอร์เกอร์แล้วคลิก Spanner คุณอาจต้องคลิก "ดูผลิตภัณฑ์เพิ่มเติม" เพื่อหาในลิสต์

ซึ่งจะนำคุณไปยังรายการอินสแตนซ์ Spanner คลิกเข้าไปในอินสแตนซ์และคุณจะเห็นฐานข้อมูล ซึ่งควรมีหน้าตาเช่นนี้

10b7fc0c4a86c59.png

GKE Autopilot

ต่อไปให้ลองใช้ GKE โดยไปที่เมนูแฮมเบอร์เกอร์แล้วคลิก Kubernetes Engine => Clusters คุณจะเห็นคลัสเตอร์ sample-games-gke ทำงานในโหมด Autopilot ที่นี่

9cecb1a702e6b7ff.png

Artifact Registry

ทีนี้คุณจะต้องดูว่าระบบจะเก็บรูปภาพไว้ที่ไหน คลิกเมนู 3 ขีด แล้วหา Artifact Registry=>Repositories Artifact Registry อยู่ในส่วน CI/CD ของเมนู

ตรงนี้คุณจะเห็นรีจิสทรี Docker ชื่อ spanner-game-images การดำเนินการนี้จะว่างเปล่าในขณะนี้

3f805eee312841b.png

Cloud Deploy

Cloud Deploy คือที่ที่สร้างไปป์ไลน์เพื่อให้ Cloud Build แสดงขั้นตอนในการสร้างอิมเมจและทำให้ใช้งานได้กับคลัสเตอร์ GKE ของเรา

ไปที่เมนูแฮมเบอร์เกอร์แล้วพบ Cloud Deploy ซึ่งอยู่ในส่วน CI/CD ของเมนูด้วย

ในส่วนนี้ คุณจะสังเกตเห็นไปป์ไลน์ 2 ส่วน ได้แก่ ส่วนแรกสำหรับบริการแบ็กเอนด์และอีก 1 ส่วนสำหรับภาระงาน ทั้ง 2 ผลิตภัณฑ์จะทำให้อิมเมจใช้งานได้ในคลัสเตอร์ GKE เดียวกัน แต่การดำเนินการนี้ช่วยให้แยกการทำให้ใช้งานได้ได้

d2e4a659145ddf5e.png

IAM

สุดท้ายให้ตรวจสอบหน้า IAM ใน Cloud Console เพื่อยืนยันบัญชีบริการที่สร้างขึ้น ไปที่เมนูแฮมเบอร์เกอร์แล้วพบ IAM and Admin=>Service accounts ซึ่งควรมีหน้าตาเช่นนี้

bed3d1af94974916.png

มีบัญชีบริการทั้งหมด 6 บัญชีที่สร้างโดย terform ดังนี้

  • บัญชีบริการคอมพิวเตอร์เริ่มต้น ไม่ได้ใช้ใน Codelab นี้
  • บัญชี Cloudbuild-cicd ใช้สำหรับขั้นตอน Cloud Build และ Cloud Deployment
  • 4 "แอป" บัญชีที่ใช้โดยบริการแบ็กเอนด์ของเราเพื่อโต้ตอบกับ Cloud Spanner

ถัดไป คุณจะต้องกำหนดค่า kubectl เพื่อโต้ตอบกับคลัสเตอร์ GKE

กำหนดค่า kubectl

# Name of GKE cluster from terraform.tfvars file
export GKE_CLUSTER=sample-game-gke 

# get GKE credentials
gcloud container clusters get-credentials $GKE_CLUSTER --region us-central1

# Check that no errors occur
kubectl get serviceaccounts

เอาต์พุตจากคำสั่ง

#export GKE_CLUSTER=sample-game-gke

# gcloud container clusters get-credentials $GKE_CLUSTER --region us-central1
Fetching cluster endpoint and auth data.
kubeconfig entry generated for sample-game-gke.

# kubectl get serviceaccounts
NAME              SECRETS   AGE
default           0         37m
item-app          0         35m
matchmaking-app   0         35m
profile-app       0         35m
tradepost-app     0         35m

สรุป

เยี่ยม! คุณจัดสรรอินสแตนซ์ Cloud Spanner ซึ่งเป็นคลัสเตอร์ GKE Autopilot ทั้งหมดใน VPC สำหรับเครือข่ายส่วนตัวได้

นอกจากนี้ ยังมีการสร้างไปป์ไลน์ Cloud Deploy 2 รายการสำหรับบริการแบ็กเอนด์และภาระงาน รวมถึงที่เก็บ Artifact Registry เพื่อจัดเก็บอิมเมจที่สร้างขึ้น

และสุดท้าย บัญชีบริการถูกสร้างขึ้นและกำหนดค่าให้ทำงานร่วมกับ Workload Identity เพื่อให้บริการแบ็กเอนด์ใช้ Cloud Spanner ได้

คุณยังได้กำหนดค่า kubectl ให้โต้ตอบกับคลัสเตอร์ GKE ใน Cloud Shell หลังจากที่ทำให้บริการแบ็กเอนด์และภาระงานใช้งานได้

รายการถัดไป

คุณต้องกำหนดสคีมาฐานข้อมูลก่อนจึงจะใช้บริการได้ คุณจะได้ตั้งค่าในลำดับต่อไป

4. สร้างสคีมาฐานข้อมูล

ภาพรวม

ก่อนที่จะเรียกใช้บริการแบ็กเอนด์ได้ คุณต้องตรวจสอบว่าสคีมาฐานข้อมูลพร้อมใช้งานแล้ว

หากดูไฟล์ในไดเรกทอรี $DEMO_HOME/schema/migrations จากที่เก็บเดโม คุณจะเห็นชุดไฟล์ .sql ที่ระบุสคีมาของเรา ซึ่งจะเลียนแบบวงจรการพัฒนาที่มีการติดตามการเปลี่ยนแปลงสคีมาในที่เก็บ และอาจเชื่อมโยงกับฟีเจอร์บางอย่างของแอปพลิเคชัน

สำหรับสภาพแวดล้อมตัวอย่างนี้ เครื่องมือคือเครื่องมือที่จะใช้การย้ายข้อมูลสคีมาของเราโดยใช้ Cloud Build

Cloud Build

ไฟล์ $DEMO_HOME/schema/cloudbuild.yaml จะอธิบายขั้นตอนที่ต้องดำเนินการ ดังนี้

serviceAccount: projects/${PROJECT_ID}/serviceAccounts/cloudbuild-cicd@${PROJECT_ID}.iam.gserviceaccount.com
steps:
- name: gcr.io/cloud-builders/curl
 id: fetch-wrench
 args: ['-Lo', '/workspace/wrench.tar.gz', 'https://github.com/cloudspannerecosystem/wrench/releases/download/v1.4.1/wrench-1.4.1-linux-amd64.tar.gz' ]

- name: gcr.io/cloud-builders/gcloud
 id: migrate-spanner-schema
 entrypoint: sh
 args:
 - '-xe'
 - '-c'
 - |
   tar -xzvf wrench.tar.gz

   chmod +x /workspace/wrench

   # Assumes only a single spanner instance and database. Fine for this demo in a dedicated project
   export SPANNER_PROJECT_ID=${PROJECT_ID}
   export SPANNER_INSTANCE_ID=$(gcloud spanner instances list | tail -n1 | awk '{print $1}')
   export SPANNER_DATABASE_ID=$(gcloud spanner databases list --instance=$$SPANNER_INSTANCE_ID | tail -n1 | awk '{print $1}')

   if [ -d ./migrations ]; then
     /workspace/wrench migrate up --directory .
   else
     echo "[Error] Missing migrations directory"
   fi
timeout: 600s

โดยมี 2 ขั้นตอนดังนี้

  • ดาวน์โหลดเครื่องมือไปยังพื้นที่ทำงาน Cloud Build
  • เรียกใช้การย้ายข้อมูลเครื่องมือ

จำเป็นต้องมีโปรเจ็กต์ Spanner, อินสแตนซ์ และตัวแปรสภาพแวดล้อมฐานข้อมูลเพื่อให้เครื่องมือเชื่อมต่อกับปลายทางการเขียน

Cloud Build ทำการเปลี่ยนแปลงเหล่านี้ได้เนื่องจากกำลังทำงานในฐานะบัญชีบริการ cloudbuild-cicd@${PROJECT_ID}.iam.gserviceaccount.com:

serviceAccount: projects/${PROJECT_ID}/serviceAccounts/cloudbuild-cicd@${PROJECT_ID}.iam.gserviceaccount.com

และบัญชีบริการนี้มีบทบาท spanner.databaseUser ที่เพิ่มโดย Terraform ซึ่งช่วยให้บัญชีบริการอัปเดต DDL ได้

การย้ายข้อมูลสคีมา

ขั้นตอนการย้ายข้อมูลมี 5 ขั้นตอน โดยอิงตามไฟล์ในไดเรกทอรี $DEMO_HOME/schema/migrations ต่อไปนี้คือตัวอย่างของไฟล์ 000001.sql ที่สร้างตารางและดัชนี players

CREATE TABLE players (
   playerUUID STRING(36) NOT NULL,
   player_name STRING(64) NOT NULL,
   email STRING(MAX) NOT NULL,
   password_hash BYTES(60) NOT NULL,
   created TIMESTAMP,
   updated TIMESTAMP,
   stats JSON,
   account_balance NUMERIC NOT NULL DEFAULT (0.00),
   is_logged_in BOOL,
   last_login TIMESTAMP,
   valid_email BOOL,
   current_game STRING(36)
) PRIMARY KEY (playerUUID);

CREATE UNIQUE INDEX PlayerAuthentication ON players(email) STORING(password_hash);
CREATE UNIQUE INDEX PlayerName ON players(player_name);
CREATE INDEX PlayerGame ON players(current_game);

ส่งการย้ายข้อมูลสคีมา

หากต้องการส่งบิลด์เพื่อย้ายข้อมูลสคีมา ให้เปลี่ยนไปใช้ไดเรกทอรี schema และเรียกใช้คำสั่ง gcloud ต่อไปนี้

cd $DEMO_HOME/schema
gcloud builds submit --config=cloudbuild.yaml

เอาต์พุตจากคำสั่ง

Creating temporary tarball archive of 8 file(s) totalling 11.2 KiB before compression.
Uploading tarball of [.] to [gs://(project)_cloudbuild/source/(snip).tgz]
Created [https://cloudbuild.googleapis.com/v1/projects/(project)/locations/global/builds/7defe982-(snip)].
Logs are available at [ https://console.cloud.google.com/cloud-build/builds/7defe982-(snip)?project=(snip) ].

gcloud builds submit only displays logs from Cloud Storage. To view logs from Cloud Logging, run:
gcloud beta builds submit

ID: 7defe982-(snip)
CREATE_TIME: (created time)
DURATION: 3M11S
SOURCE: gs://(project)_cloudbuild/source/(snip).tgz
IMAGES: -
STATUS: SUCCESS

ในเอาต์พุตด้านบน คุณจะเห็นลิงก์ไปยังกระบวนการบิลด์ในระบบคลาวด์ของ Created หากคลิก ระบบจะนำคุณไปยังบิลด์ใน Cloud Console เพื่อให้คุณตรวจสอบความคืบหน้าของบิลด์และดูว่ากำลังทำอะไรอยู่

11b1cf107876d797.png

สรุป

ในขั้นตอนนี้ คุณใช้ Cloud Build เพื่อส่งการย้ายข้อมูลสคีมาเริ่มต้นที่ใช้การดำเนินการ DDL ที่แตกต่างกัน 5 รายการ การดำเนินการเหล่านี้แสดงถึงเมื่อมีการเพิ่มฟีเจอร์ต่างๆ ซึ่งจำเป็นต้องเปลี่ยนแปลงสคีมาฐานข้อมูล

ในสถานการณ์การพัฒนาปกติ คุณจะต้องทำการเปลี่ยนแปลงสคีมาย้อนหลังที่เข้ากันได้กับแอปพลิเคชันปัจจุบันเพื่อหลีกเลี่ยงการหยุดทำงาน

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

รายการถัดไป

เมื่อมีสคีมาแล้ว ขั้นตอนต่อไปคือการทำให้บริการแบ็กเอนด์ใช้งานได้

5. ทำให้บริการแบ็กเอนด์ใช้งานได้

ภาพรวม

บริการแบ็กเอนด์สำหรับ Codelab นี้คือ Golang REST API ที่นำเสนอบริการ 4 ประเภทดังนี้

  • โปรไฟล์: ช่วยให้ผู้เล่นสามารถลงชื่อสมัครใช้และตรวจสอบสิทธิ์ของ "เกม" ตัวอย่างของเรา
  • การจับคู่ที่ตรงกัน: โต้ตอบกับข้อมูลผู้เล่นเพื่อช่วยในเรื่องฟังก์ชันการจับคู่ ติดตามข้อมูลเกี่ยวกับเกมที่สร้างขึ้น และอัปเดตสถิติผู้เล่นเมื่อเกมปิดลง
  • ไอเทม: ช่วยให้ผู้เล่นได้รับไอเทมในเกมและเงินผ่านการเล่นเกม
  • Tradepost: เปิดโอกาสให้ผู้เล่นซื้อและขายสินค้าตามผู้ค้า

d36e958411d44b5d.png

คุณดูข้อมูลเพิ่มเติมเกี่ยวกับบริการเหล่านี้ได้ใน Codelab ของการเริ่มต้นใช้งาน Cloud Spanner กับการพัฒนาเกม ตามวัตถุประสงค์ของเรา เราต้องการให้บริการเหล่านี้ทำงานบนคลัสเตอร์ GKE Autopilot ของเรา

บริการเหล่านี้ต้องแก้ไขข้อมูล Spanner ได้ ในการทำเช่นนั้น แต่ละบริการจะสร้างบัญชีบริการที่ให้สิทธิ์ "databaseUser"

Workload Identity อนุญาตให้บัญชีบริการ Kubernetes แอบอ้างเป็นบริการ บัญชีบริการระบบคลาวด์ของ Google โดยทำตามขั้นตอนต่อไปนี้ใน Terraform

  • สร้างทรัพยากรบัญชีบริการระบบคลาวด์ของ Google (GSA) ของบริการ
  • กำหนดบทบาท databaseUser ให้กับบัญชีบริการนั้น
  • มอบหมายบทบาท workloadIdentityUser ให้บัญชีบริการนั้น
  • สร้างบัญชีบริการ Kubernetes (KSA) ที่อ้างอิง GSA

แผนภาพคร่าวๆ จะมีลักษณะดังนี้

a8662d31d66b5910.png

terform สร้างบัญชีบริการและบัญชีบริการ Kubernetes ให้คุณ และคุณจะตรวจสอบบัญชีบริการ Kubernetes โดยใช้ kubectl ได้ด้วย โดยทำดังนี้

# kubectl get serviceaccounts
NAME              SECRETS   AGE
default           0         37m
item-app          0         35m
matchmaking-app   0         35m
profile-app       0         35m
tradepost-app     0         35m

วิธีการทำงานของบิลด์มีดังนี้

serviceAccount: projects/${PROJECT_ID}/serviceAccounts/cloudbuild-cicd@${PROJECT_ID}.iam.gserviceaccount.com
steps:

#
# Building of images
#
 - name: gcr.io/cloud-builders/docker
   id: profile
   args: ["build", ".", "-t", "${_PROFILE_IMAGE}"]
   dir: profile
   waitFor: ['-']
 - name: gcr.io/cloud-builders/docker
   id: matchmaking
   args: ["build", ".", "-t", "${_MATCHMAKING_IMAGE}"]
   dir: matchmaking
   waitFor: ['-']
 - name: gcr.io/cloud-builders/docker
   id: item
   args: ["build", ".", "-t", "${_ITEM_IMAGE}"]
   dir: item
   waitFor: ['-']
 - name: gcr.io/cloud-builders/docker
   id: tradepost
   args: ["build", ".", "-t", "${_TRADEPOST_IMAGE}"]
   dir: tradepost
   waitFor: ['-']

#
# Deployment
#
 - name: gcr.io/google.com/cloudsdktool/cloud-sdk
   id: cloud-deploy-release
   entrypoint: gcloud
   args:
     [
       "deploy", "releases", "create", "${_REL_NAME}",
       "--delivery-pipeline", "sample-game-services",
       "--skaffold-file", "skaffold.yaml",
       "--skaffold-version", "1.39",
       "--images", "profile=${_PROFILE_IMAGE},matchmaking=${_MATCHMAKING_IMAGE},item=${_ITEM_IMAGE},tradepost=${_TRADEPOST_IMAGE}",
       "--region", "us-central1"
     ]

artifacts:
 images:
   - ${_REGISTRY}/profile
   - ${_REGISTRY}/matchmaking
   - ${_REGISTRY}/item
   - ${_REGISTRY}/tradepost

substitutions:
 _PROFILE_IMAGE: ${_REGISTRY}/profile:${BUILD_ID}
 _MATCHMAKING_IMAGE: ${_REGISTRY}/matchmaking:${BUILD_ID}
 _ITEM_IMAGE: ${_REGISTRY}/item:${BUILD_ID}
 _TRADEPOST_IMAGE: ${_REGISTRY}/tradepost:${BUILD_ID}
 _REGISTRY: us-docker.pkg.dev/${PROJECT_ID}/spanner-game-images
 _REL_NAME: rel-${BUILD_ID:0:8}
options:
 dynamic_substitutions: true
 machineType: E2_HIGHCPU_8
 logging: CLOUD_LOGGING_ONLY
  • คำสั่ง Cloud Build จะอ่านไฟล์นี้และทำตามขั้นตอนที่ระบุไว้ ขั้นแรก โมเดลจะสร้างอิมเมจของบริการ จากนั้นจะเรียกใช้คำสั่ง gcloud deploy create โดยจะอ่านไฟล์ $DEMO_HOME/backend_services/skaffold.yaml ซึ่งระบุตำแหน่งของไฟล์การทำให้ใช้งานได้แต่ละไฟล์ ดังนี้
apiVersion: skaffold/v2beta29
kind: Config
deploy:
 kubectl:
   manifests:
     - spanner_config.yaml
     - profile/deployment.yaml
     - matchmaking/deployment.yaml
     - item/deployment.yaml
     - tradepost/deployment.yaml
  • Cloud Deployment จะทำตามคำจำกัดความของไฟล์ deployment.yaml ของแต่ละบริการ ไฟล์การติดตั้งใช้งานของบริการมีข้อมูลสำหรับการสร้างบริการ ซึ่งในกรณีนี้คือclusterIP ที่ทำงานอยู่ในพอร์ต 80

" ประเภท ClusterIP" ป้องกันไม่ให้พ็อดบริการแบ็กเอนด์มี IP ภายนอก ดังนั้นเฉพาะเอนทิตีที่สามารถเชื่อมต่อกับเครือข่าย GKE ภายในเท่านั้นที่สามารถเข้าถึงบริการแบ็กเอนด์ได้ ผู้เล่นไม่ควรเข้าถึงบริการเหล่านี้ได้โดยตรง เนื่องจากผู้เล่นจะเข้าถึงและแก้ไขข้อมูล Spanner

apiVersion: v1
kind: Service
metadata:
 name: profile
spec:
 type: ClusterIP
 selector:
   app: profile
 ports:
 - port: 80
   targetPort: 80

นอกเหนือจากการสร้างบริการ Kubernetes แล้ว Cloud Deployment ยังสร้างการติดตั้งใช้งาน Kubernetes อีกด้วย มาดูส่วนการทำให้ใช้งานได้ของบริการ profile กัน

---
apiVersion: apps/v1
kind: Deployment
metadata:
 name: profile
spec:
 replicas: 2 # EDIT: Number of instances of deployment
 selector:
   matchLabels:
     app: profile
 template:
   metadata:
     labels:
       app: profile
   spec:
     serviceAccountName: profile-app
     containers:
     - name: profile-service
       image: profile
       ports:
         - containerPort: 80
       envFrom:
         - configMapRef:
             name: spanner-config
       env:
         - name: SERVICE_HOST
           value: "0.0.0.0"
         - name: SERVICE_PORT
           value: "80"
       resources:
         requests:
           cpu: "1"
           memory: "1Gi"
           ephemeral-storage: "100Mi"
         limits:
           cpu: "1"
           memory: "1Gi"
           ephemeral-storage: "100Mi"

ส่วนด้านบนจะแสดงข้อมูลเมตาบางส่วนเกี่ยวกับบริการ สิ่งที่สำคัญที่สุดคือการกำหนดจำนวนตัวจำลองที่จะสร้างขึ้นด้วยการทำให้ใช้งานได้นี้

replicas: 2 # EDIT: Number of instances of deployment

ถัดไป เราจะดูว่าบัญชีบริการใดควรเรียกใช้แอปและรูปภาพใดควรใช้ รายการเหล่านี้ตรงกับบัญชีบริการ Kubernetes ที่สร้างจาก Terraform และอิมเมจที่สร้างขึ้นในขั้นตอน Cloud Build

spec:
  serviceAccountName: profile-app
  containers:
    - name: profile-service
      image: profile

หลังจากนั้น เราจะระบุข้อมูลบางอย่างเกี่ยวกับตัวแปรเครือข่ายและสภาพแวดล้อม

spanner_config คือ ConfigMap ของ Kubernetes ที่ระบุโปรเจ็กต์ อินสแตนซ์ และฐานข้อมูลที่จำเป็นสำหรับแอปพลิเคชันในการเชื่อมต่อกับ Spanner

apiVersion: v1
kind: ConfigMap
metadata:
  name: spanner-config
data:
  SPANNER_PROJECT_ID: ${project_id}
  SPANNER_INSTANCE_ID: ${instance_id}
  SPANNER_DATABASE_ID: ${database_id}
ports:
  - containerPort: 80
envFrom:
  - configMapRef:
    name: spanner-config
env:
  - name: SERVICE_HOST
    value: "0.0.0.0"
  - name: SERVICE_PORT
    value: "80"

SERVICE_HOST และ SERVICE_PORT เป็นตัวแปรสภาพแวดล้อมเพิ่มเติมที่บริการต้องใช้เพื่อให้ทราบตำแหน่งที่จะเชื่อมโยง

ส่วนสุดท้ายจะบอก GKE ถึงจำนวนทรัพยากรที่อนุญาตสำหรับตัวจำลองแต่ละรายการในการทำให้ใช้งานได้นี้ นอกจากนี้ GKE Autopilot ยังใช้เพื่อปรับขนาดคลัสเตอร์ตามความจำเป็นด้วย

resources:
  requests:
    cpu: "1"
    memory: "1Gi"
    ephemeral-storage: "100Mi"
  limits:
    cpu: "1"
    memory: "1Gi"
    ephemeral-storage: "100Mi"

เมื่อมีข้อมูลนี้ก็ถึงเวลาทำให้บริการแบ็กเอนด์ใช้งานได้

ทำให้บริการแบ็กเอนด์ใช้งานได้

ดังที่กล่าวไปแล้ว การทำให้บริการแบ็กเอนด์ใช้งานได้จะใช้ Cloud Build คุณส่งคำขอบิลด์ได้โดยใช้บรรทัดคำสั่ง gcloud เช่นเดียวกับการย้ายข้อมูลสคีมา ดังนี้

cd $DEMO_HOME/backend_services
gcloud builds submit --config=cloudbuild.yaml

เอาต์พุตจากคำสั่ง

Creating temporary tarball archive of 66 file(s) totalling 864.6 KiB before compression.
Uploading tarball of [.] to [gs://(project)_cloudbuild/source/(snip).tgz]
Created [https://cloudbuild.googleapis.com/v1/projects/(project)/locations/global/builds/30207dd1-(snip)].
Logs are available at [ https://console.cloud.google.com/cloud-build/builds/30207dd1-(snip)?project=(snip) ].

gcloud builds submit only displays logs from Cloud Storage. To view logs from Cloud Logging, run:
gcloud beta builds submit

ID: 30207dd1-(snip)
CREATE_TIME: (created time)
DURATION: 3M17S
SOURCE: gs://(project)_cloudbuild/source/(snip).tgz
IMAGES: us-docker.pkg.dev/(project)/spanner-game-images/profile:30207dd1-(snip) (+3 more)
STATUS: SUCCESS

เอาต์พุตของบิลด์นี้บ่งชี้ว่ามีอิมเมจที่สร้างขึ้นบางรายการ ซึ่งต่างจากเอาต์พุตของขั้นตอน schema migration โดยระบบจะจัดเก็บข้อมูลเหล่านั้นไว้ในที่เก็บ Artifact Registry ของคุณ

เอาต์พุตของขั้นตอน gcloud build จะมีลิงก์ไปยัง Cloud Console ลองดูข้อมูลพวกนั้นนะ

เมื่อได้รับการแจ้งเตือนที่สำเร็จจาก Cloud Build แล้ว ให้ไปที่ Cloud Deployment จากนั้นไปที่ไปป์ไลน์ sample-game-services เพื่อตรวจสอบความคืบหน้าของการทำให้ใช้งานได้

df5c6124b9693986.png

เมื่อทำให้บริการใช้งานได้แล้ว คุณจะตรวจสอบ kubectl เพื่อดูพ็อดได้ สถานะ:

kubectl get pods

เอาต์พุตจากคำสั่ง

NAME                           READY   STATUS    RESTARTS   AGE
item-6b9d5f678c-4tbk2          1/1     Running   0          83m
matchmaking-5bcf799b76-lg8zf   1/1     Running   0          80m
profile-565bbf4c65-kphdl       1/1     Running   0          83m
profile-565bbf4c65-xw74j       1/1     Running   0          83m
tradepost-68b87ccd44-gw55r     1/1     Running   0          79m

จากนั้นตรวจสอบบริการเพื่อดูการทำงานของ ClusterIP ดังนี้

kubectl get services

เอาต์พุตจากคำสั่ง

NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
item          ClusterIP   10.172.XXX.XXX   <none>        80/TCP    84m
kubernetes    ClusterIP   10.172.XXX.XXX   <none>        443/TCP   137m
matchmaking   ClusterIP   10.172.XXX.XXX   <none>        80/TCP    84m
profile       ClusterIP   10.172.XXX.XXX   <none>        80/TCP    84m
tradepost     ClusterIP   10.172.XXX.XXX   <none>        80/TCP    84m

นอกจากนี้ คุณยังไปที่ UI ของ GKE ใน Cloud Console เพื่อดู Workloads, Services และ ConfigMaps ได้ด้วย

ภาระงาน

da98979ae49e5a30.png

บริการ

406ca2fe7ad4818b.png

ConfigMaps

a0ebd34ee735ee11.png

3b9ef91c77a4e7f0.png

สรุป

ในขั้นตอนนี้ คุณได้ทำให้บริการแบ็กเอนด์ 4 รายการใช้งานได้กับ GKE Autopilot คุณสามารถเรียกใช้ขั้นตอน Cloud Build และตรวจสอบความคืบหน้าใน Cloud Deployment และบน Kubernetes ใน Cloud Console ได้

และคุณยังได้เรียนรู้วิธีที่บริการเหล่านี้ใช้ Workload Identity เพื่อแอบอ้างเป็นบัญชีบริการที่มีสิทธิ์ที่เหมาะสมในการอ่านและเขียนข้อมูลไปยังฐานข้อมูล Spanner

ขั้นตอนถัดไป

ในส่วนถัดไป คุณจะทำให้ภาระงานใช้งานได้

6. ทำให้ภาระงานใช้งานได้

ภาพรวม

เมื่อบริการแบ็กเอนด์ทำงานอยู่บนคลัสเตอร์แล้ว คุณจะต้องทำให้ภาระงานใช้งานได้

dd900485e2eeb611.png

ภาระงานเข้าถึงได้จากภายนอก และมีภาระงานอยู่ 1 รายการสำหรับบริการแบ็กเอนด์แต่ละรายการตามวัตถุประสงค์ของ Codelab นี้

ภาระงานเหล่านี้เป็นสคริปต์การสร้างภาระงานที่อิงตาม Locust ซึ่งเลียนแบบรูปแบบการเข้าถึงจริงที่บริการตัวอย่างเหล่านี้คาดหวัง

กระบวนการ Cloud Build มีดังนี้

  • $DEMO_HOME/workloads/cloudbuild.yaml (สร้างโดย Terraform)
  • $DEMO_HOME/workloads/skaffold.yaml
  • ไฟล์ deployment.yaml สำหรับภาระงานแต่ละรายการ

ไฟล์ภาระงาน deployment.yaml ดูต่างจากไฟล์การทำให้บริการแบ็กเอนด์ใช้งานได้เล็กน้อย

ตัวอย่างจาก matchmaking-workload มีดังนี้

apiVersion: v1
kind: Service
metadata:
 name: matchmaking-workload
spec:
 type: LoadBalancer
 selector:
   app: matchmaking-workload
 ports:
 - port: 8089
   targetPort: 8089
---
apiVersion: apps/v1
kind: Deployment
metadata:
 name: matchmaking-workload
spec:
 replicas: 1 # EDIT: Number of instances of deployment
 selector:
   matchLabels:
     app: matchmaking-workload
 template:
   metadata:
     labels:
       app: matchmaking-workload
   spec:
     serviceAccountName: default
     containers:
     - name: matchmaking-workload
       image: matchmaking-workload
       ports:
         - containerPort: 8089
       resources:
         requests:
           cpu: "500m"
           memory: "512Mi"
           ephemeral-storage: "100Mi"
         limits:
           cpu: "500m"
           memory: "512Mi"
           ephemeral-storage: "100Mi"

ส่วนบนของไฟล์จะกำหนดบริการ ในกรณีนี้ ระบบจะสร้าง LoadBalancer และภาระงานจะทำงานบนพอร์ต 8089

LoadBalancer จะมี IP ภายนอกที่ใช้เชื่อมต่อกับภาระงานได้

apiVersion: v1
kind: Service
metadata:
 name: matchmaking-workload
spec:
 type: LoadBalancer
 selector:
   app: matchmaking-workload
 ports:
 - port: 8089
   targetPort: 8089

ที่ด้านบนของส่วนการทำให้ใช้งานได้คือข้อมูลเมตาเกี่ยวกับภาระงาน ในกรณีนี้ ระบบจะทำให้ตัวจำลองใช้งานได้เพียง 1 รายการเท่านั้น

replicas: 1 

อย่างไรก็ตาม ข้อมูลจำเพาะของคอนเทนเนอร์นั้นแตกต่างกัน เหตุผลหนึ่งคือ เราจะใช้บัญชีบริการ Kubernetes ของ default บัญชีนี้ไม่มีสิทธิ์พิเศษ เนื่องจากภาระงานไม่จำเป็นต้องเชื่อมต่อกับทรัพยากร Google Cloud ใดๆ ยกเว้นบริการแบ็กเอนด์ที่ทำงานบนคลัสเตอร์ GKE

ความแตกต่างอีกอย่างคือ ไม่ต้องใช้ตัวแปรสภาพแวดล้อมใดๆ สำหรับภาระงานเหล่านี้ ผลลัพธ์ที่ได้คือข้อกำหนดการติดตั้งใช้งานที่สั้นลง

spec:
  serviceAccountName: default
  containers:
    - name: matchmaking-workload
      image: matchmaking-workload
  ports:
    - containerPort: 8089

การตั้งค่าทรัพยากรคล้ายกับบริการแบ็กเอนด์ อย่าลืมว่านี่เป็นวิธีที่ GKE Autopilot รู้จำนวนทรัพยากรที่จำเป็นสำหรับการตอบสนองคำขอของพ็อดทั้งหมดที่ทำงานอยู่บนคลัสเตอร์

แล้วทำให้ภาระงานใช้งานได้เลย

ทำให้ภาระงานใช้งานได้

คุณส่งคำขอบิลด์โดยใช้บรรทัดคำสั่ง gcloud ได้เช่นเดิม

cd $DEMO_HOME/workloads
gcloud builds submit --config=cloudbuild.yaml

เอาต์พุตจากคำสั่ง

Creating temporary tarball archive of 18 file(s) totalling 26.2 KiB before compression.
Some files were not included in the source upload.

Check the gcloud log [/tmp/tmp.4Z9EqdPo6d/logs/(snip).log] to see which files and the contents of the
default gcloudignore file used (see `$ gcloud topic gcloudignore` to learn
more).

Uploading tarball of [.] to [gs://(project)_cloudbuild/source/(snip).tgz]
Created [https://cloudbuild.googleapis.com/v1/projects/(project)/locations/global/builds/(snip)].
Logs are available at [ https://console.cloud.google.com/cloud-build/builds/0daf20f6-(snip)?project=(snip) ].

gcloud builds submit only displays logs from Cloud Storage. To view logs from Cloud Logging, run:
gcloud beta builds submit

ID: 0daf20f6-(snip)
CREATE_TIME: (created_time)
DURATION: 1M41S
SOURCE: gs://(project)_cloudbuild/source/(snip).tgz
IMAGES: us-docker.pkg.dev/(project)/spanner-game-images/profile-workload:0daf20f6-(snip) (+4 more)
STATUS: SUCCESS

อย่าลืมตรวจสอบบันทึกของ Cloud Build และไปป์ไลน์ Cloud Deployment ใน Cloud Console เพื่อตรวจสอบสถานะ สำหรับภาระงาน ไปป์ไลน์ Cloud Deploy คือ sample-game-workloads:

เมื่อทำให้ใช้งานได้เรียบร้อยแล้ว ให้ตรวจสอบสถานะด้วย kubectl ใน Cloud Shell:

kubectl get pods

เอาต์พุตจากคำสั่ง

NAME                                    READY   STATUS    RESTARTS   AGE
game-workload-7ff44cb657-pxxq2          1/1     Running   0          12m
item-6b9d5f678c-cr29w                   1/1     Running   0          9m6s
item-generator-7bb4f57cf8-5r85b         1/1     Running   0          12m
matchmaking-5bcf799b76-lg8zf            1/1     Running   0          117m
matchmaking-workload-76df69dbdf-jds9z   1/1     Running   0          12m
profile-565bbf4c65-kphdl                1/1     Running   0          121m
profile-565bbf4c65-xw74j                1/1     Running   0          121m
profile-workload-76d6db675b-kzwng       1/1     Running   0          12m
tradepost-68b87ccd44-gw55r              1/1     Running   0          116m
tradepost-workload-56c55445b5-b5822     1/1     Running   0          12m

จากนั้นตรวจสอบบริการภาระงานเพื่อดูการทำงานของ LoadBalancer

kubectl get services 

เอาต์พุตจากคำสั่ง

NAME                   TYPE          CLUSTER-IP  EXTERNAL-IP     PORT(S)        AGE
game-workload          LoadBalancer  *snip*      35.XX.XX.XX   8089:32483/TCP   12m
item                   ClusterIP     *snip*      <none>         80/TCP          121m
item-generator         LoadBalancer  *snip*      34.XX.XX.XX   8089:32581/TCP   12m
kubernetes             ClusterIP     *snip*      <none>          443/TCP        174m
matchmaking            ClusterIP     *snip*      <none>          80/TCP         121m
matchmaking-workload   LoadBalancer  *snip*      34.XX.XX.XX   8089:31735/TCP   12m
profile                ClusterIP     *snip*      <none>          80/TCP         121m
profile-workload       LoadBalancer  *snip*      34.XX.XX.XX   8089:32532/TCP   12m
tradepost              ClusterIP     *snip*      <none>          80/TCP         121m
tradepost-workload     LoadBalancer  *snip*      34.XX.XX.XX   8089:30002/TCP   12m

สรุป

คุณได้ทำให้ภาระงานใช้งานได้กับคลัสเตอร์ GKE แล้ว ภาระงานเหล่านี้ไม่ต้องใช้สิทธิ์ IAM เพิ่มเติมและเข้าถึงได้จากภายนอกบนพอร์ต 8089 โดยใช้บริการ LoadBalancer

ขั้นตอนถัดไป

ขณะที่บริการแบ็กเอนด์และภาระงานทำงานอยู่ ถึงเวลา "เล่น" เกมนี้!

7. เริ่มเล่นเกม

ภาพรวม

บริการแบ็กเอนด์สำหรับ "เกม" ตัวอย่างของคุณ กำลังทำงาน และคุณยังมีวิธีสร้าง "โปรแกรมเล่น" อีกด้วย ในการโต้ตอบกับบริการเหล่านั้นโดยใช้ภาระงานดังกล่าว

ภาระงานแต่ละรายการใช้ Locust เพื่อจำลองการโหลดจริงกับ API บริการของเรา ในขั้นตอนนี้ คุณจะเรียกใช้ภาระงานหลายรายการเพื่อสร้างโหลดบนคลัสเตอร์ GKE และบน Spanner รวมถึงจัดเก็บข้อมูลบน Spanner

คำอธิบายของแต่ละภาระงานมีดังนี้

  • ภาระงานของ item-generator คือภาระงานง่ายๆ ในการสร้างรายการ game_items ที่ผู้เล่นจะได้รับผ่านขั้นตอน "เล่นเกม" เกมนี้
  • profile-workload จะจำลองให้ผู้เล่นลงชื่อสมัครใช้และเข้าสู่ระบบ
  • matchmaking-workload จำลองผู้เล่นเข้าคิวรอเพื่อรับมอบหมายเกม
  • game-workload จะจำลองผู้เล่นได้รับ game_items และเงินผ่านการเล่นเกม
  • tradepost-workload จะจำลองให้ผู้เล่นขายและซื้อไอเทมในโพสต์ซื้อขายได้

Codelab นี้จะไฮไลต์การเรียกใช้ item-generator และ profile-workload โดยเฉพาะ

เรียกใช้โปรแกรมสร้างรายการ

item-generator ใช้จุดสิ้นสุดของบริการแบ็กเอนด์ item เพื่อเพิ่ม game_items ไปยัง Spanner จำเป็นต้องมีรายการเหล่านี้เพื่อให้ game-workload และ tradepost-workload ทำงานได้อย่างถูกต้อง

ขั้นตอนแรกคือการหา IP ภายนอกของบริการ item-generator ใน Cloud Shell ให้เรียกใช้คำสั่งต่อไปนี้

# The external IP is the 4th column of the output
kubectl get services | grep item-generator | awk '{print $4}'

เอาต์พุตจากคำสั่ง

{ITEMGENERATOR_EXTERNAL_IP}

ตอนนี้ให้เปิดแท็บเบราว์เซอร์ใหม่และชี้ไปที่ http://{ITEMGENERATOR_EXTERNAL_IP}:8089 คุณควรเห็นหน้าเว็บดังนี้

817307157d66c661.png

คุณจะใช้ users และ spawn เป็นค่าเริ่มต้น 1 สำหรับ host, ให้ป้อน http://item คลิกตัวเลือกขั้นสูงและป้อน 10s สำหรับเวลาทำงาน

การกําหนดค่าควรมีลักษณะดังนี้

f3143165c6285c21.png

คลิก "เริ่มจับกลุ่ม"

สถิติจะเริ่มปรากฏสำหรับคำขอที่ออกในปลายทาง POST /items การโหลดจะหยุดลงหลังจากผ่านไป 10 วินาที

คลิกเพื่อไปที่ Charts และคุณจะเห็นกราฟแสดงประสิทธิภาพของคำขอเหล่านี้

abad0a9f3c165345.png

ตอนนี้คุณต้องการตรวจสอบว่ามีการป้อนข้อมูลลงในฐานข้อมูล Spanner หรือไม่

โดยคลิกเมนู 3 ขีด แล้วไปที่ "Spaner" จากหน้านี้ ให้ไปที่ sample-instance และ sample-database จากนั้นคลิก "Query"

เราต้องการเลือกจำนวน game_items:

SELECT COUNT(*) FROM game_items;

คุณจะเห็นผลการวัดที่ด้านล่าง

137ce291a2ff2706.png

เราไม่จำเป็นต้องมี game_items อะไรมากนัก แต่ตอนนี้เกมพร้อมให้ผู้เล่นซื้อแล้ว!

เรียกใช้ภาระงานของโปรไฟล์

ด้วย game_items ตั้งต้น ขั้นตอนถัดไปคือให้ผู้เล่นลงชื่อสมัครใช้เพื่อให้สามารถเล่นเกมได้

profile-workload จะใช้ Locust เพื่อจำลองผู้เล่นสร้างบัญชี ลงชื่อเข้าสู่ระบบ ดึงข้อมูลโปรไฟล์ และออกจากระบบ ทั้งหมดนี้ทดสอบปลายทางของบริการแบ็กเอนด์ profile ในภาระงานที่เหมือนกับเวอร์ชันที่ใช้งานจริงทั่วไป

หากต้องการเรียกใช้ ให้หา IP ภายนอก profile-workload ดังนี้

# The external IP is the 4th column of the output
kubectl get services | grep profile-workload | awk '{print $4}'

เอาต์พุตจากคำสั่ง

{PROFILEWORKLOAD_EXTERNAL_IP}

ตอนนี้ให้เปิดแท็บเบราว์เซอร์ใหม่และชี้ไปที่ http://{PROFILEWORKLOAD_EXTERNAL_IP}:8089 คุณจะเห็นหน้า Locust ที่คล้ายกับหน้าก่อนหน้า

ในกรณีนี้ คุณจะใช้ http://profile สำหรับโฮสต์ และคุณจะไม่ระบุรันไทม์ในตัวเลือกขั้นสูง และระบุ users เป็น 4 ซึ่งจะจำลองคำขอของผู้ใช้ครั้งละ 4 รายการ

การทดสอบ profile-workload ควรมีลักษณะดังนี้

f6e0f06efb0ad6e.png

คลิก "เริ่มจับกลุ่ม"

เช่นเดียวกับก่อนหน้านี้ สถิติสำหรับปลายทาง REST ของ profile ต่างๆ จะเริ่มปรากฏ คลิกที่แผนภูมิเพื่อดูการแสดงผลการทำงานของทุกอย่าง

4c2146e1cb3de23e.png

สรุป

ในขั้นตอนนี้ คุณได้สร้าง game_items บางส่วน และได้ค้นหาตาราง game_items โดยใช้ Spanner Query UI ใน Cloud Console

คุณยังอนุญาตให้ผู้เล่นลงชื่อสมัครใช้เกมของคุณ และดูว่า Locust สามารถสร้างภาระงานแบบเดียวกับเวอร์ชันที่ใช้งานจริงในบริการแบ็กเอนด์ของคุณได้อย่างไร

ขั้นตอนถัดไป

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

8. ตรวจสอบการใช้งาน GKE และ Spanner

เมื่อบริการโปรไฟล์ทำงานอยู่ ก็ได้เวลาใช้โอกาสเพื่อดูว่าคลัสเตอร์ GKE Autopilot และ Cloud Spanner ทำงานเป็นอย่างไร

ตรวจสอบคลัสเตอร์ GKE

ไปที่คลัสเตอร์ Kubernetes โปรดสังเกตว่าเนื่องจากคุณได้ทำให้ภาระงานและบริการใช้งานได้ ตอนนี้คลัสเตอร์จะมีรายละเอียดเพิ่มเติมเกี่ยวกับ vCPU และหน่วยความจำทั้งหมด ไม่มีข้อมูลนี้เมื่อไม่มีภาระงานบนคลัสเตอร์

61d2d766c1f10079.png

จากนั้นคลิกคลัสเตอร์ sample-game-gke แล้วสลับไปที่แท็บความสามารถในการสังเกต

fa9acc7e26ea04a.png

เนมสเปซ Kubernetes ของ default ควรสูงกว่าเนมสเปซ kube-system สำหรับการใช้งาน CPU เนื่องจากภาระงานและบริการแบ็กเอนด์ของเราทำงานบน default หากไม่ ให้ตรวจสอบว่า profile workload ยังทำงานอยู่และรอสักครู่เพื่อให้แผนภูมิอัปเดต

หากต้องการดูว่าภาระงานใดใช้ทรัพยากรมากที่สุด ให้ไปที่หน้าแดชบอร์ด Workloads

แทนที่จะไปยังแต่ละภาระงาน ให้ไปที่แท็บ "การสังเกตการณ์" ของหน้าแดชบอร์ดโดยตรง คุณควรเห็นว่า CPU ของ profile และ profile-workload เพิ่มขึ้น

f194b618969cfa9e.png

ตอนนี้ให้ตรวจสอบ Cloud Spanner

ตรวจสอบอินสแตนซ์ Cloud Spanner

หากต้องการตรวจสอบประสิทธิภาพของ Cloud Spanner ให้ไปที่ Spanner และคลิกเข้าไปในอินสแตนซ์ sample-instance และฐานข้อมูล sample-game

จากตรงนี้ คุณจะเห็นแท็บข้อมูลเชิงลึกของระบบในเมนูด้านซ้าย

216212182a57dfd1.png

มีแผนภูมิจำนวนมากที่จะช่วยให้คุณเข้าใจประสิทธิภาพทั่วไปของอินสแตนซ์ Spanner รวมถึง CPU utilization, transaction latency and locking และ query throughput

นอกเหนือจากข้อมูลเชิงลึกของระบบแล้ว คุณสามารถดูรายละเอียดเพิ่มเติมเกี่ยวกับภาระงานของการค้นหาได้ด้วยการดูลิงก์อื่นๆ ในส่วน "การสังเกตการณ์"

  • ข้อมูลเชิงลึกเกี่ยวกับการค้นหาช่วยระบุการค้นหายอดนิยมที่ใช้ทรัพยากรบน Spanner
  • ข้อมูลเชิงลึกเกี่ยวกับธุรกรรมและล็อกช่วยระบุธุรกรรมที่มีเวลาในการตอบสนองสูง
  • Key Visualizer ช่วยให้เห็นภาพรูปแบบการเข้าถึงและช่วยติดตามฮอตสปอตในข้อมูลได้

สรุป

ในขั้นตอนนี้ คุณได้เรียนรู้วิธีตรวจสอบเมตริกประสิทธิภาพพื้นฐานบางรายการสำหรับทั้ง GKE Autopilot และ Spanner

ตัวอย่างเช่น ขณะที่ภาระงานของโปรไฟล์ทำงานอยู่ ให้ค้นหาตารางผู้เล่นเพื่อรับข้อมูลเพิ่มเติมเกี่ยวกับข้อมูลที่เก็บอยู่ในนั้น

ขั้นตอนถัดไป

ต่อไปก็ถึงเวลาล้างข้อมูล

9. กำลังล้างข้อมูล

ก่อนล้างข้อมูล โปรดสำรวจภาระงานอื่นๆ ที่ยังไม่ครอบคลุม โดยเฉพาะ matchmaking-workload, game-workload และ tradepost-workload

เมื่อ "กำลังเล่น" เสร็จแล้ว คุณสามารถทำความสะอาด สนามเด็กเล่นของคุณ โชคดีที่เรื่องนี้ไม่ยากเลย

ก่อนอื่น หาก profile-workload ยังคงทำงานอยู่ในเบราว์เซอร์ ให้ข้ามและหยุดเบราว์เซอร์โดยทำดังนี้

13ae755a11f3228.png

ดำเนินการแบบเดียวกันนี้สำหรับแต่ละภาระงานที่คุณอาจทดสอบไปแล้ว

จากนั้นไปที่โฟลเดอร์โครงสร้างพื้นฐานใน Cloud Shell คุณจะdestroyโครงสร้างพื้นฐานโดยใช้ terraform:

cd $DEMO_HOME/infrastructure
terraform destroy
# type 'yes' when asked

เอาต์พุตจากคำสั่ง

Plan: 0 to add, 0 to change, 46 to destroy.

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

*snip*

Destroy complete! Resources: 46 destroyed.

ใน Cloud Console ให้ไปที่ Spanner, Kubernetes Cluster, Artifact Registry, Cloud Deploy และ IAM เพื่อตรวจสอบความถูกต้องของการนำทรัพยากรทั้งหมดออก

10. ยินดีด้วย

ยินดีด้วย คุณได้ทำให้แอปพลิเคชัน Golang ตัวอย่างใช้งานได้บน GKE Autopilot แล้ว และเชื่อมต่อกับ Cloud Spanner โดยใช้ Workload Identity

ยิ่งไปกว่านั้น โครงสร้างพื้นฐานนี้สามารถตั้งค่าและนำออกได้อย่างง่ายดายในลักษณะที่ทำซ้ำโดยใช้ terform

อ่านข้อมูลเพิ่มเติมเกี่ยวกับบริการของ Google Cloud ที่เคยโต้ตอบด้วยได้ใน Codelab นี้

ขั้นตอนถัดไปคือ

ตอนนี้คุณเข้าใจพื้นฐานเกี่ยวกับวิธีที่ GKE Autopilot และ Cloud Spanner ทำงานร่วมกันแล้ว ลองก้าวต่อไปและเริ่มสร้างแอปพลิเคชันของคุณเองเพื่อทำงานกับบริการเหล่านี้