Requisitos
Uma imagem de contêiner personalizada para o Dataflow precisa atender aos seguintes requisitos:
- O SDK do Apache Beam e as dependências necessárias instaladas Recomendamos começar com uma imagem padrão do SDK do Apache Beam. Para mais informações, consulte Selecionar uma imagem de base neste documento.
- O script
/opt/apache/beam/boot
precisa ser executado como a última etapa durante a inicialização do contêiner. O script inicializa o ambiente do worker e inicia o processo de worker do SDK. Esse script é oENTRYPOINT
padrão nas imagens do SDK do Apache Beam. No entanto, se você usar uma imagem de base diferente ou modificar oENTRYPOINT
padrão, será necessário executar o script explicitamente. Para mais informações, consulte Modificar o ponto de entrada do contêiner neste documento. - A imagem do contêiner precisa ser compatível com a arquitetura das VMs de worker para seu job do Dataflow. Se você planeja usar o contêiner personalizado em VMs ARM, recomendamos criar uma imagem de multiarquitetura. Para mais informações, consulte Criar uma imagem de contêiner de várias arquiteturas.
Antes de começar
Verifique se a versão do SDK do Apache Beam instalada é compatível com o Runner v2 e sua versão de linguagem. Para mais informações, consulte Instalar o SDK do Apache Beam.
Para testar sua imagem de contêiner localmente, é necessário ter o Docker instalado. Para mais informações, consulte Obter Docker.
Crie um repositório do Artifact Registry. Especifique o formato de imagem do Docker. É preciso ter pelo menos o acesso "Gravador do Artifact Registry" no repositório.
Para criar um novo repositório, execute o comando
gcloud artifacts repositories create
:gcloud artifacts repositories create REPOSITORY \ --repository-format=docker \ --location=REGION \ --async
Substitua:
- REPOSITORY: um nome para o repositório. Os nomes dos repositórios precisam ser exclusivos para cada local em um projeto.
- REGION: a região onde o job do Dataflow será implantado. Selecione uma região do Dataflow próxima de onde você executa os comandos. O valor precisa ser um nome de região válido. Para mais informações sobre regiões e locais, consulte Locais do Dataflow.
Neste exemplo, usamos a flag
--async
. O comando retorna imediatamente, sem aguardar a conclusão da operação.Para configurar o Docker para autenticar solicitações do Artifact Registry, execute o comando
gcloud auth configure-docker
:gcloud auth configure-docker REGION-docker.pkg.dev
O comando atualiza a configuração do Docker. Agora é possível se conectar ao Artifact Registry no seu projeto do Google Cloud para enviar imagens.
Selecionar uma imagem de base
Recomendamos começar com uma imagem do SDK do Apache Beam como a imagem do contêiner de base. Essas imagens padrão são lançadas como parte das versões do Apache Beam para DockerHub.
Usar uma imagem de base do Apache Beam
Para usar uma imagem do SDK do Apache Beam como a imagem de base, especifique a imagem do contêiner na instrução FROM
e adicione suas próprias personalizações.
Java
Este exemplo usa o Java 8 com a versão 2.58.1 do SDK do Apache Beam.
FROM apache/beam_java8_sdk:2.58.1
# Make your customizations here, for example:
ENV FOO=/bar
COPY path/to/myfile ./
A versão do tempo de execução do contêiner personalizado precisa corresponder ao tempo de execução que você
usará para iniciar o pipeline. Por exemplo, se você iniciar o pipeline a partir de um
ambiente Java 11 local, a linha FROM
precisará especificar um ambiente Java 11:
apache/beam_java11_sdk:...
.
Python
Este exemplo usa o Python 3.10 com a versão 2.58.1 do SDK do Apache Beam.
FROM apache/beam_python3.10_sdk:2.58.1
# Make your customizations here, for example:
ENV FOO=/bar
COPY path/to/myfile ./
A versão do tempo de execução do contêiner personalizado precisa corresponder ao tempo de execução que você
usará para iniciar o pipeline. Por exemplo, se você iniciar o pipeline em um
ambiente Python 3.10 local, a linha FROM
precisará especificar um ambiente Python 3.10:
apache/beam_python3.10_sdk:...
.
Go
Este exemplo usa o Go com o SDK do Apache Beam versão 2.58.1.
FROM apache/beam_go_sdk:2.58.1
# Make your customizations here, for example:
ENV FOO=/bar
COPY path/to/myfile ./
Usar uma imagem de base personalizada
Se você quiser usar uma imagem de base diferente ou precisar modificar algum aspecto das imagens padrão do Apache Beam (como versão ou patches do SO), use um processo de build de vários estágios. Copie os artefatos necessários de uma imagem base padrão do Apache Beam.
Defina o ENTRYPOINT
para executar o script /opt/apache/beam/boot
, que
inicializa o ambiente do worker e inicia o processo de worker do SDK. Se você
não definir esse ponto de entrada, os workers do Dataflow não serão iniciados
corretamente.
Veja no exemplo a seguir um Dockerfile que copia arquivos do SDK do Apache Beam:
Java
FROM openjdk:8
# Copy files from official SDK image, including script/dependencies.
COPY --from=apache/beam_java8_sdk:2.58.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.58.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.58.1 /opt/apache/beam /opt/apache/beam
# Set the entrypoint to Apache Beam SDK launcher.
ENTRYPOINT ["/opt/apache/beam/boot"]
Neste exemplo, presume-se que as dependências necessárias (neste caso, Python 3.10 e pip
)
foram instaladas na imagem base atual. A instalação do SDK do Apache Beam na imagem garante que ela tenha as dependências necessárias do SDK e reduz o tempo de inicialização do worker.
Importante: a versão do SDK especificada nas
instruções RUN
e COPY
precisa corresponder à versão usada para iniciar o pipeline.
Go
FROM golang:latest
# Copy files from official SDK image, including script/dependencies.
COPY --from=apache/beam_go_sdk:2.58.1 /opt/apache/beam /opt/apache/beam
# Set the entrypoint to Apache Beam SDK launcher.
ENTRYPOINT ["/opt/apache/beam/boot"]
Modificar o ponto de entrada do contêiner
Se o contêiner executar um script personalizado durante a inicialização, ele precisará terminar com a execução de /opt/apache/beam/boot
. Os argumentos transmitidos pelo Dataflow durante a inicialização do contêiner precisam ser passados para o script de inicialização padrão. O exemplo a seguir mostra um script de inicialização personalizado que chama o
script de inicialização padrão:
#!/bin/bash
echo "This is my custom script"
# ...
# Pass command arguments to the default boot script.
/opt/apache/beam/boot "$@"
No Dockerfile, defina ENTRYPOINT
para chamar o script:
Java
FROM apache/beam_java8_sdk:2.58.1
COPY script.sh path/to/my/script.sh
ENTRYPOINT [ "path/to/my/script.sh" ]
Python
FROM apache/beam_python3.10_sdk:2.58.1
COPY script.sh path/to/my/script.sh
ENTRYPOINT [ "path/to/my/script.sh" ]
Go
FROM apache/beam_go_sdk:2.58.1
COPY script.sh path/to/my/script.sh
ENTRYPOINT [ "path/to/my/script.sh" ]
Criar e enviar a imagem
Use o Cloud Build ou o Docker para criar a imagem do contêiner e enviá-la para um repositório do Artifact Registry.
Cloud Build
Para criar o arquivo e enviá-lo ao repositório do Artifact Registry, execute o
comando 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
Substitua:
REGION
: a região em que o job do Dataflow será implantado. O valor da variávelREGION
precisa ser um nome de região válido.PROJECT_ID
: o nome do projeto ou do usuário.REPOSITORY
: o nome do repositório de imagens.FILE_NAME
: o nome do Dockerfile.TAG
: a tag de imagem. Sempre especifique uma tag ou um SHA de contêiner com controle de versões. Não use a tag:latest
ou uma tag mutável.
Pré-instalar dependências do Python
Esta seção se aplica aos pipelines do Python.
Ao iniciar um job em Python do Dataflow, é possível especificar outras
dependências usando as opções --requirements_file
ou --extra_packages
no
ambiente de execução. Para mais informações, leia Como gerenciar dependências de pipeline do Python.
Outras dependências são instaladas em cada contêiner de worker do Dataflow. Quando o job é iniciado e durante o escalonamento automático, a instalação de dependência geralmente leva ao alto uso da CPU e a um longo período de aquecimento em todos os workers recém-iniciados do Dataflow.
Para evitar instalações repetitivas, é possível pré-criar a imagem de um contêiner personalizada do SDK do Python com as dependências pré-instaladas. É possível executar essa etapa no tempo de build usando um Dockerfile ou no ambiente de execução, ao enviar o job.
Os workers criam um novo ambiente virtual do Python quando iniciam o contêiner. Por esse motivo, instale dependências no ambiente Python padrão (global) em vez de criar um ambiente virtual. Se você ativar um ambiente virtual na imagem do contêiner, talvez esse ambiente não esteja ativado quando o job for iniciado. Para saber mais, consulte Problemas comuns.
Pré-instalar usando um Dockerfile
Para adicionar mais dependências diretamente ao contêiner personalizado do Python, use os seguintes comandos:
FROM apache/beam_python3.10_sdk:2.58.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
Envie o job com as opções de pipeline --sdk_container_image
e --sdk_location
.
A opção --sdk_location
vai impedir o download do SDK quando o job for iniciado.
O SDK é recuperado diretamente da imagem do contêiner.
O exemplo a seguir executa o
pipeline de exemplo 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
Substitua:
- INPUT_FILE: um arquivo de entrada para o pipeline.
- OUTPUT_FILE: um caminho de arquivo para gravar a saída.
- PROJECT_ID: o ID do projeto do Google Cloud
- REGION: a região em que o job do Dataflow será implantado.
- TEMP_LOCATION: o caminho do Cloud Storage para o Dataflow em que os arquivos de job temporários são preparados
- IMAGE_URI: o URI da imagem do contêiner personalizado
Crie previamente uma imagem de contêiner ao enviar o job.
A pré-criação de uma imagem de contêiner permite a pré-instalação das dependências do pipeline antes da inicialização do job. Você não precisa criar uma imagem de contêiner personalizada.
Para criar previamente um contêiner com outras dependências do Python ao enviar um job, use as seguintes opções de pipeline:
--prebuild_sdk_container_engine=[cloud_build | local_docker]
. Quando essa flag é definida, o Apache Beam gera um contêiner personalizado e instala todas as dependências especificadas pelas opções--requirements_file
e--extra_packages
. Essa flag é compatível com os seguintes valores:cloud_build
: Use o Cloud Build para criar o contêiner. A API Cloud Build precisa estar ativada no projeto.local_docker
. Use a instalação local do Docker para criar o contêiner.
--docker_registry_push_url=IMAGE_PATH
. SubstituaIMAGE_PATH
por uma pasta do Artifact Registry.--sdk_location=container
. Essa opção impede que os workers façam o download do SDK quando o job é iniciado. Em vez disso, o SDK é recuperado diretamente da imagem do contêiner.
O exemplo a seguir usa o Cloud Build para pré-criar a imagem:
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
O recurso de pré-build requer a versão 2.25.0 ou mais recente do SDK do Apache Beam para Python.
O fluxo de trabalho de pré-criação da imagem do contêiner do SDK usa a imagem transmitida com a
opção de pipeline --sdk_container_image
como a imagem base. Se a opção não estiver definida,
uma imagem do Apache Beam é usada como a imagem base por padrão.
É possível reutilizar uma imagem de contêiner do SDK do Python pré-criada em outro job com as mesmas dependências e a mesma versão do SDK.
Para reutilizar a imagem, transmita o URL de imagem de contêiner pré-criado para o outro job
usando a opção de pipeline --sdk_container_image
. Remova as opções de dependência
--requirements_file
, --extra_packages
e --setup_file
.
Se você não for reutilizar a imagem, pode excluí-la depois de concluir o job. É possível excluir a imagem com a CLI gcloud ou nas páginas do Artifact Registry no console do Google Cloud.
Se a imagem estiver armazenada no Artifact Registry, use
o comando artifacts docker images delete
:
gcloud artifacts docker images delete IMAGE --delete-tags
Problemas comuns
Se o job tiver outras dependências do Python de um espelho PyPi particular e não puder ser extraído por um job remoto do Cloud Build, tente usar a opção local do Docker ou criar o contêiner usando um Dockerfile.
Se o job do Cloud Build falhar com
docker exit code 137
, quer dizer que o job de compilação ficou sem memória, possivelmente devido ao tamanho das dependências que estão sendo instaladas. Use um tipo de máquina de worker do Cloud Build maior transmitindo--cloud_build_machine_type=machine_type
, em que machine_type é uma das seguintes opções:n1-highcpu-8
n1-highcpu-32
e2-highcpu-8
e2-highcpu-32
Por padrão, o Cloud Build usa o tipo de máquina
e2-medium
.No Apache Beam 2.44.0 e versões posteriores, os workers criam um ambiente virtual ao iniciar um contêiner personalizado. Se o contêiner criar o próprio ambiente virtual para instalar dependências, elas serão descartadas. Esse comportamento pode causar erros como os mostrados a seguir:
ModuleNotFoundError: No module named '<dependency name>'
Para evitar esse problema, instale dependências no ambiente Python padrão (global). Como solução alternativa, desative esse comportamento no Beam 2.48.0 e versões mais recentes, definindo a seguinte variável de ambiente na imagem do contêiner:
ENV RUN_PYTHON_SDK_IN_DEFAULT_ENVIRONMENT=1
A seguir
- Para mais informações sobre a gravação de Dockerfiles, consulte Práticas recomendadas para gravar Dockerfiles.
- Saiba como executar um job do Dataflow em um contêiner personalizado.