Memulai tugas Cloud Run

1. Pengantar

1965fab24c502bd5.png

Ringkasan

Layanan Cloud Run sangat cocok untuk container yang menjalankan pemrosesan permintaan HTTP tanpa batas waktu, sedangkan tugas Cloud Run lebih cocok untuk container yang berjalan hingga selesai (saat ini hingga 24 jam) dan tidak melayani permintaan. Misalnya, memproses record dari database, memproses daftar file dari bucket Cloud Storage, atau operasi yang berjalan lama, seperti menghitung Pi, akan berfungsi dengan baik jika diterapkan sebagai tugas Cloud Run.

Tugas tidak memiliki kemampuan untuk melayani permintaan atau memproses port. Ini berarti bahwa tidak seperti layanan Cloud Run, tugas tidak boleh memaketkan server web. Sebaliknya, container tugas akan keluar setelah selesai.

Pada tugas Cloud Run, Anda dapat menjalankan beberapa salinan container secara paralel dengan menentukan sejumlah tugas. Setiap tugas mewakili satu salinan container yang berjalan. Menggunakan beberapa tugas akan berguna jika setiap tugas dapat memproses subkumpulan data Anda secara independen. Misalnya, memproses 10.000 data dari Cloud SQL atau 10.000 file dari Cloud Storage dapat dilakukan lebih cepat dengan 10 tugas memproses 1.000 data atau file, masing-masing secara paralel.

Penggunaan tugas Cloud Run memiliki dua langkah:

  1. Buat tugas: Tindakan ini merangkum semua konfigurasi yang diperlukan untuk menjalankan tugas, seperti image container, region, variabel lingkungan.
  2. Jalankan tugas: Tindakan ini akan membuat eksekusi tugas yang baru. Secara opsional, siapkan tugas Anda agar berjalan sesuai jadwal menggunakan Cloud Scheduler.

Dalam codelab ini, Anda akan mempelajari aplikasi Node.js terlebih dahulu untuk mengambil screenshot halaman web dan menyimpannya ke Cloud Storage. Selanjutnya, Anda akan membangun image container untuk aplikasi, menjalankannya di tugas Cloud Run, mengupdate tugas untuk memproses lebih banyak halaman web, dan menjalankan tugas sesuai jadwal dengan Cloud Scheduler.

Yang akan Anda pelajari

  • Cara menggunakan aplikasi untuk mengambil screenshot halaman web.
  • Cara membuat image container untuk aplikasi.
  • Cara membuat tugas Cloud Run untuk aplikasi.
  • Cara menjalankan aplikasi sebagai tugas Cloud Run.
  • Cara memperbarui tugas.
  • Cara menjadwalkan tugas dengan Cloud Scheduler.

2. Penyiapan dan Persyaratan

Penyiapan lingkungan mandiri

  1. Login ke Google Cloud Console dan buat project baru atau gunakan kembali project yang sudah ada. Jika belum memiliki akun Gmail atau Google Workspace, Anda harus membuatnya.

295004821bab6a87.pngS

37d264871000675d.png

96d86d3d5655cdbe.pngS

  • Project name adalah nama tampilan untuk peserta project ini. String ini adalah string karakter yang tidak digunakan oleh Google API. Anda dapat memperbaruinya kapan saja.
  • Project ID bersifat unik di semua project Google Cloud dan tidak dapat diubah (tidak dapat diubah setelah ditetapkan). Cloud Console otomatis membuat string unik; biasanya Anda tidak mementingkan kata-katanya. Di sebagian besar codelab, Anda harus merujuk Project ID-nya (umumnya diidentifikasi sebagai PROJECT_ID). Jika tidak suka dengan ID yang dibuat, Anda dapat membuat ID acak lainnya. Atau, Anda dapat mencobanya sendiri, dan lihat apakah ID tersebut tersedia. ID tidak dapat diubah setelah langkah ini dan tersedia selama durasi project.
  • Sebagai informasi, ada nilai ketiga, Project Number, yang digunakan oleh beberapa API. Pelajari lebih lanjut ketiga nilai ini di dokumentasi.
  1. Selanjutnya, Anda harus mengaktifkan penagihan di Konsol Cloud untuk menggunakan resource/API Cloud. Menjalankan operasi dalam codelab ini tidak akan memakan banyak biaya, bahkan mungkin tidak sama sekali. Guna mematikan resource agar tidak menimbulkan penagihan di luar tutorial ini, Anda dapat menghapus resource yang dibuat atau menghapus project-nya. Pengguna baru Google Cloud memenuhi syarat untuk mengikuti program Uji Coba Gratis senilai $300 USD.

