コンテナ環境

Beam SDKランタイム環境は、他のランタイムシステムから分離するために、コンテナ化してDockerを使用できます。コンテナ環境の詳細については、Beam SDK Harnessコンテナ契約をご覧ください。

事前に構築されたSDKコンテナイメージは、サポートされている言語ごとにBeamリリース中にリリースされ、Docker Hubにプッシュされます。

カスタムコンテナ

コンテナイメージをカスタマイズしたい理由はたくさんあります。例:

このガイドでは、Beam SDKのカスタマイズされたコンテナを作成および使用する方法について説明します。

前提条件

**注**:2020年11月20日、Docker Hubは匿名および無料の認証済み使用に対してレート制限を施行しました。これは、コンテナを複数回プルする大規模なパイプラインに影響を与える可能性があります。

最適なユーザーエクスペリエンスを得るには、Beamの最新リリースバージョンを使用することをお勧めします。

カスタムコンテナのビルドとプッシュ

Beam SDKコンテナイメージは、GithubリポジトリにチェックインされたDockerfileからビルドされ、すべてのリリースでDocker Hubに公開されます。カスタマイズされたコンテナは、次の3つの方法のいずれかでビルドできます。

  1. **リリースされたコンテナイメージに基づいて新しいDockerfileを作成する**。これは、アーティファクトや環境変数を追加するなど、イメージに簡単な追加を行うのに十分です。
  2. **BeamのソースDockerfileを変更する**。この方法では、Beamソースからビルドする必要がありますが、コンテナをより詳細にカスタマイズできます(アーティファクトの置換やベースOS/言語バージョンの変更を含む)。
  3. **既存のコンテナイメージを変更してApache Beamランナーと互換性を持たせる**。この方法は、ユーザーが既存のイメージから開始し、Apache Beamランナーと互換性を持つようにイメージを設定する場合に使用されます。

既存の公開コンテナイメージに基づいて新しいDockerfileを作成する

  1. FROM命令を使用してベースイメージを指定する新しいDockerfileを作成します。
FROM apache/beam_python3.7_sdk:2.25.0

ENV FOO=bar
COPY /src/path/to/file /dest/path/to/file/

この`Dockerfile`は、(SDKバージョン)`2.25.0`でタグ付けされた事前に構築されたPython 3.7 SDKコンテナイメージ`beam_python3.7_sdk`を使用し、イメージに追加の環境変数とファイルを追加します。

  1. Dockerを使用してイメージをビルドし、プッシュします。
export BASE_IMAGE="apache/beam_python3.7_sdk:2.25.0"
export IMAGE_NAME="myremoterepo/mybeamsdk"
# Avoid using `latest` with custom containers to make reproducing failures easier.
export TAG="mybeamsdk-versioned-tag"

# Optional - pull the base image into your local Docker daemon to ensure
# you have the most up-to-date version of the base image locally.
docker pull "${BASE_IMAGE}"

docker build -f Dockerfile -t "${IMAGE_NAME}:${TAG}" .
  1. ランナーがリモートで実行されている場合は、イメージにタグを付け直し、適切なリポジトリにプッシュします。
docker push "${IMAGE_NAME}:${TAG}"
  1. コンテナイメージをプッシュした後、リモートイメージIDとダイジェストが、`docker build`または`docker images`からの出力であるローカルイメージIDとダイジェストと一致することを確認します。

BeamのソースDockerfileを変更する

この方法では、Beamソースからイメージアーティファクトをビルドする必要があります。開発環境のセットアップの詳細については、貢献ガイドを参照してください。

**注**:パイプラインを実行するには、SDKの同じバージョンに対応する安定したリリースブランチ(`release-X.XX.X`)から開始することをお勧めします。SDKバージョンの違いは、予期しないエラーにつながる可能性があります。

  1. `beam`リポジトリのクローンを作成します。
export BEAM_SDK_VERSION="2.26.0"
git clone https://github.com/apache/beam.git
cd beam

# Save current directory as working directory
export BEAM_WORKDIR=$PWD

git checkout origin/release-$BEAM_SDK_VERSION
  1. 通常は`sdks/<language>/container/Dockerfile`ディレクトリ(例:PythonのDockerfile)にある、特定の言語の`Dockerfile`をカスタマイズします。

  2. ルートの Beam ディレクトリに戻り、イメージの Gradle docker ターゲットを実行します。

cd $BEAM_WORKDIR

# The default repository of each SDK
./gradlew :sdks:java:container:java11:docker
./gradlew :sdks:java:container:java17:docker
./gradlew :sdks:java:container:java21:docker
./gradlew :sdks:go:container:docker
./gradlew :sdks:python:container:py39:docker
./gradlew :sdks:python:container:py310:docker
./gradlew :sdks:python:container:py311:docker
./gradlew :sdks:python:container:py312:docker

