ปรับขนาดพูลผู้ปฏิบัติงาน Cloud Run โดยอัตโนมัติตามปริมาณคิว Pub/Sub โดยใช้ CREMA

1. บทนำ

ภาพรวม

บทแนะนำนี้จะแสดงวิธีทำให้กลุ่ม Worker ของ Cloud Run (ผู้ใช้) ใช้งานได้เพื่อประมวลผลข้อความ Pub/Sub และปรับขนาดอินสแตนซ์ผู้ใช้โดยอัตโนมัติตามความลึกของคิวโดยใช้การปรับขนาดอัตโนมัติของเมตริกภายนอกของ Cloud Run (CREMA)

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

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

  • สร้างหัวข้อและการสมัครใช้บริการ Pub/Sub แล้วส่งข้อความไปยังหัวข้อนั้น
  • ทําให้กลุ่ม Worker ของ Cloud Run (ผู้ใช้) ใช้งานได้ซึ่งจะใช้ข้อความจาก Pub/Sub
  • ติดตั้งใช้งานโปรเจ็กต์ CREMA บน GitHub เป็นบริการ Cloud Run เพื่อปรับขนาดกลุ่ม Worker โดยอัตโนมัติตามจำนวนข้อความในการสมัครใช้บริการ Pub/Sub
  • ทดสอบการกำหนดค่าการปรับขนาดอัตโนมัติโดยสร้างโหลดด้วยการเรียกใช้สคริปต์ Python ในเครื่อง

2. กำหนดค่าตัวแปรสภาพแวดล้อม

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

set -u

ซึ่งจะเตือนคุณหากพยายามใช้ตัวแปรสภาพแวดล้อมที่ยังไม่ได้ตั้งค่า หากต้องการเลิกทำการตั้งค่านี้ ให้เรียกใช้ set +u

ก่อนอื่น ให้เปลี่ยนตัวแปรต่อไปนี้เป็นรหัสโปรเจ็กต์

export PROJECT_ID=<YOUR_PROJECT_ID>

แล้วตั้งค่าเป็นโปรเจ็กต์สำหรับโค้ดแล็บนี้

gcloud config set project $PROJECT_ID

จากนั้นตั้งค่าตัวแปรสภาพแวดล้อมที่ใช้โดย Codelab นี้

export REGION=us-central1
export TOPIC_ID=crema-pubsub-topic
export SUBSCRIPTION_ID=crema-pubsub-sub
export CREMA_SA_NAME=crema-service-account
export CONSUMER_SA_NAME=consumer-service-account
export CONSUMER_WORKER_POOL_NAME=worker-pool-consumer
export CREMA_SERVICE_NAME=my-crema-service

สร้างไดเรกทอรีสำหรับ Codelab นี้

mkdir crema-pubsub-codelab
cd crema-pubsub-codelab

เปิดใช้ API

gcloud services enable \
        artifactregistry.googleapis.com \
        cloudbuild.googleapis.com \
        run.googleapis.com \
        parametermanager.googleapis.com

สุดท้าย ตรวจสอบว่า gcloud ใช้เวอร์ชันล่าสุด

gcloud components update

3. การตั้งค่า Pub/Sub

สร้างหัวข้อและการสมัครรับข้อมูลแบบดึงที่พูลผู้ปฏิบัติงานจะประมวลผล Bash

สร้างหัวข้อ

gcloud pubsub topics create $TOPIC_ID

สร้างการสมัครใช้บริการ

gcloud pubsub subscriptions create $SUBSCRIPTION_ID --topic=$TOPIC_ID

4. IAM และบัญชีบริการ

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

  • SA ของผู้ใช้: ข้อมูลประจำตัวสำหรับพูลผู้ปฏิบัติงานที่ประมวลผลข้อความ Pub/Sub
  • CREMA SA: ข้อมูลประจำตัวสำหรับบริการ Autoscaler ของ CREMA

สร้างบัญชีบริการ

สร้าง SA ของผู้ใช้พูลผู้ปฏิบัติงาน

gcloud iam service-accounts create $CONSUMER_SA_NAME \
  --display-name="PubSub Consumer Service Account"

