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 秒。
资料来源:
如果 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 来构建它s1,s2并且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)