Memulai tugas Cloud Run

1. Pengantar

96d07289bb51daa7.png

Ringkasan

Meskipun layanan Cloud Run sangat cocok untuk container yang menjalankan pemrosesan permintaan HTTP tanpa batas waktu, tugas Cloud Run mungkin lebih cocok untuk container yang dijalankan hingga selesai 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.

Alur Kerja Tugas

Sangat mudah untuk menggunakan tugas Cloud Run, dengan hanya melibatkan dua langkah:

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

Batasan Pratinjau

Selama pratinjau, tugas Cloud Run memiliki batasan berikut:

  • Maksimum 50 eksekusi (dari tugas yang sama atau berbeda) dapat berjalan serentak per project per region.
  • Anda dapat melihat tugas yang ada, memulai eksekusi, dan memantau status eksekusi dari halaman Tugas Cloud Run di Cloud Console. Gunakan gcloud untuk membuat tugas baru karena Cloud Console saat ini tidak mendukung pembuatan tugas baru.
  • Jangan gunakan tugas Cloud Run untuk beban kerja produksi. Tidak ada jaminan keandalan atau jaminan performa. Tugas Cloud Run dapat berubah sehingga tidak kompatibel dengan versi sebelumnya, dengan sedikit pemberitahuan sebelum GA.

Dalam codelab ini, Anda akan mempelajari aplikasi Node.js terlebih dahulu untuk mengambil screenshot halaman web dan menyimpannya ke Cloud Storage. Selanjutnya, Anda akan mem-build image container untuk aplikasi, menjalankannya sebagai tugas di 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.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Nama project adalah nama tampilan untuk peserta project ini. String ini adalah string karakter yang tidak digunakan oleh Google API, dan Anda dapat memperbaruinya kapan saja.
  • Project ID harus unik di semua project Google Cloud dan tidak dapat diubah (tidak dapat diubah setelah ditetapkan). Cloud Console otomatis menghasilkan string unik; biasanya Anda tidak peduli dengan kata-katanya. Pada sebagian besar codelab, Anda harus mereferensikan Project ID (dan biasanya diidentifikasi sebagai PROJECT_ID). Jadi, jika Anda tidak menyukainya, buat ID acak lain, atau, Anda dapat mencoba sendiri dan melihat apakah tersedia. Kemudian file akan "dibekukan" setelah project dibuat.
  • Ada nilai ketiga, Nomor Project yang digunakan oleh beberapa API. Pelajari lebih lanjut ketiga nilai ini di dokumentasi.
  1. Selanjutnya, Anda harus mengaktifkan penagihan di Cloud Console untuk menggunakan API/resource Cloud. Menjalankan operasi dalam codelab ini seharusnya tidak memerlukan banyak biaya, bahkan mungkin tidak sama sekali. Untuk menonaktifkan resource agar tidak menimbulkan penagihan di luar tutorial ini, ikuti petunjuk "pembersihan" yang ada di akhir codelab. 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:

55efc1aaa7a4d3ad.png

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

7ffe5cbb04455448.png

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 di lab ini dapat dilakukan hanya dengan browser.

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. Anda dapat memilih region dari salah satu lokasi Cloud Run.

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

Aktifkan 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.

f78880c00c0af1ef.png

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 node:17-alpine

# Installs latest Chromium (92) package.
RUN apk add --no-cache \
      chromium \
      nss \
      freetype \
      harfbuzz \
      ca-certificates \
      ttf-freefont \
      nodejs \
      npm

# Tell Puppeteer to skip installing Chrome. We'll be using the installed package.
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \
    PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser

# Add user so we don't need --no-sandbox.
RUN addgroup -S pptruser && adduser -S -g pptruser pptruser \
    && mkdir -p /home/pptruser/Downloads /app \
    && chown -R pptruser:pptruser /home/pptruser \
    && chown -R pptruser:pptruser /app

# Install dependencies
COPY package*.json ./
RUN npm install

# Copy all files
COPY . .

# Run everything after as a non-privileged user.
USER pptruser