Mulai Cloud Shell

Meskipun Google Cloud dapat dioperasikan dari jarak jauh menggunakan laptop Anda, dalam codelab ini, Anda akan menggunakan Google Cloud Shell, lingkungan command line yang berjalan di Cloud.

Dari Google Cloud Console, klik ikon Cloud Shell di toolbar kanan atas:

84688aa223b1c3a2.pngS

Hanya perlu waktu beberapa saat untuk penyediaan dan terhubung ke lingkungan. Jika sudah selesai, Anda akan melihat tampilan seperti ini:

320e18fedb7fbe0.pngS

Mesin virtual ini berisi semua alat pengembangan yang Anda perlukan. Layanan ini menawarkan direktori beranda tetap sebesar 5 GB dan beroperasi di Google Cloud, sehingga sangat meningkatkan performa dan autentikasi jaringan. Semua pekerjaan Anda dalam codelab ini dapat dilakukan di browser. Anda tidak perlu menginstal apa pun.

Menyiapkan gcloud

Di Cloud Shell, tetapkan project ID Anda dan region tempat Anda ingin men-deploy tugas Cloud Run. Simpan sebagai variabel PROJECT_ID dan REGION. Di masa mendatang, Anda dapat memilih region dari salah satu lokasi Cloud Run.

PROJECT_ID=[YOUR-PROJECT-ID]
REGION=us-central1
gcloud config set core/project $PROJECT_ID

Mengaktifkan API

Aktifkan semua layanan yang diperlukan:

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

3. Mendapatkan kode

Pertama-tama, Anda akan mempelajari aplikasi Node.js terlebih dahulu untuk mengambil screenshot halaman web dan menyimpannya ke Cloud Storage. Kemudian, Anda membuat image container untuk aplikasi dan menjalankannya sebagai tugas di Cloud Run.

Dari Cloud Shell, jalankan perintah berikut untuk membuat clone kode aplikasi dari repo ini:

git clone https://github.com/GoogleCloudPlatform/jobs-demos.git

Buka direktori yang berisi aplikasi:

cd jobs-demos/screenshot

Anda akan melihat tata letak file ini:

screenshot
 |
 ├── Dockerfile
 ├── README.md
 ├── screenshot.js
 ├── package.json

Berikut deskripsi singkat dari setiap file:

  • screenshot.js berisi kode Node.js untuk aplikasi.
  • package.json menentukan dependensi library.
  • Dockerfile menentukan image container.

4. Mempelajari kode

Untuk mempelajari kode tersebut, gunakan editor teks bawaan dengan mengklik tombol Open Editor di bagian atas jendela Cloud Shell.

15a2cdc9b7f6dfc6.pngS

Berikut penjelasan singkat dari setiap file.

screenshot.js

screenshot.js menambahkan Puppeteer dan Cloud Storage sebagai dependensi terlebih dahulu. Puppeteer adalah library Node.js yang Anda gunakan untuk mengambil screenshot halaman web:

const puppeteer = require('puppeteer');
const {Storage} = require('@google-cloud/storage');

Ada fungsi initBrowser untuk menginisialisasi Puppeteer dan fungsi takeScreenshot untuk mengambil screenshot URL tertentu:

async function initBrowser() {
  console.log('Initializing browser');
  return await puppeteer.launch();
}

async function takeScreenshot(browser, url) {
  const page = await browser.newPage();

  console.log(`Navigating to ${url}`);
  await page.goto(url);

  console.log(`Taking a screenshot of ${url}`);
  return await page.screenshot({
    fullPage: true
  });
}

Selanjutnya, ada fungsi untuk mendapatkan atau membuat bucket Cloud Storage dan fungsi lainnya untuk mengupload screenshot halaman web ke bucket:

async function createStorageBucketIfMissing(storage, bucketName) {
  console.log(`Checking for Cloud Storage bucket '${bucketName}' and creating if not found`);
  const bucket = storage.bucket(bucketName);
  const [exists] = await bucket.exists();
  if (exists) {
    // Bucket exists, nothing to do here
    return bucket;
  }

  // Create bucket
  const [createdBucket] = await storage.createBucket(bucketName);
  console.log(`Created Cloud Storage bucket '${createdBucket.name}'`);
  return createdBucket;
}