# Shortcut for building all Python SDKs
./gradlew :sdks:python:container:buildAll
  1. docker images を実行して、ビルドしたイメージが作成されたことを確認します。
$> docker images --digests
REPOSITORY                         TAG                  DIGEST                   IMAGE ID         CREATED           SIZE
apache/beam_java8_sdk              latest               sha256:...               ...              1 min ago         ...
apache/beam_java11_sdk             latest               sha256:...               ...              1 min ago         ...
apache/beam_java17_sdk             latest               sha256:...               ...              1 min ago         ...
apache/beam_python3.6_sdk          latest               sha256:...               ...              1 min ago         ...
apache/beam_python3.7_sdk          latest               sha256:...               ...              1 min ago         ...
apache/beam_python3.8_sdk          latest               sha256:...               ...              1 min ago         ...
apache/beam_python3.9_sdk          latest               sha256:...               ...              1 min ago         ...
apache/beam_python3.10_sdk          latest               sha256:...               ...              1 min ago         ...
apache/beam_go_sdk                 latest               sha256:...               ...              1 min ago         ...
  1. ランナーがリモートで実行されている場合は、イメージに新しいタグを付け、プッシュしてリポジトリにイメージを送信します。カスタムのリポジトリ/タグを追加パラメータとして指定する場合は、この手順をスキップできます。
export BEAM_SDK_VERSION="2.26.0"
export IMAGE_NAME="gcr.io/my-gcp-project/beam_python3.7_sdk"
export TAG="${BEAM_SDK_VERSION}-custom"

docker tag apache/beam_python3.7_sdk "${IMAGE_NAME}:${TAG}"
docker push "${IMAGE_NAME}:${TAG}"
  1. コンテナイメージをプッシュした後、リモートイメージの ID とダイジェストが、docker_images --digests の出力にあるローカルイメージの ID とダイジェストと一致することを確認します。

追加のビルドパラメータ

docker Gradle タスクはデフォルトのイメージリポジトリを定義し、タグgradle.properties で定義されている SDK バージョンです。デフォルトのリポジトリは Docker Hub の apache 名前空間で、デフォルトのタグは gradle.properties で定義されているSDK バージョンです。

ビルドタスクにパラメータを提供することで、ビルドされたイメージに異なるリポジトリまたはタグを指定できます。例えば

./gradlew :sdks:python:container:py36:docker -Pdocker-repository-root="example-repo" -Pdocker-tag="2.26.0-custom"

は Python 3.6 コンテナをビルドし、example-repo/beam_python3.6_sdk:2.26.0-custom としてタグ付けします。

Beam 2.21.0 以降、サードパーティ依存関係のライセンス/通知を Docker イメージに追加するための docker-pull-licenses フラグが導入されました。例えば

./gradlew :sdks:java:container:java11:docker -Pdocker-pull-licenses

は、適切なライセンスを /opt/apache/beam/third_party_licenses/ に含む Java 11 SDK イメージを作成します。

デフォルトでは、Docker イメージにライセンス/通知は追加されません。

既存のコンテナイメージを変更してApache Beamランナーと互換性を持たせる

Beam は、独自のカスタムコンテナイメージを提供する方法を提供しています。Apache Beam ランナーと互換性のある新しいカスタムイメージを構築する最も簡単な方法は、マルチステージビルドプロセスを使用することです。これは、デフォルトの Apache Beam ベースイメージから必要なアーティファクトをコピーして、カスタムコンテナイメージをビルドします。

  1. Apache Beam ベースイメージから必要なアーティファクトをイメージにコピーします。
# This can be any container image,
FROM python:3.8-bookworm

# Install SDK. (needed for Python SDK)
RUN pip install --no-cache-dir apache-beam[gcp]==2.52.0

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

# Perform any additional customizations if desired

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

:この例では、必要な依存関係(この場合は Python 3.8 と pip)が既存のベースイメージにインストールされていることを前提としています。Apache Beam SDK をイメージにインストールすると、イメージに必要な SDK 依存関係が含まれ、ワーカーの起動時間が短縮されます。RUN 命令で指定されたバージョンは、パイプラインの起動に使用されたバージョンと一致する必要があります。
ベースイメージで指定されている Python または Java ランタイムのバージョンが、パイプラインの実行に使用されているバージョンと同じであることを確認してください。

:追加の Python 依存関係は、カスタムイメージのグローバル Python 環境にインストールする必要があります。

  1. Dockerを使用してイメージをビルドし、プッシュします。
  export BASE_IMAGE="apache/beam_python3.8_sdk:2.52.0"
  export IMAGE_NAME="myremoterepo/mybeamsdk"
  export TAG="latest"

  # Optional - pull the base image into your local Docker daemon to ensure
  # you have the most up-to-date version of the base image locally.
  docker pull "${BASE_IMAGE}"

  docker build -f Dockerfile -t "${IMAGE_NAME}:${TAG}" .
  1. ランナーがリモートで実行されている場合は、イメージに新しいタグを付け、プッシュしてリポジトリにイメージを送信します。