ENTRYPOINT ["node", "screenshot.js"]

5. Membuat dan memublikasikan image container

Artifact Registry adalah layanan penyimpanan dan pengelolaan image container di Google Cloud. Lihat Bekerja dengan gambar container untuk informasi selengkapnya. Artifact Registry dapat menyimpan image container Docker dan OCI dalam repositori Docker.

Buat repositori Artifact Registry baru yang disebut containers:

gcloud artifacts repositories create containers --repository-format=docker --location=$REGION

Buat dan publikasikan image container:

gcloud builds submit -t $REGION-docker.pkg.dev/$PROJECT_ID/containers/screenshot:v1

Setelah beberapa menit, Anda akan melihat image container yang di-build dan dihosting di Artifact Registry.

62e50ebe805f9a9c.png

6. Buat 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

Anda kini siap untuk membuat tugas Cloud Run yang menyertakan konfigurasi yang diperlukan untuk menjalankan tugas.

gcloud beta run jobs create screenshot \
  --image=$REGION-docker.pkg.dev/$PROJECT_ID/containers/screenshot:v1 \
  --args="https://example.com" \
  --args="https://cloud.google.com" \
  --tasks=2 \
  --task-timeout=5m \
  --set-env-vars=BUCKET_NAME=screenshot-$PROJECT_ID \
  --service-account=screenshot-sa@$PROJECT_ID.iam.gserviceaccount.com

Tindakan ini akan 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 1 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.

7. Menjalankan tugas

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

gcloud beta run jobs list

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

Jalankan tugas dengan perintah berikut:

gcloud beta run jobs execute screenshot

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

gcloud beta run jobs executions list --job screenshot

...
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 beta run jobs executions describe screenshot-znkmm
✔ 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:

e59ed4e532b974b1.png

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

f2f86e60b94ba47c.png

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 beta run jobs executions delete screenshot-znkmm

8 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 beta run jobs update screenshot \
  --args="https://www.pinterest.com" \
  --args="https://www.apartmenttherapy.com" \
  --args="https://www.google.com" \
  --tasks=3

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

gcloud beta run jobs execute screenshot --wait

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

ce91c96dcfd271bb.png

9. Menjadwalkan tugas

Sejauh ini, codelab ini menunjukkan tugas yang berjalan secara manual. Dalam skenario dunia nyata, Anda mungkin ingin menjalankan pekerjaan sebagai respons terhadap suatu peristiwa atau sesuai jadwal. Anda dapat melakukannya melalui Cloud Run REST API. Mari kita lihat cara menjalankan tugas screenshot sesuai jadwal menggunakan Cloud Scheduler.

Pertama, pastikan Cloud Scheduler API diaktifkan:

gcloud services enable cloudscheduler.googleapis.com

Buat tugas Cloud Scheduler untuk menjalankan tugas Cloud Run setiap hari pukul 09.00:

PROJECT_NUMBER="$(gcloud projects describe $(gcloud config get-value project) --format='value(projectNumber)')"

gcloud scheduler jobs create http screenshot-scheduled --schedule "0 9 * * *" \
   --http-method=POST \
   --uri=https://$REGION-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/$PROJECT_ID/jobs/screenshot:run \
   --oauth-service-account-email=$PROJECT_NUMBER-compute@developer.gserviceaccount.com \
   --location $REGION

Pastikan bahwa tugas Cloud Scheduler telah dibuat dan siap untuk memanggil tugas Cloud Run:

gcloud scheduler jobs list

ID: screenshot-scheduled
LOCATION: $REGION
SCHEDULE (TZ): 0 9 * * * (Etc/UTC)
TARGET_TYPE: HTTP
STATE: ENABLED

Untuk menguji, picu Cloud Scheduler secara manual:

gcloud scheduler jobs run screenshot-scheduled

Dalam beberapa detik, Anda akan melihat 3 screenshot lainnya yang ditambahkan oleh panggilan dari Cloud Scheduler:

971ea598020cf9ba.png

10. Selamat

Selamat, Anda telah menyelesaikan codelab!

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.