สร้าง SA ของบริการ CREMA ของพูลผู้ปฏิบัติงาน

gcloud iam service-accounts create $CREMA_SA_NAME \
  --display-name="CREMA Autoscaler Service Account"

ให้สิทธิ์แก่ Consumer SA

ให้สิทธิ์แก่ SA ของผู้ใช้พูลของ Worker เพื่อดึงข้อความจากการสมัครใช้บริการ

gcloud pubsub subscriptions add-iam-policy-binding $SUBSCRIPTION_ID \
  --member="serviceAccount:$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/pubsub.subscriber"

ให้สิทธิ์แก่ CREMA SA

CREMA ต้องมีสิทธิ์ในการอ่านพารามิเตอร์ ปรับขนาดพูลของ Worker และตรวจสอบเมตริก Pub/Sub

  1. เข้าถึงเครื่องมือจัดการพารามิเตอร์ (ผู้อ่านการกำหนดค่า)
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/parametermanager.parameterViewer"
  1. ปรับขนาดพูลผู้ปฏิบัติงาน (นักพัฒนาซอฟต์แวร์ Cloud Run):
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/run.developer"
  1. ตรวจสอบ Pub/Sub

ให้บทบาทผู้ดูการตรวจสอบ

gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/monitoring.viewer"

เพิ่มนโยบายในการสมัครใช้บริการสำหรับ CREMA service SA เพื่อดู

gcloud pubsub subscriptions add-iam-policy-binding $SUBSCRIPTION_ID \
  --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/pubsub.viewer"

นอกจากนี้ CREMA SA ยังต้องมีผู้ใช้บัญชีบริการ ซึ่งจำเป็นต่อการเปลี่ยนจำนวนอินสแตนซ์ด้วย

gcloud iam service-accounts add-iam-policy-binding \
    $CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com \
    --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
    --role="roles/iam.serviceAccountUser"

5. ยืนยันสิทธิ์ SA

ก่อนดำเนินการกับ Codelab ให้ตรวจสอบว่า SA ของบริการ CREMA มีบทบาทระดับโปรเจ็กต์ที่ถูกต้อง

gcloud projects get-iam-policy $PROJECT_ID \
  --flatten="bindings[].members" \
  --format="table(bindings.role)" \
  --filter="bindings.members:serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com"

ควรส่งผลให้เกิดสิ่งต่อไปนี้

roles/monitoring.viewer
roles/parametermanager.parameterViewer
roles/run.developer

ตรวจสอบว่าการสมัครใช้บริการ Pub/Sub มีนโยบายที่อนุญาตให้ SA ของบริการ CREMA ดูได้

gcloud pubsub subscriptions get-iam-policy $SUBSCRIPTION_ID \
  --flatten="bindings[].members" \
  --filter="bindings.members:serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
  --format="table(bindings.role)"

ควรส่งผลให้

roles/pubsub.viewer

และตรวจสอบว่า CREMA SA มีบทบาทผู้ใช้บัญชีบริการ

gcloud iam service-accounts get-iam-policy \
  $CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com \
  --flatten="bindings[].members" \
  --filter="bindings.members:serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com"

ควรส่งผลให้เกิดสิ่งต่อไปนี้

bindings:
  members: serviceAccount:crema-service-account@<PROJECT_ID>.iam.gserviceaccount.com
  role: roles/iam.serviceAccountUser

และ SA ของผู้ใช้พูลผู้ปฏิบัติงานมีบทบาทผู้ใช้บริการ Pub/Sub

gcloud pubsub subscriptions get-iam-policy $SUBSCRIPTION_ID \
  --flatten="bindings[].members" \
  --filter="bindings.members:serviceAccount:$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
  --format="table(bindings.role)"

ควรส่งผลให้

ROLE
roles/pubsub.subscriber

6. สร้างและทำให้พูลผู้ปฏิบัติงานของผู้บริโภคใช้งานได้

สร้างไดเรกทอรีสำหรับรหัสผู้บริโภคแล้วป้อนรหัส

mkdir consumer
cd consumer
  1. สร้างไฟล์ consumer.py
import os
import time
from google.cloud import pubsub_v1
from concurrent.futures import TimeoutError

