重用 docker 构建镜像中的步骤。缓存?

mon*_*lls 7 docker dockerfile

我正在尝试提高 CI/CD 的速度。步骤之一是构建我的 docker 映像。构建镜像后,我将其推送到注册表,以便稍后在下一次 CI/CD 迭代中进行拉取||循环||在开始构建过程之前运行,以便重用 docker 构建镜像层缓存。预计此步骤需要一些时间,但是,如果之前已经构建了以前的图像,则可以减少时间。如果之前的行没有改变,docker 不应该重复(或者至少这是我所期望的)同一层(Dockerfile 行)。

下面是真实的例子:

我有这个目录

ls  
Dockerfile  
somefile.txt
Run Code Online (Sandbox Code Playgroud)

Dockerfile 内容:

cat Dockerfile
FROM ruby:2.7.4-slim

ENTRYPOINT irb
Run Code Online (Sandbox Code Playgroud)

当我第一次构建时:

docker build -t my-registry/my-docker-cache .
Sending build context to Docker daemon   2.56kB
Step 1/2 : FROM ruby:2.7.4-slim
 ---> db4073acbaac
Step 2/2 : ENTRYPOINT irb
 ---> Running in 14055ed3e5d1
Removing intermediate container 14055ed3e5d1
 ---> f4f317dde34d
Successfully built f4f317dde34d
Successfully tagged my-registry/my-docker-cache:latest
Run Code Online (Sandbox Code Playgroud)

一切都像预期的那样,没有缓存,每一步都被执行。如果我重复该命令:

docker build -t my-registry/my-docker-cache .
Sending build context to Docker daemon   2.56kB
Step 1/2 : FROM ruby:2.7.4-slim
 ---> db4073acbaac
Step 2/2 : ENTRYPOINT irb
 ---> Using cache
 ---> f4f317dde34d
Successfully built f4f317dde34d
Successfully tagged my-registry/my-docker-cache:latest
Run Code Online (Sandbox Code Playgroud)

一切都很好,正如预期的那样,步骤 2 说“使用缓存”,但它没有被执行。

我将把我的图像推送到注册表:

docker push my-registry/my-docker-cache
aaf6670012a0: Mounted from previous-image-in-other-experiments 
e21a639a3286: Mounted from previous-image-in-other-experiments
f01aae87d116: Mounted from previous-image-in-other-experiments
04f100f96a69: Mounted from previous-image-in-other-experiments
e1bbcf243d0e: Mounted from previous-image-in-other-experiments
latest: digest: sha256:317cbcbb751fc90e3656818a7942ddd67fb8cb9c24841f57cce272bc47c02ce5 size: 1366
Run Code Online (Sandbox Code Playgroud)

现在我将从本地 docker 中删除该映像:

docker rmi my-registry/my-docker-cache
Untagged: my-registry/my-docker-cache:latest
Untagged: my-registry/my-docker-cache@sha256:317cbcbb751fc90e3656818a7942ddd67fb8cb9c24841f57cce272bc47c02ce5
Deleted: sha256:f4f317dde34ddba589867c3d81af9cd6fe30732afc0173a53740c271d2b70ed3
Run Code Online (Sandbox Code Playgroud)

现在我将从注册表中提取:

docker pull my-registry/my-docker-cache
Using default tag: latest
latest: Pulling from my-docker-cache
eff15d958d66: Already exists 
923e91ae3a1b: Already exists 
2aa5d3a4a151: Already exists 
bc64adf2d0b2: Already exists 
bfc5cca7d80e: Already exists 
Digest: sha256:317cbcbb751fc90e3656818a7942ddd67fb8cb9c24841f57cce272bc47c02ce5
Status: Downloaded newer image for my-registry/my-docker-cache:latest
my-registry/my-docker-cache:latest
Run Code Online (Sandbox Code Playgroud)

现在,即使使用相同的名称,我也将再次构建图像​​:

docker build -t my-registry/my-docker-cache .
Sending build context to Docker daemon   2.56kB
Step 1/2 : FROM ruby:2.7.4-slim
 ---> db4073acbaac
Step 2/2 : ENTRYPOINT irb
 ---> Running in b779e2e702bf
Removing intermediate container b779e2e702bf
 ---> 73464e25f559
Successfully built 73464e25f559
Successfully tagged my-registry/my-docker-cache:latest
Run Code Online (Sandbox Code Playgroud)

我原以为步骤 2 会说“使用缓存”并且不执行。在这种情况下,ENTRYPOINT 步骤运行得很快,但在RUN bundle installRUN apt update的情况下;apt install bla bla bla不一样。

我做错了什么,或者我可以做些什么来实现我的目标?

docker version
Client: Docker Engine - Community
 Cloud integration: v1.0.28
 Version:           20.10.17
 API version:       1.41
 Go version:        go1.17.11
 Git commit:        100c701
 Built:             Mon Jun  6 23:02:57 2022
 OS/Arch:           linux/amd64
 Context:           desktop-linux
 Experimental:      true

Server: Docker Desktop 4.11.0 (83626)
 Engine:
  Version:          20.10.17
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.17.11
  Git commit:       a89b842
  Built:            Mon Jun  6 23:01:23 2022
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.6
  GitCommit:        10c12954828e7c7c9b6e0ea9b0c02b01407d3ae1
 runc:
  Version:          1.1.2
  GitCommit:        v1.1.2-0-ga916309
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
Run Code Online (Sandbox Code Playgroud)

Man*_*ash 1

来源

您需要显式指定要引用 Docker 进行缓存的映像。尝试这个:

docker build --cache-from my-registry/my-docker-cache:latest -t new_img .