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