# Configuration
PROJECT_ID = os.environ.get('PROJECT_ID')
SUBSCRIPTION_ID = os.environ.get('SUBSCRIPTION_ID')

subscription_path = f"projects/{PROJECT_ID}/subscriptions/{SUBSCRIPTION_ID}"

print(f"Worker Pool instance starting. Watching {subscription_path}...")

subscriber = pubsub_v1.SubscriberClient()

def callback(message):
    try:
        data = message.data.decode("utf-8")
        print(f"Processing job: {data}")
        time.sleep(5)  # Simulate work
        print(f"Done {data}")
        message.ack()
    except Exception as e:
        print(f"Error processing message: {e}")
        message.nack()

streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)
print(f"Listening for messages on {subscription_path}...")

# Wrap subscriber in a 'with' block to automatically call close() when done.
with subscriber:
    try:
        # When `timeout` is not set, result() will block indefinitely,
        # unless an exception is encountered first.
        streaming_pull_future.result()
    except TimeoutError:
        streaming_pull_future.cancel()  # Trigger the shutdown.
        streaming_pull_future.result()  # Block until the shutdown is complete.
    except Exception as e:
        print(f"Streaming pull failed: {e}")
  1. สร้าง Dockerfile
FROM python:3.12-slim
RUN pip install google-cloud-pubsub
COPY consumer.py .
CMD ["python", "-u", "consumer.py"]
  1. ติดตั้งใช้งานพูลผู้ปฏิบัติงานของผู้บริโภค

Codelab นี้แนะนำให้ติดตั้งใช้งานกลุ่ม Worker โดยมีอินสแตนซ์ 0 รายการเพื่อเริ่มต้น คุณจึงสามารถดู CREMA ปรับขนาดกลุ่ม Worker เมื่อตรวจพบข้อความ Pub/Sub ในการสมัครใช้บริการ

gcloud beta run worker-pools deploy $CONSUMER_WORKER_POOL_NAME \
  --source . \
  --region $REGION \
  --service-account="$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
  --instances=0 \
  --set-env-vars PROJECT_ID=$PROJECT_ID,SUBSCRIPTION_ID=$SUBSCRIPTION_ID

7. กำหนดค่า CREMA

  1. กลับไปที่ไดเรกทอรีรากของโปรเจ็กต์
cd ..
  1. สร้างไฟล์การกำหนดค่า สร้างไฟล์ชื่อ crema-config.yaml
apiVersion: crema/v1
kind: CremaConfig
spec:
  pollingInterval: 30
  triggerAuthentications:
    - metadata:
        name: adc-trigger-auth
      spec:
        podIdentity:
          provider: gcp
  scaledObjects:
    - spec:
        scaleTargetRef:
          name: projects/PROJECT_ID_PLACEHOLDER/locations/REGION_PLACEHOLDER/workerpools/CONSUMER_WORKER_POOL_NAME_PLACEHOLDER
        triggers:
          - type: gcp-pubsub
            metadata:
              subscriptionName: "SUBSCRIPTION_ID_PLACEHOLDER"
              # Target number of undelivered messages per worker instance
              value: "10"
              mode: "SubscriptionSize"
            authenticationRef:
              name: adc-trigger-auth
  1. ตัวแปรแทน
sed -i "s/PROJECT_ID_PLACEHOLDER/$PROJECT_ID/g" crema-config.yaml
sed -i "s/REGION_PLACEHOLDER/$REGION/g" crema-config.yaml
sed -i "s/CONSUMER_WORKER_POOL_NAME_PLACEHOLDER/$CONSUMER_WORKER_POOL_NAME/g" crema-config.yaml
sed -i "s/SUBSCRIPTION_ID_PLACEHOLDER/$SUBSCRIPTION_ID/g" crema-config.yaml
  1. ตรวจสอบว่า crema-config.yaml ของคุณถูกต้อง
if grep -q "_PLACEHOLDER" crema-config.yaml; then
  echo "❌ ERROR: Validations failed. '_PLACEHOLDER' was found in crema-config.yaml."
  echo "Please check your environment variables and run the 'sed' commands again."
else
  echo "✅ Config check passed: No placeholders found."