async function uploadImage(bucket, taskIndex, imageBuffer) {
  // Create filename using the current time and task index
  const date = new Date();
  date.setMinutes(date.getMinutes() - date.getTimezoneOffset());
  const filename = `${date.toISOString()}-task${taskIndex}.png`;

  console.log(`Uploading screenshot as '${filename}'`)
  await bucket.file(filename).save(imageBuffer);
}

Terakhir, fungsi main adalah titik entri:

async function main(urls) {
  console.log(`Passed in urls: ${urls}`);

  const taskIndex = process.env.CLOUD_RUN_TASK_INDEX || 0;
  const url = urls[taskIndex];
  if (!url) {
    throw new Error(`No url found for task ${taskIndex}. Ensure at least ${parseInt(taskIndex, 10) + 1} url(s) have been specified as command args.`);
  }
  const bucketName = process.env.BUCKET_NAME;
  if (!bucketName) {
    throw new Error('No bucket name specified. Set the BUCKET_NAME env var to specify which Cloud Storage bucket the screenshot will be uploaded to.');
  }

  const browser = await initBrowser();
  const imageBuffer = await takeScreenshot(browser, url).catch(async err => {
    // Make sure to close the browser if we hit an error.
    await browser.close();
    throw err;
  });
  await browser.close();

  console.log('Initializing Cloud Storage client')
  const storage = new Storage();
  const bucket = await createStorageBucketIfMissing(storage, bucketName);
  await uploadImage(bucket, taskIndex, imageBuffer);

  console.log('Upload complete!');
}

main(process.argv.slice(2)).catch(err => {
  console.error(JSON.stringify({severity: 'ERROR', message: err.message}));
  process.exit(1);
});

Perhatikan hal berikut tentang metode main:

  • URL diteruskan sebagai argumen.
  • Nama bucket diteruskan sebagai variabel lingkungan BUCKET_NAME buatan pengguna. Nama bucket harus unik secara global di semua Google Cloud.
  • Variabel lingkungan CLOUD_RUN_TASK_INDEX diteruskan oleh tugas Cloud Run. Tugas Cloud Run dapat menjalankan beberapa salinan aplikasi sebagai tugas unik. CLOUD_RUN_TASK_INDEX merepresentasikan indeks tugas yang sedang berjalan. Setelan defaultnya adalah nol saat kode dijalankan di luar tugas Cloud Run. Saat aplikasi dijalankan sebagai beberapa tugas, setiap tugas/container mengambil URL yang menjadi tanggung jawabnya, mengambil screenshot, dan menyimpan gambar ke bucket.

package.json

File package.json menentukan aplikasi dan menentukan dependensi untuk Cloud Storage dan Puppeteer:

{
  "name": "screenshot",
  "version": "1.0.0",
  "description": "Create a job to capture screenshots",
  "main": "screenshot.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Google LLC",
  "license": "Apache-2.0",
  "dependencies": {
    "@google-cloud/storage": "^5.18.2",
    "puppeteer": "^13.5.1"
  }
}

Dockerfile

Dockerfile menentukan image container untuk aplikasi dengan semua library dan dependensi yang diperlukan:

FROM ghcr.io/puppeteer/puppeteer:16.1.0
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
ENTRYPOINT ["node", "screenshot.js"]

5. Men-deploy tugas

Sebelum membuat tugas, Anda perlu membuat akun layanan yang akan digunakan untuk menjalankan tugas tersebut.

gcloud iam service-accounts create screenshot-sa --display-name="Screenshot app service account"

Beri peran storage.admin ke akun layanan agar dapat digunakan untuk membuat bucket dan objek.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --role roles/storage.admin \
  --member serviceAccount:screenshot-sa@$PROJECT_ID.iam.gserviceaccount.com

Sekarang Anda siap untuk men-deploy tugas Cloud Run yang menyertakan konfigurasi yang diperlukan untuk menjalankan tugas.

gcloud beta run jobs deploy screenshot \
  --source=. \
  --args="https://example.com" \
  --args="https://cloud.google.com" \
  --tasks=2 \
  --task-timeout=5m \
  --region=$REGION \
  --set-env-vars=BUCKET_NAME=screenshot-$PROJECT_ID \
  --service-account=screenshot-sa@$PROJECT_ID.iam.gserviceaccount.com

