容器環境
Beam SDK 執行階段環境可以使用 容器化,並透過 Docker 來隔離它與其他執行階段系統。若要進一步了解容器環境,請閱讀 Beam SDK Harness 容器合約。
預先建置的 SDK 容器映像會根據 Beam 版本發行時每個支援的語言來推送至 Docker Hub。
自訂容器
您可能因為許多原因而想要自訂容器映像,包括
- 預先安裝額外的相依性
- 在工作者環境中啟動協力廠商軟體
- 進一步自訂執行環境
本指南說明如何為 Beam SDK 建立和使用自訂容器。
先決條件
- 本指南需要使用 Docker 建置映像。在本地安裝 Docker。某些 CI/CD 平台,例如 Google Cloud Build,也提供使用 Docker 建置映像的功能。
- 對於遠端執行引擎/執行器,請準備一個容器登錄檔來託管您的自訂容器映像。選項包括 Docker Hub 或「自行託管」的儲存庫,包括雲端特定的容器登錄檔,例如 Google Container Registry (GCR) 或 Amazon Elastic Container Registry (ECR)。請確定您的執行引擎或執行器可以存取您的登錄檔。
注意:在 2020 年 11 月 20 日,Docker Hub 對於匿名和免費驗證使用實施了 速率限制,這可能會影響多次提取容器的較大型管線。
為了獲得最佳的使用者體驗,我們也建議您使用最新發行的 Beam 版本。
建立並推送自訂容器
Beam SDK 容器映像是根據簽入 Github 儲存庫的 Dockerfile 所建立,並針對每個版本發佈到 Docker Hub。您可以使用以下三種方式之一來建立自訂容器
- 根據已發行的容器映像撰寫新的 Dockerfile。這足以對映像進行簡單的加入,例如新增成品或環境變數。
- 修改 Beam 中的來源 Dockerfile。此方法需要從 Beam 來源建置,但允許對容器進行更大的自訂 (包括替換成品或基礎作業系統/語言版本)。
- 修改現有的容器映像以使其與 Apache Beam 執行器相容。當使用者從現有的映像開始,並將映像設定為與 Apache Beam 執行器相容時,會使用此方法。
根據現有已發佈的容器映像撰寫新的 Dockerfile
- 使用 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
,並將額外的環境變數和檔案新增至映像。
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}" .
- 如果您的執行器在遠端執行,請重新標記映像並將其 推送 到適當的儲存庫。
docker push "${IMAGE_NAME}:${TAG}"
- 推送容器映像之後,請驗證遠端映像 ID 和摘要與
docker build
或docker images
的輸出中的本機映像 ID 和摘要相符。
修改 Beam 中的來源 Dockerfile
此方法需要從 Beam 來源建置映像成品。如需設定開發環境的其他指示,請參閱貢獻指南。
注意:建議您從與執行管線的 SDK 版本相同的穩定發行分支 (
release-X.XX.X
) 開始。SDK 版本中的差異可能會導致意外的錯誤。
- 複製
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
自訂給定語言的
Dockerfile
,通常位於sdks/<language>/container/Dockerfile
目錄中 (例如,Python 的 Dockerfile)。返回根 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
- 執行
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 ...
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}"
- 推送容器映像之後,請驗證遠端映像 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-pull-licenses
旗標,可將第三方相依性的授權/聲明新增至 Docker 映像檔。例如:
./gradlew :sdks:java:container:java11:docker -Pdocker-pull-licenses
會在 /opt/apache/beam/third_party_licenses/
中建立具有適當授權的 Java 11 SDK 映像檔。
預設情況下,不會將授權/聲明新增至 Docker 映像檔。
修改現有的容器映像以使其與 Apache Beam 執行器相容
Beam 提供一種方式讓您提供自己的自訂容器映像檔。建立與 Apache Beam Runner 相容的新自訂映像檔最簡單的方法是使用多階段建置程序。這會將必要的成品從預設的 Apache Beam 基本映像檔複製過來,以建置您的自訂容器映像檔。
- 將必要的成品從 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 相依性,並縮短 Worker 的啟動時間。
RUN
指令中指定的版本必須與用於啟動管道的版本相符。
請確保基本映像檔中指定的 Python 或 Java 執行階段版本與用於執行管道的版本相同。
注意:任何額外的 Python 相依性都應安裝在自訂映像檔的全域 Python 環境中。
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}" .
- 如果您的 Runner 是遠端執行,請重新標記映像檔並將映像檔推送到您的儲存庫。
docker push "${IMAGE_NAME}:${TAG}"
從頭開始建立相容的容器映像 (Go)
從 2.55.0 版本開始,Beam Go SDK 已改為使用distroless 映像檔作為基礎。這些映像檔不包含常用的工具和公用程式,因此降低了安全性攻擊面。這可能會導致使用上述方法之一自訂映像檔時產生困難。作為一種備案,可以從頭開始建置自訂映像檔,方法是建置一個匹配的開機載入程式,並將其設定為容器的進入點。
例如,如果希望使用 alpine 作為容器作業系統,您的多階段 Docker 檔案可能如下所示:
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 的自訂容器。
使用自訂容器映像執行管線
提供容器映像檔的常用方法是使用 PortableRunner 旗標 --environment_config
,由 Portable Runner 或支援 PortableRunner 旗標的 Runner 支援。其他 Runner(例如 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 FlinkRunner which starts a Flink job server.
python -m apache_beam.examples.wordcount \
--input=/path/to/inputfile \
--output=path/to/write/counts \
--runner=FlinkRunner \
# When running batch jobs locally, we need to reuse the container.
--environment_cache_millis=10000 \
--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 管道時遇到意外錯誤時,需要考慮的一些常見問題。
- 容器 SDK 和管道 SDK 之間的語言和 SDK 版本差異可能會因為不相容而導致意外錯誤。為了獲得最佳效果,請確保您的基本容器和執行管道時都使用相同的穩定 SDK 版本。
- 如果您在使用遠端容器時遇到意外錯誤,請確保您的容器存在於遠端儲存庫中,並且任何第三方服務(如果需要)都可以存取該容器。
- 本機 Runner 會嘗試提取遠端映像檔,並預設使用本機映像檔。如果無法在本機(由 Docker 精靈)提取映像檔,您可能會看到類似以下的記錄訊息:
Error response from daemon: manifest for remote.repo/beam_python3.7_sdk:2.25.0-custom not found: manifest unknown: ... INFO:apache_beam.runners.portability.fn_api_runner.worker_handlers:Unable to pull image...
上次更新時間為 2024/10/31
您是否找到您想要的所有內容?
這些內容是否有用且清楚?您想要變更任何內容嗎?請告訴我們!