Membangun image container kustom untuk Dataflow

Dokumen ini menjelaskan cara membuat image container kustom untuk tugas Dataflow.

Persyaratan

Image container kustom untuk Dataflow harus memenuhi persyaratan berikut:

  • Apache Beam SDK dan dependensi yang diperlukan telah diinstal. Sebaiknya mulai dengan image Apache Beam SDK default. Untuk mengetahui informasi selengkapnya, lihat bagian Memilih image dasar dalam dokumen ini.
  • Skrip /opt/apache/beam/boot harus dijalankan sebagai langkah terakhir selama startup container. Skrip ini melakukan inisialisasi lingkungan pekerja dan memulai proses pekerja SDK. Skrip ini adalah ENTRYPOINT default pada image Apache Beam SDK. Namun, jika Anda menggunakan image dasar yang berbeda, atau jika Anda mengganti ENTRYPOINT default, Anda harus menjalankan skrip secara eksplisit. Untuk informasi selengkapnya, lihat Mengubah titik entri container dalam dokumen ini.
  • Image container Anda harus mendukung arsitektur VM pekerja untuk tugas Dataflow Anda. Jika Anda berencana menggunakan container kustom di VM ARM, sebaiknya buat image multi-arsitektur. Untuk mengetahui informasi selengkapnya, lihat Membuat image container multi-arsitektur.

Sebelum memulai

  1. Pastikan versi Apache Beam SDK yang diinstal mendukung Runner v2 dan versi bahasa Anda. Untuk mengetahui informasi selengkapnya, lihat Menginstal Apache Beam SDK.

  2. Untuk menguji image container secara lokal, Anda harus menginstal Docker. Untuk mengetahui informasi selengkapnya, baca bagian Mendapatkan Docker.

  3. Buat repositori Artifact Registry. Menentukan format image Docker. Anda harus memiliki setidaknya akses Artifact Registry Writer ke repositori.

    Untuk membuat repositori baru, jalankan perintah gcloud artifacts repositories create:

    gcloud artifacts repositories create REPOSITORY \
      --repository-format=docker \
      --location=REGION \
      --async
    

    Ganti kode berikut:

    • REPOSITORY: nama untuk repositori Anda. Nama repositori harus unik untuk setiap lokasi dalam project.
    • REGION: region untuk men-deploy tugas Dataflow. Pilih region Dataflow yang dekat dengan tempat Anda menjalankan perintah. Nilai harus berupa nama wilayah yang valid. Untuk mengetahui informasi selengkapnya tentang region dan lokasi, lihat Lokasi Dataflow.

    Contoh ini menggunakan flag --async. Perintah ini akan segera ditampilkan, tanpa menunggu operasi selesai.

  4. Untuk mengonfigurasi Docker guna mengautentikasi permintaan untuk Artifact Registry, jalankan perintah gcloud auth configure-docker:

    gcloud auth configure-docker REGION-docker.pkg.dev
    

    Perintah ini memperbarui konfigurasi Docker Anda. Sekarang Anda dapat terhubung dengan Artifact Registry di project Google Cloud untuk mengirim image.

Pilih image dasar

Sebaiknya mulai dengan image Apache Beam SDK sebagai image penampung dasar. Gambar ini dirilis sebagai bagian dari rilis Apache Beam ke Docker Hub.

Menggunakan image dasar Apache Beam

Untuk menggunakan image Apache Beam SDK sebagai image dasar, tentukan image container dalam petunjuk FROM, lalu tambahkan penyesuaian Anda sendiri.

Java

Contoh ini menggunakan Java 8 dengan Apache Beam SDK versi 2.55.1.

FROM apache/beam_java8_sdk:2.55.1

# Make your customizations here, for example:
ENV FOO=/bar
COPY path/to/myfile ./

Versi runtime penampung kustom harus cocok dengan runtime yang akan Anda gunakan untuk memulai pipeline. Misalnya, jika Anda akan memulai pipeline dari lingkungan Java 11 lokal, baris FROM harus menentukan lingkungan Java 11: apache/beam_java11_sdk:....

Python

Contoh ini menggunakan Python 3.10 dengan Apache Beam SDK versi 2.55.1.

FROM apache/beam_python3.10_sdk:2.55.1

