รูปภาพรายวัน: ห้องปฏิบัติการ 5 - การล้างข้อมูลหลังการลบรูปภาพ

1. ภาพรวม

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

d93345bfc235f81e.png

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

  • Cloud Run
  • Cloud Storage
  • Cloud Firestore
  • Eventarc

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

การตั้งค่าสภาพแวดล้อมแบบเรียนรู้ด้วยตนเอง

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

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

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

เริ่มต้น Cloud Shell

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

จาก GCP Console ให้คลิกไอคอน Cloud Shell ในแถบเครื่องมือด้านขวาบน

bce75f34b2c53987.png

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

f6ef2b5f13479f3a.png

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

3. ข้อมูลเบื้องต้นเกี่ยวกับ Eventarc

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

776ed63706ca9683.png

คุณดึงเหตุการณ์จากแหล่งที่มาของ Google Cloud และแอปพลิเคชันที่กำหนดเองซึ่งเผยแพร่ไปยัง Cloud Pub/Sub และส่งไปยังปลายทาง Google Cloud Run ได้

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

แอปพลิเคชันที่กำหนดเองซึ่งเผยแพร่ไปยัง Cloud Pub/Sub จะเผยแพร่ข้อความไปยังหัวข้อ Pub/Sub ที่ระบุในรูปแบบใดก็ได้

ทริกเกอร์เหตุการณ์คือกลไกการกรองเพื่อระบุเหตุการณ์ที่จะส่งไปยัง Sink ใด

เหตุการณ์ทั้งหมดจะส่งในรูปแบบ CloudEvents v1.0 เพื่อให้ทำงานร่วมกันได้ในบริการต่างๆ

4. ก่อนเริ่มต้น

เปิดใช้ API

คุณจะต้องใช้บริการ Eventarc เพื่อทริกเกอร์บริการ Cloud Run ตรวจสอบว่าเปิดใช้แล้ว ดังนี้

gcloud services enable eventarc.googleapis.com

คุณควรเห็นการดำเนินการเสร็จสมบูรณ์ดังนี้

Operation "operations/acf.5c5ef4f6-f734-455d-b2f0-ee70b5a17322" finished successfully.

กำหนดค่าบัญชีบริการ

ระบบจะใช้บัญชีบริการ Compute เริ่มต้นในทริกเกอร์ มอบบทบาท eventarc.eventReceiver ให้กับบัญชีบริการ Compute เริ่มต้น

PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format='value(projectNumber)')

gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
    --member serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com \
    --role roles/eventarc.eventReceiver

มอบบทบาท pubsub.publisher ให้กับบัญชีบริการ Cloud Storage คุณต้องมีสิ่งต่อไปนี้สำหรับทริกเกอร์ Cloud Storage ของ Eventarc

SERVICE_ACCOUNT=$(gsutil kms serviceaccount -p $PROJECT_NUMBER)

gcloud projects add-iam-policy-binding $PROJECT_NUMBER \
    --member serviceAccount:$SERVICE_ACCOUNT \
    --role roles/pubsub.publisher

หากเปิดใช้บัญชีบริการ Pub/Sub ในวันที่ 8 เมษายน 2021 หรือก่อนหน้านั้น ให้มอบบทบาท iam.serviceAccountTokenCreator ให้กับบัญชีบริการ Pub/Sub โดยทำดังนี้

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:service-$PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \
  --role roles/iam.serviceAccountTokenCreator

5. โคลนโค้ด

โคลนโค้ด หากคุณยังไม่ได้ทำในโค้ดแล็บก่อนหน้า

git clone https://github.com/GoogleCloudPlatform/serverless-photosharing-workshop

จากนั้นคุณจะไปที่ไดเรกทอรีที่มีบริการได้โดยทำดังนี้

cd serverless-photosharing-workshop/services/garbage-collector/nodejs

คุณจะมีเลย์เอาต์ไฟล์ต่อไปนี้สำหรับบริการ

services
 |
 ├── garbage-collector
      |
      ├── nodejs
           |
           ├── index.js
           ├── package.json

ภายในโฟลเดอร์ คุณจะมีไฟล์ 3 ไฟล์ดังนี้

  • index.js มีโค้ด Node.js
  • package.json กำหนดทรัพยากร Dependency ของไลบรารี

6. สำรวจโค้ด

ทรัพยากร Dependency

ไฟล์ package.json จะกำหนดทรัพยากร Dependency ของไลบรารีที่จำเป็น

{
  "name": "garbage_collector_service",
  "version": "0.0.1",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "cloudevents": "^4.0.1",
    "express": "^4.17.1",
    "@google/events": "^3.1.0",
    "@google-cloud/firestore": "^4.9.9",
    "@google-cloud/storage": "^5.8.3"
  }
}

