docker - Dockerized Apache Beam 返回“未提供 ID”
问题描述
我遇到了 dockerized Apache Beam 的问题。尝试运行容器时,我收到"No id provided."
消息,仅此而已。这是代码和文件:
Dockerfile
FROM apache/beam_python3.8_sdk:latest
RUN apt update
RUN apt install -y wget curl unzip git
COPY ./ /root/data_analysis/
WORKDIR /root/data_analysis
RUN python3 -m pip install -r data_analysis/beam/requirements.txt
ENV PYTHONPATH=/root/data_analysis
ENV WORKER_ID=1
CMD python3 data_analysis/analysis.py
代码analysis.py
:
import apache_beam as beam
from apache_beam.options.pipeline_options import PipelineOptions
def run():
options = PipelineOptions(["--runner=DirectRunner"])
with beam.Pipeline(options=options) as p:
p | beam.Create([1, 2, 3]) | beam.Map(lambda x: x-1) | beam.Map(print)
if __name__ == "__main__":
run()
命令:
% docker build -f Dockerfile_beam -t beam .
[+] Building 242.2s (12/12) FINISHED
...
% docker run --name=beam beam
2021/09/15 13:44:07 No id provided.
我发现这个错误消息很可能是由这一行产生的:https ://github.com/apache/beam/blob/410ad7699621e28433d81809f6b9c42fe7bd6a60/sdks/python/container/boot.go#L98
但是这是什么意思?这是哪个id?我错过了什么?
解决方案
由于您的 Docker 映像基于 SDK 线束映像 ( apache/beam_python3.8_sdk
),因此很可能会发生此错误。SDK 线束图像用于便携式管道;当可移植运行器需要执行必须以其原始语言执行的管道阶段时,它会使用 SDK 工具启动一个容器,并将该管道阶段的执行委托给 SDK 工具。因此,当 SDK 工具启动时,它期望启动它的运行器提供各种配置详细信息,其中之一是 ID。当您直接启动此容器时,不会提供这些配置详细信息并且它会崩溃。
对于您的特定用例的上下文,让我首先绘制出运行可移植管道所涉及的不同过程。
Pipeline Construction <---> Job Service <---> SDK Harness
\--> Cross-Language SDK Harness
- 管道构建- 您定义和运行管道的过程。它将您的管道定义发送到作业服务并接收管道结果。它不执行任何管道。
- 工作服务- 您选择的跑步者的流程。这可能与您的原始管道构造使用不同的语言,因此无法运行用户代码,例如自定义 DoFns。
- SDK Harness - 执行用户代码的过程,由作业服务发起和管理。默认情况下,它位于 docker 容器中。
- Cross-Language SDK Harness使用与管道构造不同的语言执行代码的进程。在您的情况下,Python 的 Kafka IO 使用跨语言,并且实际上在 Java SDK 工具中执行。
目前,您创建的 docker 容器基于 SDK 线束容器,这听起来不像您想要的。您似乎一直在尝试将您的管道构造代码容器化,并意外地将 SDK 工具容器化。但是,由于您描述了您希望 ReadFromKafka 消费者被容器化,听起来您需要将作业服务器容器化,以及它使用的任何 SDK 工具。
将作业服务器容器化是可能的,并且可能已经完成。例如,这是一个容器化的 Flink Job Server。容器化作业服务器可能会给您带来一些关于工件的麻烦,因为容器无法访问您本地机器上的工件暂存目录,但可能有解决方法。
此外,您提到您希望避免在嵌套的 docker 容器中启动 SDK 线束。如果您为 SDK 工具启动一个工作池 docker 容器并将其设置为外部环境,则运行程序(假设它支持外部环境)将尝试连接到您提供的 URL,而不是创建新的 docker 容器。如果在 Python SDK 中可行,您还需要为 Java 跨语言环境配置它。此配置应通过 python 的管道选项完成。--environment_type
并且--environment_options
是很好的起点。
推荐阅读
- c# - 使用 Mirror 框架 PortMapping UPnP (Mono.Nat) 后仍然无法通过 Internet 连接
- ios - 如何在 iOS Objective c 中进行 iOS 导航健康设置?
- javascript - 反应音乐播放器
- c# - 为 CLR 聚合实现 IBinarySerialize
- c - gcc 包含标头并在预处理后获取输出
- typescript - Typescript 动态参数和返回类型
- python - 将数据从 JSON 写入 CSV 文件
- control-m - 在 Control-M 中从订单日期减去 2 分钟
- javascript - 用 html5 画布绘制地砖,但它是完美的。我怎样才能使用 webgl 变得逼真
- c# - 在表单面板的中心显示 msgbox