fi
  1. อัปโหลดไปยัง Parameter Manager

ตั้งค่าตัวแปรสภาพแวดล้อมเพิ่มเติมสำหรับเครื่องมือจัดการพารามิเตอร์

export PARAMETER_ID=crema-config
export PARAMETER_REGION=global
export PARAMETER_VERSION=1

สร้างทรัพยากรพารามิเตอร์

gcloud parametermanager parameters create $PARAMETER_ID \
  --location=$PARAMETER_REGION \
  --parameter-format=YAML

สร้างพารามิเตอร์เวอร์ชัน 1

gcloud parametermanager parameters versions create $PARAMETER_VERSION \
  --parameter=crema-config \
  --project=$PROJECT_ID \
  --location=$PARAMETER_REGION \
  --payload-data-from-file=crema-config.yaml

ยืนยันว่าเพิ่มพารามิเตอร์สำเร็จแล้ว

gcloud parametermanager parameters versions list \
  --parameter=$PARAMETER_ID \
  --location=$PARAMETER_REGION

คุณควรเห็นข้อความคล้ายกับ

projects/<YOUR_PROJECT_ID>/locations/global/parameters/crema-config/versions/1

8. ติดตั้งใช้งานบริการ CREMA

ในส่วนนี้ คุณจะติดตั้งใช้งานบริการ Autoscaler ของ CREMA คุณจะใช้รูปภาพที่เผยแพร่แบบสาธารณะ

  1. ตั้งค่าตัวแปรสภาพแวดล้อมที่จำเป็นสำหรับ CREMA
CREMA_CONFIG_PARAM_VERSION=projects/$PROJECT_ID/locations/$PARAMETER_REGION/parameters/$PARAMETER_ID/versions/$PARAMETER_VERSION
  1. ยืนยันเส้นทางชื่อเวอร์ชัน
echo $CREMA_CONFIG_PARAM_VERSION

โดยควรมีลักษณะดังนี้

projects/<YOUR_PROJECT>/locations/global/parameters/crema-config/versions/1
  1. ตั้งค่าตัวแปรสภาพแวดล้อมสำหรับรูปภาพ CREMA
IMAGE=us-central1-docker.pkg.dev/cloud-run-oss-images/crema-v1/autoscaler:1.0
  1. และติดตั้งใช้งานบริการ CREMA

โปรดทราบว่าต้องระบุรูปภาพฐาน

gcloud beta run deploy $CREMA_SERVICE_NAME \
  --image=$IMAGE \
  --region=${REGION} \
  --service-account="${CREMA_SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --no-allow-unauthenticated \
  --no-cpu-throttling \
  --labels=created-by=crema \
  --base-image=us-central1-docker.pkg.dev/serverless-runtimes/google-24/runtimes/java25 \
  --set-env-vars="CREMA_CONFIG=${CREMA_CONFIG_PARAM_VERSION},OUTPUT_SCALER_METRICS=True,ENABLE_CLOUD_LOGGING=True"

9. การทดสอบการโหลด

  1. สร้างสคริปต์ที่จะเผยแพร่ข้อความไปยังหัวข้อ Pub/Sub
touch load-pubsub.sh
  1. เพิ่มโค้ดต่อไปนี้ลงในไฟล์ load-pubsub.sh
#!/bin/bash
TOPIC_ID=${TOPIC_ID} 
PROJECT_ID=${PROJECT_ID}
NUM_MESSAGES=100

echo "Publishing $NUM_MESSAGES messages to topic $TOPIC_ID..."

for i in $(seq 1 $NUM_MESSAGES); do
  gcloud pubsub topics publish $TOPIC_ID --message="job-$i" --project=$PROJECT_ID &
  if (( $i % 10 == 0 )); then
    wait
    echo "Published $i messages..."
  fi
done
wait
echo "Done. All messages published."
  1. เรียกใช้การทดสอบโหลด
chmod +x load-pubsub.sh
./load-pubsub.sh
  1. รอการปรับขนาดจอภาพ 3-4 นาที ดูบันทึก CREMA เพื่อดูว่ามีการแนะนำอินสแตนซ์ตามการกำหนดค่า authenticationRef ใหม่หรือไม่
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=$CREMA_SERVICE_NAME AND textPayload:SCALER" \
  --limit=20 \
  --format="value(textPayload)" \
  --freshness=5m
  1. ตรวจสอบการประมวลผล ดูบันทึกของผู้บริโภคเพื่อดูว่ามีการหมุนขึ้น