Perintah ini menggunakan deployment berbasis sumber dan membuat tugas Cloud Run tanpa menjalankannya.

Perhatikan cara halaman web diteruskan sebagai argumen. Nama bucket untuk menyimpan screenshot diteruskan sebagai variabel lingkungan.

Anda dapat menjalankan beberapa salinan container secara paralel dengan menentukan sejumlah tugas untuk dijalankan dengan tanda --tasks. Setiap tugas mewakili satu salinan container yang berjalan. Menggunakan beberapa tugas akan berguna jika setiap tugas dapat memproses subkumpulan data Anda secara independen. Untuk memfasilitasi hal ini, setiap tugas mengetahui indeksnya, yang disimpan di variabel lingkungan CLOUD_RUN_TASK_INDEX. Kode Anda bertanggung jawab untuk menentukan tugas mana yang menangani subkumpulan data. Perhatikan --tasks=2 pada contoh ini. Ini memastikan 2 container berjalan untuk 2 URL yang ingin kami proses.

Setiap tugas dapat berjalan hingga 24 jam. Anda dapat mengurangi waktu tunggu ini menggunakan tanda --task-timeout, seperti yang kami lakukan dalam contoh ini. Semua tugas harus berhasil agar tugas berhasil diselesaikan. Secara default, tugas yang gagal tidak akan dicoba lagi. Anda dapat mengonfigurasi tugas agar dicoba lagi jika gagal. Jika tugas apa pun melebihi jumlah percobaan ulang, seluruh tugas akan gagal.

Secara default, tugas Anda akan berjalan dengan sebanyak mungkin tugas secara paralel. Jumlah tugas ini akan sama dengan jumlah tugas untuk tugas Anda, maksimal 100. Anda mungkin ingin menyetel paralelisme lebih rendah untuk tugas yang mengakses backend dengan skalabilitas terbatas. Misalnya, database yang mendukung koneksi aktif dalam jumlah terbatas. Anda dapat menurunkan paralelisme dengan tanda --parallelism.

6. Menjalankan tugas

Sebelum menjalankan tugas, cantumkan tugas untuk melihat bahwa tugas tersebut telah dibuat:

gcloud run jobs list

✔
JOB: screenshot
REGION: us-central
LAST RUN AT:
CREATED: 2022-02-22 12:20:50 UTC

Jalankan tugas dengan perintah berikut:

gcloud run jobs execute screenshot --region=$REGION

Tindakan ini akan menjalankan tugas. Anda dapat mencantumkan eksekusi saat ini dan sebelumnya:

gcloud run jobs executions list --job screenshot --region=$REGION

...
JOB: screenshot
EXECUTION: screenshot-znkmm
REGION: $REGION
RUNNING: 1
COMPLETE: 1 / 2
CREATED: 2022-02-22 12:40:42 UTC

Jelaskan eksekusinya. Anda akan melihat tanda centang hijau dan pesan tasks completed successfully:

gcloud run jobs executions describe screenshot-znkmm --region=$REGION

✔ Execution screenshot-znkmm in region $REGION
2 tasks completed successfully


Image:           $REGION-docker.pkg.dev/$PROJECT_ID/containers/screenshot at 311b20d9...
Tasks:           2
Args:            https://example.com https://cloud.google.com
Memory:          1Gi
CPU:             1000m
Task Timeout:    3600s
Parallelism:     2
Service account: 11111111-compute@developer.gserviceaccount.com
Env vars:
  BUCKET_NAME    screenshot-$PROJECT_ID

Anda juga dapat memeriksa halaman tugas Cloud Run di Cloud Console untuk melihat statusnya:

1afde14d65f0d9ce.pngS

Jika Anda memeriksa bucket Cloud Storage, Anda akan melihat dua file screenshot dibuat:

7c4d355f6f65106.pngS

Terkadang Anda mungkin perlu menghentikan eksekusi sebelum selesai - mungkin karena Anda menyadari bahwa tugas harus dijalankan dengan parameter yang berbeda atau ada kesalahan dalam kode, dan Anda tidak ingin menggunakan waktu komputasi yang tidak perlu.

Untuk menghentikan eksekusi tugas, Anda perlu menghapus eksekusi:

gcloud run jobs executions delete screenshot-znkmm --region=$REGION

7. Memperbarui tugas