docker push "${IMAGE_NAME}:${TAG}"

互換性のあるコンテナイメージをゼロから構築する(Go)

2.55.0 リリースから、Beam Go SDK はベースとしてdistroless イメージを使用するように移行しました。これらのイメージは、一般的なツールやユーティリティを含まないことで、セキュリティ攻撃対象領域を縮小しています。これは、上記のアプローチのいずれかを使用してイメージをカスタマイズすることを困難にする可能性があります。代替手段として、一致するブートローダーを構築し、それをコンテナのエントリポイントとして設定することで、ゼロからカスタムイメージを構築することが可能です。

たとえば、コンテナ OS として alpine を使用したい場合、マルチステージ Dockerfile は次のようになります。

FROM golang:latest-alpine AS build_base

# Set the Current Working Directory inside the container
WORKDIR /tmp/beam

# Build the Beam Go bootloader, to the local directory, matching your Beam version.
# Similar go targets exist for other SDK languages.
RUN GOBIN=`pwd` go install github.com/apache/beam/sdks/v2/go/container@v2.53.0

# Set the real base image.
FROM alpine:3.9
RUN apk add ca-certificates

# The following are required for the container to operate correctly.
# Copy the boot loader `container` to the image.
COPY --from=build_base /tmp/beam/container /opt/apache/beam/boot

# Set the container to use the newly built boot loader.
ENTRYPOINT ["/opt/apache/beam/boot"]

上記の既存のベースイメージの変更と同様に、新しいイメージをビルドしてプッシュします。

:Java と Python は、有効なコンテナイメージのために、ランタイムや SDK パッケージなどの追加の依存関係が必要です。ブートローダーだけでは、これらの SDK のカスタムコンテナを作成するには不十分です。

カスタムコンテナイメージを使用してパイプラインを実行する

コンテナイメージを提供する一般的な方法は、Portable Runner または PortableRunner フラグをサポートするランナーでサポートされている PortableRunner フラグ --environment_config を使用することです。Dataflow などの他のランナーは、異なるフラグでコンテナを指定することをサポートしています。

export IMAGE="my-repo/beam_python_sdk_custom"
export TAG="X.Y.Z"
export IMAGE_URL="${IMAGE}:${TAG}"

python -m apache_beam.examples.wordcount \
--input=/path/to/inputfile \
--output /path/to/write/counts \
--runner=PortableRunner \
--job_endpoint=embed \
--environment_type="DOCKER" \
--environment_config="${IMAGE_URL}"
export IMAGE="my-repo/beam_python_sdk_custom"
export TAG="X.Y.Z"
export IMAGE_URL = "${IMAGE}:${TAG}"

# Run a pipeline using the SparkRunner which starts the Spark job server
python -m apache_beam.examples.wordcount \
--input=/path/to/inputfile \
--output=path/to/write/counts \
--runner=SparkRunner \
# When running batch jobs locally, we need to reuse the container.
--environment_cache_millis=10000 \
--environment_type="DOCKER" \
--environment_config="${IMAGE_URL}"
export GCS_PATH="gs://my-gcs-bucket"
export GCP_PROJECT="my-gcp-project"
export REGION="us-central1"

# By default, the Dataflow runner has access to the GCR images
# under the same project.
export IMAGE="my-repo/beam_python_sdk_custom"
export TAG="X.Y.Z"
export IMAGE_URL = "${IMAGE}:${TAG}"

# Run a pipeline on Dataflow.
# This is a Python batch pipeline, so to run on Dataflow Runner V2
# you must specify the experiment "use_runner_v2"

python -m apache_beam.examples.wordcount \
  --input gs://dataflow-samples/shakespeare/kinglear.txt \
  --output "${GCS_PATH}/counts" \
  --runner DataflowRunner \
  --project $GCP_PROJECT \
  --region $REGION \
  --temp_location "${GCS_PATH}/tmp/" \
  --experiment=use_runner_v2 \
  --sdk_container_image=$IMAGE_URL

カスタムイメージでタグ :latest を使用しないでください。ビルドには、日付または一意の識別子でタグを付けます。問題が発生した場合、このタイプのタグを使用すると、パイプラインの実行を以前に既知の動作構成に戻し、変更を検査できる可能性があります。

トラブルシューティング

次のセクションでは、カスタムコンテナで Beam パイプラインを実行する際に予期しないエラーが発生した場合に考慮すべき一般的な問題について説明します。