เราใช้ไลบรารี Cloud Storage เพื่อลบรูปภาพภายใน Cloud Storage เราประกาศการขึ้นต่อกันใน Cloud Firestore เพื่อลบข้อมูลเมตาของรูปภาพที่เราจัดเก็บไว้ก่อนหน้านี้ด้วย นอกจากนี้ เรายังใช้ CloudEvents SDK และไลบรารีเหตุการณ์ของ Google เพื่ออ่าน CloudEvents ที่ Eventarc ส่ง Express เป็นเฟรมเวิร์กเว็บ JavaScript / Node Bluebird ใช้สำหรับการจัดการ Promise

index.js

มาดูโค้ด index.js อย่างละเอียดกัน

const express = require('express');
const {Storage} = require('@google-cloud/storage');
const Firestore = require('@google-cloud/firestore');
const { HTTP } = require("cloudevents");
const {toStorageObjectData} = require('@google/events/cloud/storage/v1/StorageObjectData');

เรากำหนดให้มีทรัพยากร Dependency ต่างๆ ที่จำเป็นต่อการเรียกใช้โปรแกรมของเรา โดย Express เป็นเฟรมเวิร์กเว็บ Node ที่เราจะใช้, Bluebird เป็นไลบรารีสำหรับจัดการสัญญา JavaScript, Storage และ Firestore ใช้สำหรับทำงานร่วมกับ Google Cloud Storage (Bucket รูปภาพของเรา) และที่เก็บข้อมูล Cloud Firestore ตามลำดับ นอกจากนี้ เรายังกำหนดให้ CloudEvent อ่าน CloudEvent ที่ Eventarc StoreObjectData ส่งจากไลบรารีเหตุการณ์ของ Google เพื่ออ่านเนื้อหาเหตุการณ์ Cloud Storage ของ CloudEvent

const app = express();
app.use(express.json());

app.post('/', async (req, res) => {
    try {
        const cloudEvent = HTTP.toEvent({ headers: req.headers, body: req.body });
        console.log(cloudEvent);


        /* ... */

    } catch (err) {
        console.log(`Error: ${err}`);
        res.status(500).send(err);
    }
});

ด้านบนนี้คือโครงสร้างของตัวแฮนเดิล Node ของเรา ซึ่งแอปจะตอบสนองต่อคำขอ HTTP แบบ POST โดยจะอ่าน CloudEvent จากคำขอ HTTP และเราจะจัดการข้อผิดพลาดเล็กน้อยในกรณีที่เกิดปัญหา ตอนนี้มาดูกันว่าโครงสร้างนี้มีอะไรอยู่ข้างใน

ขั้นตอนถัดไปคือการดึงและแยกวิเคราะห์เนื้อหา CloudEvent รวมถึงดึงชื่อออบเจ็กต์

const storageObjectData = toStorageObjectData(cloudEvent.data);
console.log(storageObjectData);

const objectName = storageObjectData.name;

เมื่อทราบชื่อรูปภาพแล้ว เราจะลบรูปภาพออกจากที่เก็บข้อมูลภาพขนาดย่อได้โดยทำดังนี้

try {
    await storage.bucket(bucketThumbnails).file(objectName).delete();
    console.log(`Deleted '${objectName}' from bucket '${bucketThumbnails}'.`);
}
catch(err) {
    console.log(`Failed to delete '${objectName}' from bucket '${bucketThumbnails}': ${err}.`);
}

ในขั้นตอนสุดท้าย ให้ลบข้อมูลเมตาของรูปภาพออกจากคอลเล็กชัน Firestore ด้วย

try {
    const pictureStore = new Firestore().collection('pictures');
    const docRef = pictureStore.doc(objectName);
    await docRef.delete();

    console.log(`Deleted '${objectName}' from Firestore collection 'pictures'`);
}
catch(err) {
    console.log(`Failed to delete '${objectName}' from Firestore: ${err}.`);
}

res.status(200).send(`Processed '${objectName}'.`);

ตอนนี้ก็ถึงเวลาทำให้สคริปต์ Node ของเราฟังคำขอที่เข้ามา นอกจากนี้ ให้ตรวจสอบว่าได้ตั้งค่าตัวแปรสภาพแวดล้อมที่จำเป็นแล้ว

app.listen(PORT, () => {
    if (!bucketThumbnails) throw new Error("BUCKET_THUMBNAILS not set");
    console.log(`Started service on port ${PORT}`);
});

7. ทดสอบในเครื่อง