Versi baru container Anda tidak otomatis diambil oleh tugas Cloud Run dalam eksekusi berikutnya. Jika Anda mengubah kode untuk tugas Anda, Anda perlu membangun ulang container dan memperbarui tugas Anda. Menggunakan gambar yang diberi tag akan membantu Anda mengidentifikasi versi gambar yang saat ini digunakan.

Demikian pula, Anda juga harus memperbarui tugas jika ingin memperbarui beberapa variabel konfigurasi. Eksekusi tugas berikutnya akan menggunakan setelan konfigurasi dan container baru.

Perbarui tugas dan ubah halaman tempat screenshot diambil aplikasi di tanda --args. Perbarui juga tanda --tasks untuk mencerminkan jumlah halaman.

gcloud run jobs update screenshot \
  --args="https://www.pinterest.com" \
  --args="https://www.apartmenttherapy.com" \
  --args="https://www.google.com" \
  --region=$REGION \
  --tasks=3

Jalankan kembali tugas tersebut. Kali ini teruskan tanda --wait untuk menunggu eksekusi selesai:

gcloud run jobs execute screenshot --region=$REGION --wait

Setelah beberapa detik, Anda akan melihat 3 screenshot lainnya yang ditambahkan ke bucket:

ed0cbe0b5a5f9144.png

8. Menjadwalkan tugas

Sejauh ini, Anda menjalankan tugas secara manual. Dalam skenario dunia nyata, Anda mungkin ingin menjalankan pekerjaan sebagai respons terhadap suatu peristiwa atau sesuai jadwal. Mari kita lihat cara menjalankan tugas screenshot sesuai jadwal menggunakan Cloud Scheduler.

Pertama, pastikan Cloud Scheduler API diaktifkan:

gcloud services enable cloudscheduler.googleapis.com

Buka halaman detail tugas Cloud Run dan klik bagian Triggers:

3ae456368905472f.pngS

Pilih tombol Add Scheduler Trigger:

48cbba777f75e1eb.pngS

Sebuah panel akan terbuka di sebelah kanan. Buat tugas Scheduler untuk dijalankan setiap hari pada pukul 09.00 dengan konfigurasi ini, lalu pilih Continue:

81fd098be0db216.pngS

Di halaman berikutnya, pilih akun layanan komputasi default, lalu pilih Create:

fe479501dfb91f9f.png

Sekarang Anda akan melihat pemicu Cloud Scheduler baru yang dibuat:

5a7bc6d96b970b92.pngS

Klik View Details untuk membuka halaman Cloud Scheduler.

Anda dapat menunggu hingga pukul 09.00 agar penjadwal dimulai atau Anda dapat memicu Cloud Scheduler secara manual dengan memilih Force Run:

959525f2c8041a6a.pngS

Setelah beberapa detik, Anda akan melihat tugas Cloud Scheduler berhasil dijalankan:

d64e03fc84d61145.png

Anda juga akan melihat 3 screenshot lainnya yang ditambahkan oleh panggilan dari Cloud Scheduler:

56398a0e827de8b0.pngS

9. Selamat

Selamat, Anda telah menyelesaikan codelab!

Pembersihan (Opsional)

Untuk menghindari timbulnya biaya, sebaiknya bersihkan sumber daya.

Jika tidak memerlukan project, Anda cukup menghapus project:

gcloud projects delete $PROJECT_ID

Jika memerlukan project, Anda dapat menghapus resource satu per satu.

Hapus kode sumber:

rm -rf ~/jobs-demos/

Hapus repositori Artifact Registry:

gcloud artifacts repositories delete containers --location=$REGION

Hapus akun layanan:

gcloud iam service-accounts delete screenshot-sa@$PROJECT_ID.iam.gserviceaccount.com

Hapus tugas Cloud Run:

gcloud run jobs delete screenshot --region=$REGION

Hapus tugas Cloud Scheduler:

gcloud scheduler jobs delete screenshot-scheduler-trigger --location=$REGION

Hapus bucket Cloud Storage:

gcloud storage rm --recursive gs://screenshot-$PROJECT_ID

Yang telah kita bahas

  • Cara menggunakan aplikasi untuk mengambil screenshot halaman web.
  • Cara membuat image container untuk aplikasi.
  • Cara membuat tugas Cloud Run untuk aplikasi.
  • Cara menjalankan aplikasi sebagai tugas Cloud Run.
  • Cara memperbarui tugas.
  • Cara menjadwalkan tugas dengan Cloud Scheduler.