# Make your customizations here, for example:
ENV FOO=/bar
COPY path/to/myfile ./

Versi runtime penampung kustom harus cocok dengan runtime yang akan Anda gunakan untuk memulai pipeline. Misalnya, jika Anda akan memulai pipeline dari lingkungan Python 3.10 lokal, baris FROM harus menentukan lingkungan Python 3.10: apache/beam_python3.10_sdk:....

Go

Contoh ini menggunakan Go dengan Apache Beam SDK versi 2.55.1.

FROM apache/beam_go_sdk:2.55.1

# Make your customizations here, for example:
ENV FOO=/bar
COPY path/to/myfile ./

Menggunakan image dasar kustom

Jika Anda ingin menggunakan image dasar yang berbeda, atau perlu mengubah beberapa aspek image Apache Beam default (seperti versi OS atau patch), gunakan proses build multistage. Salin artefak yang diperlukan dari image dasar Apache Beam default.

Tetapkan ENTRYPOINT untuk menjalankan skrip /opt/apache/beam/boot, yang menginisialisasi lingkungan pekerja dan memulai proses pekerja SDK. Jika Anda tidak menetapkan titik entri ini, pekerja Dataflow tidak akan memulai dengan benar.

Contoh berikut menunjukkan Dockerfile yang menyalin file dari Apache Beam SDK:

Java

FROM openjdk:8

# Copy files from official SDK image, including script/dependencies.
COPY --from=apache/beam_java8_sdk:2.55.1 /opt/apache/beam /opt/apache/beam

# Set the entrypoint to Apache Beam SDK launcher.
ENTRYPOINT ["/opt/apache/beam/boot"]

Python

FROM python:3.10-slim

# Install SDK.
RUN pip install --no-cache-dir apache-beam[gcp]==2.55.1

# Verify that the image does not have conflicting dependencies.
RUN pip check

# Copy files from official SDK image, including script/dependencies.
COPY --from=apache/beam_python3.10_sdk:2.55.1 /opt/apache/beam /opt/apache/beam

# Set the entrypoint to Apache Beam SDK launcher.
ENTRYPOINT ["/opt/apache/beam/boot"]

Contoh ini mengasumsikan bahwa dependensi yang diperlukan (dalam hal ini, Python 3.10 dan pip) telah diinstal pada image dasar yang ada. Menginstal Apache Beam SDK ke dalam gambar akan memastikan bahwa image tersebut memiliki dependensi SDK yang diperlukan dan mengurangi waktu startup pekerja.

Penting: Versi SDK yang ditentukan dalam petunjuk RUN dan COPY harus sesuai dengan versi yang digunakan untuk meluncurkan pipeline.

Go

FROM golang:latest

# Copy files from official SDK image, including script/dependencies.
COPY --from=apache/beam_go_sdk:2.55.1 /opt/apache/beam /opt/apache/beam

# Set the entrypoint to Apache Beam SDK launcher.
ENTRYPOINT ["/opt/apache/beam/boot"]

Mengubah titik entri container

Jika container Anda menjalankan skrip kustom selama startup container, skrip harus diakhiri dengan menjalankan /opt/apache/beam/boot. Argumen yang diteruskan oleh Dataflow selama startup container harus diteruskan ke skrip booting default. Contoh berikut menunjukkan skrip startup kustom yang memanggil skrip booting default:

#!/bin/bash

echo "This is my custom script"
# ...

# Pass command arguments to the default boot script.
/opt/apache/beam/boot "$@"

Di Dockerfile, tetapkan ENTRYPOINT untuk memanggil skrip Anda:

Java

FROM apache/beam_java8_sdk:2.55.1

COPY script.sh path/to/my/script.sh
ENTRYPOINT [ "path/to/my/script.sh" ]

Python

FROM apache/beam_python3.10_sdk:2.55.1

COPY script.sh path/to/my/script.sh
ENTRYPOINT [ "path/to/my/script.sh" ]

Go

FROM apache/beam_go_sdk:2.55.1

COPY script.sh path/to/my/script.sh
ENTRYPOINT [ "path/to/my/script.sh" ]

Membangun dan mengirim image

Anda dapat menggunakan Cloud Build atau Docker untuk membangun image container dan mengirimkannya ke repositori Artifact Registry.