gcloud beta run worker-pools logs tail $CONSUMER_WORKER_POOL_NAME --region=$REGION

คุณควรเห็นบันทึกที่คล้ายกับ

Done job-100

10. การแก้ปัญหา

ก่อนอื่น คุณจะต้องพิจารณาว่าปัญหาเกิดจากการกำหนดค่าบริการ CREMA หรือการกำหนดค่าผู้ใช้ PubSub

ตั้งค่า Autoscaler ของผู้ใช้ PubSub เป็น 1 แทนที่จะเป็น 0 หากเริ่มประมวลผลข้อความ Pub/Sub ทันที แสดงว่ามีปัญหาเกี่ยวกับ CREMA หากไม่ประมวลผลข้อความ Pub/Sub แสดงว่ามีปัญหาเกี่ยวกับผู้ใช้ Pub/Sub

11. ยินดีด้วย

ขอแสดงความยินดีที่ทำ Codelab นี้เสร็จสมบูรณ์

เราขอแนะนำให้อ่านเอกสารประกอบของ Cloud Run

สิ่งที่เราได้พูดถึงไปแล้ว

  • วิธีสร้างหัวข้อและการสมัครใช้บริการ Pub/Sub รวมถึงวิธีพุชข้อความไปยังหัวข้อนั้น
  • วิธีทำให้กลุ่ม Worker ของ Cloud Run (ผู้ใช้) ที่ใช้ข้อความจาก Pub/Sub ใช้งานได้
  • วิธีติดตั้งใช้งานโปรเจ็กต์ CREMA ใน GitHub เป็นบริการ Cloud Run เพื่อปรับขนาดกลุ่ม Worker โดยอัตโนมัติตามจำนวนข้อความในการสมัครใช้บริการ Pub/Sub
  • วิธีทดสอบการกำหนดค่าการปรับขนาดอัตโนมัติโดยการสร้างภาระงานด้วยการเรียกใช้สคริปต์ Python ในเครื่อง

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

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

ลบทรัพยากรที่ใช้ใน Codelab นี้

  1. ลบบริการ CREMA ของ Cloud Run
gcloud run services delete $CREMA_SERVICE_NAME --region=$REGION --quiet
  1. ลบผู้ใช้พูลผู้ปฏิบัติงาน Cloud Run
gcloud beta run worker-pools delete $CONSUMER_WORKER_POOL_NAME --region=$REGION --quiet
  1. ลบการสมัครใช้บริการและหัวข้อ Pub/Sub
gcloud pubsub subscriptions delete $SUBSCRIPTION_ID --quiet
gcloud pubsub topics delete $TOPIC_ID --quiet
  1. ลบการกำหนดค่าเครื่องมือจัดการพารามิเตอร์

ลบเวอร์ชันภายในพารามิเตอร์

gcloud parametermanager parameters versions delete $PARAMETER_VERSION \
  --parameter=$PARAMETER_ID \
  --location=$PARAMETER_REGION \
  --quiet

ตอนนี้ให้ลบพารามิเตอร์ที่ว่างเปล่า

gcloud parametermanager parameters delete $PARAMETER_ID \
  --location=$PARAMETER_REGION \
  --quiet
  1. ลบบัญชีบริการ
gcloud iam service-accounts delete "$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" --quiet
gcloud iam service-accounts delete "$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" --quiet

หรือลบทั้งโปรเจ็กต์

หากต้องการลบทั้งโปรเจ็กต์ ให้ไปที่จัดการทรัพยากร เลือกโปรเจ็กต์ที่สร้างในขั้นตอนที่ 2 แล้วเลือก "ลบ" หากลบโปรเจ็กต์ คุณจะต้องเปลี่ยนโปรเจ็กต์ใน Cloud SDK คุณดูรายการโปรเจ็กต์ทั้งหมดที่พร้อมใช้งานได้โดยเรียกใช้ gcloud projects list