需求條件
Dataflow 的自訂容器映像檔必須符合下列規定:
- 系統會安裝 Apache Beam SDK 和必要依附元件。建議您先使用預設的 Apache Beam SDK 映像檔。詳情請參閱本文的「選取基礎映像檔」一節。
/opt/apache/beam/boot
指令碼必須在容器啟動期間的最後一個步驟執行。這個指令碼會初始化工作站環境,並啟動 SDK 工作站程序。這個指令碼是 Apache Beam SDK 映像檔中的預設ENTRYPOINT
。不過,如果您使用其他基礎映像檔,或是覆寫預設的ENTRYPOINT
,則必須明確執行指令碼。詳情請參閱本文中的「修改容器進入點」。- 容器映像檔必須支援 Dataflow 工作工作站 VM 的架構。如果您打算在 ARM VM 上使用自訂容器,建議您建構多架構映像檔。詳情請參閱建構多架構容器映像檔。
事前準備
確認安裝的 Apache Beam SDK 版本支援 Runner v2 和您的語言版本。詳情請參閱「安裝 Apache Beam SDK」。
如要在本機測試容器映像檔,必須先安裝 Docker。 詳情請參閱「取得 Docker」。
建立 Artifact Registry 存放區。 指定 Docker 映像檔格式。您必須至少具備存放區的Artifact Registry 寫入者存取權。
如要建立新的存放區,請執行
gcloud artifacts repositories create
指令:gcloud artifacts repositories create REPOSITORY \ --repository-format=docker \ --location=REGION \ --async
更改下列內容:
- REPOSITORY:存放區名稱。專案中每個位置的存放區名稱不得重複。
- REGION:用於部署 Dataflow 工作的區域。選取靠近您執行指令位置的 Dataflow 區域。值必須是有效的區域名稱。如要進一步瞭解地區和位置,請參閱 Dataflow 位置。
本範例使用
--async
旗標。指令會立即傳回,不會等待作業完成。如要將 Docker 設為驗證 Artifact Registry 的要求,請執行
gcloud auth configure-docker
指令:gcloud auth configure-docker REGION-docker.pkg.dev
這個指令會更新 Docker 設定。您現在可以在 Google Cloud 專案中連結 Artifact Registry,以推送映像檔。
選取基礎圖片
建議您以 Apache Beam SDK 映像檔做為基礎容器映像檔。這些映像檔會隨著 Apache Beam 版本發布到 Docker Hub。
使用 Apache Beam 基本映像檔
如要使用 Apache Beam SDK 映像檔做為基本映像檔,請在 FROM
指令中指定容器映像檔,然後新增自訂項目。
Java
本例使用 Java 8 和 Apache Beam SDK 2.66.0 版。
FROM apache/beam_java8_sdk:2.66.0
# Make your customizations here, for example:
ENV FOO=/bar
COPY path/to/myfile ./
自訂容器的執行階段版本必須與您用來啟動管道的執行階段相符。舉例來說,如果您要從本機 Java 11 環境啟動管道,FROM
行必須指定 Java 11 環境:apache/beam_java11_sdk:...
。
Python
這個範例使用 Python 3.10 和 Apache Beam SDK 2.66.0 版。
FROM apache/beam_python3.10_sdk:2.66.0
# Make your customizations here, for example:
ENV FOO=/bar
COPY path/to/myfile ./
自訂容器的執行階段版本必須與您用來啟動管道的執行階段相符。舉例來說,如果您要從本機 Python 3.10 環境啟動管道,FROM
行必須指定 Python 3.10 環境:apache/beam_python3.10_sdk:...
。
Go
本例使用 Go 和 Apache Beam SDK 2.66.0 版。
FROM apache/beam_go_sdk:2.66.0
# Make your customizations here, for example:
ENV FOO=/bar
COPY path/to/myfile ./
使用自訂基本映像檔
如要使用其他基礎映像檔,或需要修改預設 Apache Beam 映像檔的某些方面 (例如 OS 版本或修補程式),請使用多階段建構程序。從預設的 Apache Beam 基本映像檔複製必要構件。
設定 ENTRYPOINT
執行 /opt/apache/beam/boot
指令碼,初始化工作站環境並啟動 SDK 工作站程序。如果未設定這個進入點,Dataflow 工作站就無法正常啟動。
以下範例顯示的 Dockerfile 會從 Apache Beam SDK 複製檔案:
Java
FROM openjdk:8
# Copy files from official SDK image, including script/dependencies.
COPY --from=apache/beam_java8_sdk:2.66.0 /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.66.0
# 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.66.0 /opt/apache/beam /opt/apache/beam
# Set the entrypoint to Apache Beam SDK launcher.
ENTRYPOINT ["/opt/apache/beam/boot"]
這個範例假設現有基本映像檔已安裝必要的依附元件 (在本例中為 Python 3.10 和 pip
)。在映像檔中安裝 Apache Beam SDK,可確保映像檔具備必要的 SDK 依附元件,並縮短工作站啟動時間。
重要事項:RUN
和 COPY
指示中指定的 SDK 版本,必須與啟動管道時使用的版本相符。
Go
FROM golang:latest
# Copy files from official SDK image, including script/dependencies.
COPY --from=apache/beam_go_sdk:2.66.0 /opt/apache/beam /opt/apache/beam
# Set the entrypoint to Apache Beam SDK launcher.
ENTRYPOINT ["/opt/apache/beam/boot"]
修改容器進入點
如果容器在啟動時執行自訂指令碼,指令碼必須以執行 /opt/apache/beam/boot
結尾。容器啟動期間,Dataflow 傳遞的引數必須傳遞至預設啟動指令碼。以下範例顯示呼叫預設開機指令碼的自訂開機指令碼:
#!/bin/bash
echo "This is my custom script"
# ...
# Pass command arguments to the default boot script.
/opt/apache/beam/boot "$@"
在 Dockerfile 中,設定 ENTRYPOINT
呼叫指令碼:
Java
FROM apache/beam_java8_sdk:2.66.0
COPY script.sh path/to/my/script.sh
ENTRYPOINT [ "path/to/my/script.sh" ]
Python
FROM apache/beam_python3.10_sdk:2.66.0
COPY script.sh path/to/my/script.sh
ENTRYPOINT [ "path/to/my/script.sh" ]
Go
FROM apache/beam_go_sdk:2.66.0
COPY script.sh path/to/my/script.sh
ENTRYPOINT [ "path/to/my/script.sh" ]
建構及推送映像檔
您可以使用 Cloud Build 或 Docker 建構容器映像檔,並將其推送至 Artifact Registry 存放區。
Cloud Build
如要建構檔案並推送至 Artifact Registry 存放區,請執行 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
更改下列內容:
REGION
:用於部署 Dataflow 工作的區域。REGION
變數的值必須是有效的區域名稱。PROJECT_ID
:專案名稱或使用者名稱。REPOSITORY
:映像檔存放區名稱。FILE_NAME
:Dockerfile 的名稱。TAG
:圖片標記。請務必指定已加入版本的容器 SHA 或標記。請勿使用:latest
標記或可變動的標記。
預先安裝 Python 依附元件
本節適用於 Python 管道。
啟動 Python Dataflow 工作時,您可以在執行階段使用 --requirements_file
或 --extra_packages
選項,指定其他相依性。詳情請參閱「管理 Python 管道依附元件」。每個 Dataflow 工作站容器都會安裝額外的依附元件。工作剛開始時和自動調度資源期間,安裝依附元件通常會導致所有新啟動的 Dataflow 工作站 CPU 使用率偏高,且暖機時間較長。
如要避免重複安裝依附元件,您可以預先建構自訂 Python SDK 容器映像檔,並預先安裝依附元件。您可以在建構時使用 Dockerfile 執行這個步驟,也可以在提交作業時執行。
啟動容器時,工作人員會建立新的 Python 虛擬環境。 因此,請將依附元件安裝到預設 (全域) Python 環境,而非建立虛擬環境。如果您在容器映像檔中啟動虛擬環境,作業啟動時可能不會啟動這個環境。詳情請參閱常見問題。
使用 Dockerfile 預先安裝
如要直接將額外依附元件新增至 Python 自訂容器,請使用下列指令:
FROM apache/beam_python3.10_sdk:2.66.0
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
使用 --sdk_container_image
和 --sdk_location
管道選項提交工作。
--sdk_location
選項可避免 SDK 在工作啟動時下載。SDK 會直接從容器映像檔擷取。
以下範例會執行 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
更改下列內容:
- INPUT_FILE:管道的輸入檔案
- OUTPUT_FILE:用於寫入輸出的路徑
- PROJECT_ID:專案 ID Google Cloud
- REGION:要部署 Dataflow 工作的區域
- TEMP_LOCATION:供 Dataflow 暫存臨時工作檔案的 Cloud Storage 路徑
- IMAGE_URI:自訂容器映像檔 URI
提交工作時預先建構容器映像檔
預先建構容器映像檔可讓您在工作啟動前,預先安裝管道依附元件。您不需要建構自訂容器映像檔。
如要在提交工作時預先建構含有其他 Python 依附元件的容器,請使用下列管道選項:
--prebuild_sdk_container_engine=[cloud_build | local_docker]
。設定這個旗標後,Apache Beam 會產生自訂容器,並安裝--requirements_file
和--extra_packages
選項指定的所有依附元件。這個標記支援下列值:cloud_build
. 使用 Cloud Build 建構容器。您必須在專案中啟用 Cloud Build API。local_docker
. 使用本機 Docker 安裝項目建構容器。
--docker_registry_push_url=IMAGE_PATH
。 將IMAGE_PATH
換成 Artifact Registry 資料夾。--sdk_location=container
。這個選項可避免工作站下載 SDK。而是直接從容器映像檔擷取 SDK。
下列範例使用 Cloud Build 預先建構映像檔:
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
預先建構功能需要 Python 適用的 Apache Beam SDK 2.25.0 以上版本。
SDK 容器映像檔預先建構工作流程會使用透過 --sdk_container_image
管道選項傳遞的映像檔做為基本映像檔。如未設定此選項,系統預設會使用 Apache Beam 映像檔做為基本映像檔。
如果其他工作具有相同的依附元件和 SDK 版本,您就可以重複使用預先建構的 Python SDK 容器映像檔。如要重複使用映像檔,請使用 --sdk_container_image
管道選項,將預先建構的容器映像檔網址傳遞至其他工作。移除依附元件選項 --requirements_file
、--extra_packages
和 --setup_file
。
如果不想重複使用圖片,請在作業完成後刪除。您可以使用 gcloud CLI 刪除映像檔,也可以在 Google Cloud 控制台的 Artifact Registry 頁面中刪除。
如果映像檔儲存在 Artifact Registry 中,請使用 artifacts docker images delete
指令:
gcloud artifacts docker images delete IMAGE --delete-tags
常見問題
如果您的工作有來自私人 PyPi 鏡像的額外 Python 依附元件,且無法由遠端 Cloud Build 工作提取,請嘗試使用本機 Docker 選項,或嘗試使用 Dockerfile 建構容器。
如果 Cloud Build 工作失敗並顯示
docker exit code 137
,表示建構工作記憶體不足,可能是因為安裝的依附元件過大。如要使用較大的 Cloud Build 工作站機器類型,請傳遞--cloud_build_machine_type=machine_type
,其中 machine_type 是下列其中一個選項:n1-highcpu-8
n1-highcpu-32
e2-highcpu-8
e2-highcpu-32
根據預設,Cloud Build 會使用
e2-medium
機型。在 Apache Beam 2.44.0 以上版本中,工作站會在啟動自訂容器時建立虛擬環境。如果容器建立自己的虛擬環境來安裝依附元件,這些依附元件就會遭到捨棄。這種行為可能會導致下列錯誤:
ModuleNotFoundError: No module named '<dependency name>'
為避免發生這個問題,請將依附元件安裝到預設 (全域) Python 環境。如要解決這個問題,請在容器映像檔中設定下列環境變數,在 Beam 2.48.0 以上版本中停用這項行為:
ENV RUN_PYTHON_SDK_IN_DEFAULT_ENVIRONMENT=1
後續步驟
- 如要進一步瞭解如何編寫 Dockerfile,請參閱編寫 Dockerfile 的最佳做法。
- 瞭解如何在自訂容器中執行 Dataflow 工作。