Cloud Build

Untuk mem-build file dan mengirimnya ke repositori Artifact Registry, jalankan perintah gcloud builds submit:

  gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/dataflow/FILE_NAME:TAG .

Docker

docker build . --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/dataflow/FILE_NAME:TAG
docker push REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/dataflow/FILE_NAME:TAG

Ganti kode berikut:

  • REGION: region tempat men-deploy tugas Dataflow Anda. Nilai variabel REGION harus berupa nama wilayah yang valid.
  • PROJECT_ID: nama project atau nama pengguna.
  • REPOSITORY: nama repositori image.
  • FILE_NAME: nama Dockerfile Anda.
  • TAG: tag gambar. Selalu tentukan SHA atau tag container berversi. Jangan gunakan tag :latest atau tag yang dapat berubah.

Menginstal terlebih dahulu dependensi Python

Bagian ini berlaku untuk pipeline Python.

Saat meluncurkan tugas Python Dataflow, Anda dapat menentukan dependensi tambahan dengan menggunakan opsi --requirements_file atau --extra_packages saat runtime. Untuk mengetahui informasi selengkapnya, lihat Mengelola Dependensi Pipeline Python. Dependensi tambahan diinstal di setiap penampung pekerja Dataflow. Saat tugas pertama kali dimulai dan selama penskalaan otomatis, penginstalan dependensi sering kali menyebabkan penggunaan CPU yang tinggi dan periode pemanasan yang panjang pada semua pekerja Dataflow yang baru dimulai.

Untuk menghindari penginstalan dependensi berulang, Anda dapat mem-build image container Python SDK kustom dengan dependensi yang sudah diinstal sebelumnya. Anda dapat melakukan langkah ini pada waktu build dengan menggunakan Dockerfile, atau pada waktu proses saat Anda mengirimkan tugas.

Pekerja membuat lingkungan Python virtual baru saat mereka memulai container. Karena alasan ini, instal dependensi ke dalam lingkungan Python default (global), bukan membuat lingkungan virtual. Jika Anda mengaktifkan lingkungan virtual di image container, lingkungan ini mungkin tidak aktif saat tugas dimulai. Untuk informasi selengkapnya, lihat Masalah umum.

Prainstal menggunakan Dockerfile

Untuk menambahkan dependensi tambahan secara langsung ke container kustom Python, gunakan perintah berikut:

FROM apache/beam_python3.10_sdk:2.55.1

COPY requirements.txt .

# Pre-install Python dependencies. For reproducibile builds,
# supply all of the dependencies and their versions in a requirements.txt file.
RUN pip install -r requirements.txt

# You can also install individual dependencies.
RUN pip install lxml
# Pre-install other dependencies.
RUN apt-get update \
  && apt-get dist-upgrade \
  && apt-get install -y --no-install-recommends ffmpeg

Kirim tugas Anda dengan opsi pipeline --sdk_container_image dan --sdk_location. Opsi --sdk_location mencegah SDK didownload saat tugas Anda diluncurkan. SDK diambil langsung dari image container.

Contoh berikut menjalankan contoh pipeline wordcount:

python -m apache_beam.examples.wordcount \
  --input=INPUT_FILE \
  --output=OUTPUT_FILE \
  --project=PROJECT_ID \
  --region=REGION \
  --temp_location=TEMP_LOCATION \
  --runner=DataflowRunner \
  --experiments=use_runner_v2 \
  --sdk_container_image=IMAGE_URI
  --sdk_location=container

Ganti kode berikut:

  • INPUT_FILE: file input untuk pipeline
  • OUTPUT_FILE: jalur untuk menulis output
  • PROJECT_ID: project ID Google Cloud
  • REGION: region untuk men-deploy tugas Dataflow Anda di
  • TEMP_LOCATION: jalur Cloud Storage untuk Dataflow guna menyiapkan file tugas sementara
  • IMAGE_URI: URI image container kustom

Mem-build image container terlebih dahulu saat mengirimkan tugas

Dengan mem-build image container terlebih dahulu, Anda dapat menginstal terlebih dahulu dependensi pipeline sebelum tugas dimulai. Anda tidak perlu membangun image container kustom.