ทดสอบโค้ดในเครื่องเพื่อให้แน่ใจว่าใช้งานได้ก่อนที่จะนำไปใช้ในระบบคลาวด์

ในโฟลเดอร์ garbage-collector/nodejs ให้ติดตั้งทรัพยากร Dependency ของ npm และเริ่มเซิร์ฟเวอร์โดยทำดังนี้

export BUCKET_THUMBNAILS=thumbnails-$GOOGLE_CLOUD_PROJECT

npm install; npm start

หากทุกอย่างเป็นไปด้วยดี เซิร์ฟเวอร์ควรเริ่มทำงานบนพอร์ต 8080

Started service on port 8080

ใช้ CTRL-C เพื่อออก

8. สร้างและทำให้ใช้งานได้กับ Cloud Run

ก่อนที่จะทำให้ใช้งานได้กับ Cloud Run ให้ตั้งค่าภูมิภาค Cloud Run เป็นภูมิภาคที่รองรับและแพลตฟอร์มเป็น managed

REGION=europe-west1
gcloud config set run/region $REGION
gcloud config set run/platform managed

คุณตรวจสอบได้ว่าได้ตั้งค่าการกำหนดค่าแล้วหรือไม่โดยทำดังนี้

gcloud config list

...
[run]
platform = managed
region = europe-west1

คุณยังใช้ Cloud Run เพื่อสร้างอิมเมจคอนเทนเนอร์ให้คุณได้โดยใช้ Google Cloud Buildpacks แทนการสร้างและเผยแพร่อิมเมจคอนเทนเนอร์โดยใช้ Cloud Build ด้วยตนเอง

เรียกใช้คำสั่งต่อไปนี้เพื่อสร้างอิมเมจคอนเทนเนอร์โดยใช้ Google Cloud Buildpack จากนั้นทำให้ใช้งานได้ใน Cloud Run

SERVICE_NAME=garbage-collector-service

gcloud run deploy $SERVICE_NAME \
    --source . \
    --no-allow-unauthenticated \
    --update-env-vars BUCKET_THUMBNAILS=$BUCKET_THUMBNAILS

โปรดสังเกตธง –-source ซึ่งจะแจ้งให้ Cloud Run ใช้ Google Cloud Buildpacks เพื่อสร้างอิมเมจคอนเทนเนอร์โดยไม่มี Dockerfile. แฟล็ก --no-allow-unauthenticated จะทำให้บริการ Cloud Run เป็นบริการภายในที่จะทริกเกอร์ได้โดยบัญชีบริการที่เฉพาะเจาะจงเท่านั้น ในภายหลัง คุณจะสร้างทริกเกอร์ด้วยบัญชีบริการ Compute เริ่มต้นที่มีบทบาท run.invoker เพื่อเรียกใช้บริการ Cloud Run ภายใน

9. สร้างทริกเกอร์

ใน Eventarc ทริกเกอร์จะกำหนดว่าบริการใดควรได้รับเหตุการณ์ประเภทใด ในกรณีนี้ คุณต้องการให้บริการรับเหตุการณ์เมื่อมีการลบไฟล์ในที่เก็บข้อมูล

ตั้งค่าตำแหน่งของทริกเกอร์ในภูมิภาคเดียวกันกับ Bucket ของรูปภาพที่อัปโหลด

gcloud config set eventarc/location eu

สร้างทริกเกอร์ AuditLog เพื่อกรองเหตุการณ์ storage.objects.delete และส่งไปยังบริการ Cloud Run โดยทำดังนี้

BUCKET_IMAGES=uploaded-pictures-$GOOGLE_CLOUD_PROJECT

gcloud eventarc triggers create trigger-$SERVICE_NAME \
  --destination-run-service=$SERVICE_NAME \
  --destination-run-region=$REGION \
  --event-filters="type=google.cloud.storage.object.v1.deleted" \
  --event-filters="bucket=$BUCKET_IMAGES" \
  --service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com

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

gcloud eventarc triggers list

10. ทดสอบบริการ

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

519abf90e7ea4d12.png

11. ล้างข้อมูล (ไม่บังคับ)

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

ลบบริการ

gcloud run services delete $SERVICE_NAME -q

ลบทริกเกอร์ Eventarc

gcloud eventarc triggers delete trigger-$SERVICE_NAME -q

หรือจะลบทั้งโปรเจ็กต์ก็ได้โดยทำดังนี้

gcloud projects delete $GOOGLE_CLOUD_PROJECT

12. ยินดีด้วย

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

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

  • Cloud Run
  • Cloud Storage
  • Cloud Firestore
  • Eventarc