【问题标题】:How to set up the same Docker cache behavior during build on Ubuntu as it is on Windows?如何在 Ubuntu 上构建与 Windows 上相同的 Docker 缓存行为?
【发布时间】:2021-09-10 19:56:01
【问题描述】:

我们有这样的Dockerfile

FROM alpine:latest as step1
RUN echo "STEP1"

FROM alpine:latest as step2
RUN echo "STEP2"

FROM step1 as step3
RUN echo "STEP3"

在 Windows(或 WSL2)上,我们有这样的构建多阶段图像的结果。

在 Windows 上构建所有步骤:

$ docker build .
[+] Building 0.2s (7/7) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                                         0.0s
 => => transferring dockerfile: 32B                                                                                                                                          0.0s
 => [internal] load .dockerignore                                                                                                                                            0.1s
 => => transferring context: 2B                                                                                                                                              0.0s
 => [internal] load metadata for docker.io/library/alpine:latest                                                                                                             0.0s
 => [step1 1/2] FROM docker.io/library/alpine:latest                                                                                                                         0.0s
 => CACHED [step1 2/2] RUN echo "STEP1"                                                                                                                                      0.0s
 => CACHED [step3 1/1] RUN echo "STEP3"                                                                                                                                      0.0s
 => exporting to image                                                                                                                                                       0.1s
 => => exporting layers                                                                                                                                                      0.0s
 => => writing image sha256:38ba33425558f5373099ad59aa187456c38b3f5eab14a60fdbb3cb7b1c484392                                                                                 0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

在 Windows 上构建步骤 2:

$ docker build --target step2 .
[+] Building 0.5s (6/6) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                                         0.0s
 => => transferring dockerfile: 32B                                                                                                                                          0.0s
 => [internal] load .dockerignore                                                                                                                                            0.0s
 => => transferring context: 2B                                                                                                                                              0.0s
 => [internal] load metadata for docker.io/library/alpine:latest                                                                                                             0.0s
 => CACHED [step2 1/2] FROM docker.io/library/alpine:latest                                                                                                                  0.0s
 => [step2 2/2] RUN echo "STEP2"                                                                                                                                             0.3s
 => exporting to image                                                                                                                                                       0.0s
 => => exporting layers                                                                                                                                                      0.0s
 => => writing image sha256:855f35039a5a902e1d33111fc781f748955f8b3cad7fb56d6eb420fc5d2fa55b                                                                                 0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

Windows 上的 Docker 版本:

$ docker version
Client:
 Cloud integration: 1.0.17
 Version:           20.10.7
 API version:       1.41
 Go version:        go1.16.4
 Git commit:        f0df350
 Built:             Wed Jun  2 12:00:56 2021
 OS/Arch:           windows/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.7
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       b0f5bc3
  Built:            Wed Jun  2 11:54:58 2021
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.4.6
  GitCommit:        d71fcd7d8303cbf684402823e425e9dd2e99285d
 runc:
  Version:          1.0.0-rc95
  GitCommit:        b9ee9c6314599f1b4a7f497e1f1f856fe433d3b7
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

在 Ubuntu 上,我们的结果略有不同

在 Ubuntu 上构建所有步骤:

$ docker build .
Sending build context to Docker daemon  2.048kB
Step 1/6 : FROM alpine:latest as step1
 ---> d4ff818577bc
Step 2/6 : RUN echo "STEP1"
 ---> Using cache
 ---> ca7b2711269c
Step 3/6 : FROM alpine:latest as step2
 ---> d4ff818577bc
Step 4/6 : RUN echo "STEP2"
 ---> Using cache
 ---> 50668d3ea1c2
Step 5/6 : FROM step1 as step3
 ---> ca7b2711269c
Step 6/6 : RUN echo "STEP3"
 ---> Using cache
 ---> f529239cd29a
Successfully built f529239cd29a

在 Ubuntu 上构建步骤 2:

$ docker build --target step2 .
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM alpine:latest as step1
 ---> d4ff818577bc
Step 2/4 : RUN echo "STEP1"
 ---> Using cache
 ---> ca7b2711269c
Step 3/4 : FROM alpine:latest as step2
 ---> d4ff818577bc
Step 4/4 : RUN echo "STEP2"
 ---> Using cache
 ---> 50668d3ea1c2
Successfully built 50668d3ea1c2

Ubuntu 上的 Docker 版本:

$ docker version
Client: Docker Engine - Community
 Version:           20.10.7
 API version:       1.41
 Go version:        go1.13.15
 Git commit:        f0df350
 Built:             Wed Jun  2 11:56:38 2021
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.7
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       b0f5bc3
  Built:            Wed Jun  2 11:54:50 2021
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.4.6
  GitCommit:        d71fcd7d8303cbf684402823e425e9dd2e99285d
 runc:
  Version:          1.0.0-rc95
  GitCommit:        b9ee9c6314599f1b4a7f497e1f1f856fe433d3b7
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

您可以看到 Docker Desktop (Windows) 跳过不需要的阶段,而 Ubuntu 上的 Docker 会构建它们。 Docker Engine 版本相同。

对于复杂的多阶段图像,与 Ubuntu 相比,Windows 上的 Docker 缓存行为可以节省大量构建时间。

如何使 Ubuntu 上的 Docker 在缓存方面的行为与 Windows 上的行为相同?

【问题讨论】:

  • 两台不同机器上的缓存可以以不同方式填充。在尝试构建相同的两个镜像之前,您可能已经在机器上构建了不同的镜像。要真正与同类进行比较,您需要先清除两台机器的缓存。无论哪种方式......你为什么关心缓存有多好 - 你应该只是在两种情况下都希望获得相同的图像,并将缓存/优化留给 docker 可执行文件的细节。
  • 当 Ubuntu(非 buildkit)输出显示 Using cache 时,它也跳过了这一步。如果您想进一步证明这一点,请尝试将其中一个步骤更改为 RUN sleep 5 并查看它是否处于休眠状态。
  • 这里的问题是我根本没有构建不需要的阶段。
  • 例如,如果 stage2 有命令COPY / /app,那么如果文件夹中的文件发生更改,那么无论缓存如何,stage2 都将在 Ubuntu 上重建。在 Windows 上,它将被跳过——正确的行为。
  • @DavidMaze,让我们进行如下更改:``` FROM alpine:latest as step1 RUN echo "STEP1" FROM alpine:latest as step2 RUN sleep 10 FROM step1 as step3 RUN echo "STEP3" ` `` 并通过docker build --no-cache .在不缓存的情况下运行构建,Windows 上的构建时间约为 1 秒,而在 Ubuntu 上则超过 10 秒。

标签: linux windows docker caching build


【解决方案1】:

我自己找到了答案。在 Ubuntu 上,我们需要通过 DOCKER_BUILDKIT=1 启用 BuildKit。见https://docs.docker.com/engine/reference/builder/#buildkit

在这种情况下,两个平台上的行为是相同的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    • 1970-01-01
    • 2020-08-25
    • 2017-12-16
    • 2023-03-10
    • 2020-11-23
    • 1970-01-01
    相关资源
    最近更新 更多