Untuk mem-build container dengan dependensi Python tambahan saat Anda mengirimkan tugas, gunakan opsi pipeline berikut:

  • --prebuild_sdk_container_engine=[cloud_build | local_docker]. Jika tanda ini ditetapkan, Apache Beam akan membuat container khusus dan menginstal semua dependensi yang ditentukan oleh --requirements_file dan opsi --extra_packages. Tanda ini mendukung nilai berikut:

    • cloud_build. Gunakan Cloud Build untuk membangun container. Cloud Build API harus diaktifkan di project Anda.
    • local_docker. Gunakan instalasi Docker lokal Anda untuk membangun container.
  • --docker_registry_push_url=IMAGE_PATH. Ganti IMAGE_PATH dengan folder Artifact Registry.

  • --sdk_location=container. Opsi ini mencegah pekerja mendownload SDK saat tugas Anda diluncurkan. Sebagai gantinya, SDK diambil langsung dari image container.

Contoh berikut menggunakan Cloud Build untuk mem-build image:

python -m apache_beam.examples.wordcount \
  --input=INPUT_FILE \
  --output=OUTPUT_FILE \
  --project=PROJECT_ID \
  --region=REGION \
  --temp_location=TEMP_LOCATION \
  --runner=DataflowRunner \
  --disk_size_gb=DISK_SIZE_GB \
  --experiments=use_runner_v2 \
  --requirements_file=./requirements.txt \
  --prebuild_sdk_container_engine=cloud_build \
  --docker_registry_push_url=IMAGE_PATH \
  --sdk_location=container

Fitur pra-build memerlukan Apache Beam SDK untuk Python versi 2.25.0 atau yang lebih baru.

Alur kerja pra-build image container SDK menggunakan image yang diteruskan menggunakan opsi pipeline --sdk_container_image sebagai image dasar. Jika opsi ini tidak ditetapkan, secara default image Apache Beam akan digunakan sebagai image dasar.

Anda dapat menggunakan kembali image container Python SDK bawaan di tugas lain dengan dependensi dan versi SDK yang sama. Untuk menggunakan kembali gambar tersebut, teruskan URL gambar container yang telah dibuat sebelumnya ke tugas lain menggunakan opsi pipeline --sdk_container_image. Hapus opsi dependensi --requirements_file, --extra_packages, dan --setup_file.

Jika Anda tidak berencana untuk menggunakan kembali gambar tersebut, hapus setelah tugas selesai. Anda dapat menghapus image dengan gcloud CLI atau di halaman Artifact Registry pada Konsol Google Cloud.

Jika image disimpan di Artifact Registry, gunakan perintah artifacts docker images delete:

   gcloud artifacts docker images delete IMAGE --delete-tags

Masalah umum

  • Jika tugas Anda memiliki dependensi Python tambahan dari mirror PyPi pribadi dan tidak dapat ditarik oleh tugas Cloud Build jarak jauh, coba gunakan opsi Docker lokal atau coba build container menggunakan Dockerfile.

  • Jika tugas Cloud Build gagal dengan docker exit code 137, tugas build akan kehabisan memori, kemungkinan karena ukuran dependensi yang diinstal. Gunakan jenis mesin pekerja Cloud Build yang lebih besar dengan meneruskan --cloud_build_machine_type=machine_type, dengan machine_type sebagai salah satu opsi berikut:

    • n1-highcpu-8
    • n1-highcpu-32
    • e2-highcpu-8
    • e2-highcpu-32

    Secara default, Cloud Build menggunakan jenis mesin e2-medium.

  • Pada Apache Beam 2.44.0 dan yang lebih baru, pekerja membuat lingkungan virtual saat memulai container kustom. Jika container membuat lingkungan virtualnya sendiri untuk menginstal dependensi, dependensi tersebut akan dihapus. Perilaku ini dapat menyebabkan error seperti berikut:

    ModuleNotFoundError: No module named '<dependency name>'

    Untuk menghindari masalah ini, instal dependensi ke lingkungan Python default (global). Sebagai solusinya, nonaktifkan perilaku ini di Beam 2.48.0 dan yang lebih baru dengan menetapkan variabel lingkungan berikut di image container Anda:

    ENV RUN_PYTHON_SDK_IN_DEFAULT_ENVIRONMENT=1

Langkah selanjutnya