docker 是否可以并行构建多阶段镜像?

Use*_*645 17 parallel-processing docker docker-build

我有一个相当大的具有多层的 Dockerfile。其中一些层需要相当长的时间。我注意到很多事情并不相互依赖。

因此,显而易见的问题是:我可以docker build并行吗?

docker构建似乎只有限制构建速度的选项,而不是加速它(例如--memory)。

示例:假设您有一个Dockerfile看起来像这样的。我现在想调用一个docker build --some-flag并行构建所有阶段的函数,除非它们必须相互协作。

FROM someImage AS stage1
# do some task

FROM otherImage AS stage2
# do another taks

FROM yetAnotherImg As stage3
# more work
COPY --from=stage2 ... # stage3 has to wait for stage2 to finish
Run Code Online (Sandbox Code Playgroud)

你知道是否--some-flag存在吗?您知道如何实现目标的不同方式吗?

编辑:

我唯一能想到的就是将 Dockerfile 分成更多阶段,从而使修改不那么痛苦,但这并不是一个真正理想的解决方案

Use*_*645 22

感谢 m303945 的回答!

这个答案为您提供了如何并行构建的示例:

Dockerfile:

FROM alpine as s1
RUN sleep 10 && echo "s1 done"

FROM alpine as s2
RUN sleep 10 && echo "s2 done"

FROM alpine as s3
RUN sleep 10 && echo "s3 done"
Run Code Online (Sandbox Code Playgroud)

顺序:docker build .大约需要 30 秒。

并行:DOCKER_BUILDKIT=1 docker build .大约需要 10 秒。

资料来源:

码头工人文档

很棒的博客文章

  • Dockerfile 在 10 秒内构建,因为“docker build.”仅构建最后一个阶段,即“s3”。但是,如果 s3 也执行了 `COPY --from=s1 //s1` 和 `COPY --from=s2 //s2` ,那么 `s1` 和 `s2` 将并行运行。我将发布包含更多详细信息的答案。 (2认同)

gus*_*afc 6

如果 BuildKit 发现某个阶段依赖于其他彼此不依赖的阶段,那么它将并行运行这些阶段(无论如何,假设有足够的线程/CPU 可用)。这是一个例子:

# syntax=docker/dockerfile:1.4

FROM alpine as s1
RUN echo Stage s1 building, time is `date` >/s1.txt && sleep 10

FROM alpine as s2
RUN echo Stage s2 building, time is `date` >/s2.txt && sleep 10

FROM alpine as s3
RUN echo Stage s3 building, time is `date` >/s3.txt && sleep 10

FROM s3 AS final-stage
COPY --from=s1 /s1.txt /
COPY --from=s2 /s2.txt /
ENTRYPOINT cat /s*.txt
Run Code Online (Sandbox Code Playgroud)

如果您使用docker build .(隐式构建 Dockerfile 中的最后一个阶段), stage 来构建它s1s2并且s3会自动并行运行(同样,假设您拥有系统资源,但这就是我相当旧的计算机上发生的情况)。整个构建在 10 秒多一点的时间内完成......

$ docker build .
[+] Building 12.6s (14/14) FINISHED                                                                                                                                                                         
 => [internal] load build definition from Dockerfile                                                                                                                                                   0.0s
 => => transferring dockerfile: 419B                                                                                                                                                                   0.0s
 => [internal] load .dockerignore                                                                                                                                                                      0.0s
 => => transferring context: 2B                                                                                                                                                                        0.0s
 => resolve image config for docker.io/docker/dockerfile:1.4                                                                                                                                           1.6s
 => CACHED docker-image://docker.io/docker/dockerfile:1.4@sha256:9ba7531bd80fb0a858632727cf7a112fbfd19b17e94c4e84ced81e24ef1a0dbc                                                                      0.0s
 => [internal] load build definition from Dockerfile                                                                                                                                                   0.0s
 => [internal] load .dockerignore                                                                                                                                                                      0.0s
 => [internal] load metadata for docker.io/library/alpine:latest                                                                                                                                       0.0s
 => CACHED [s2 1/2] FROM docker.io/library/alpine                                                                                                                                                      0.0s
 => [s1 2/2] RUN echo Stage s1 building, time is `date` >/s1.txt && sleep 10                                                                                                                          10.4s
 => [s3 2/2] RUN echo Stage s3 building, time is `date` >/s3.txt && sleep 10                                                                                                                          10.5s
 => [s2 2/2] RUN echo Stage s2 building, time is `date` >/s2.txt && sleep 10                                                                                                                          10.4s
 => [final-stage 1/2] COPY --from=s1 /s1.txt /                                                                                                                                                         0.0s
 => [final-stage 2/2] COPY --from=s2 /s2.txt /                                                                                                                                                         0.0s
 => exporting to image                                                                                                                                                                                 0.0s
 => => exporting layers                                                                                                                                                                                0.0s
 => => writing image sha256:3f76475f4bab8aa773a7b4daf1403cbd269fa964b7133f81800e1359eae08d60                                                                                                           0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
Run Code Online (Sandbox Code Playgroud)

...如果我们运行图像,我们可以看到各个阶段确实同时运行:

$ docker run --rm sha256:3f76475f4bab8aa773a7b4daf1403cbd269fa964b7133f81800e1359eae08d60
Stage s1 building, time is Wed Jan 25 18:52:50 UTC 2023
Stage s2 building, time is Wed Jan 25 18:52:50 UTC 2023
Stage s3 building, time is Wed Jan 25 18:52:50 UTC 2023
Run Code Online (Sandbox Code Playgroud)

因此,为了回答你的问题,你可以分为stage3两个阶段,一个阶段执行实际工作,另一个阶段只是复制其他阶段的内容:

FROM yetAnotherImg As stage3-intermediate
# more work

FROM stage3-intermediate AS stage3
COPY --from=stage2 ... # stage2 and stage3-intermediate will run in parallel
Run Code Online (Sandbox Code Playgroud)