Docker下载更新的图像以进行所谓的缓存摘要



我的Dockerfile有第一步:

FROM python:3.6.10@sha256:6cd232ed00e729b4d4d3aa57c1764dddfab70f616042b7f36536e2c3d70c4c11

这样做的目的是"锁定"或"固定"图像的版本。

有一段时间,docker build正确地使用了缓存版本:

Step 1/2 : FROM python:3.6.10@sha256:6cd232ed00e729b4d4d3aa57c1764dddfab70f616042b7f36536e2c3d70c4c11
---> 114ae8bdb954

但过了一段时间,它决定"下载一个更新的图像":

Step 1/2 : FROM python:3.6.10@sha256:6cd232ed00e729b4d4d3aa57c1764dddfab70f616042b7f36536e2c3d70c4c11
sha256:6cd232ed00e729b4d4d3aa57c1764dddfab70f616042b7f36536e2c3d70c4c11: Pulling from library/python
7e2b2a5af8f6: Pulling fs layer
09b6f03ffac4: Pulling fs layer
dc3f0c679f0f: Pulling fs layer
fd4b47407fc3: Pulling fs layer
bb7b28578995: Pulling fs layer
6ebea4a9a306: Pulling fs layer
22a2327cd1ca: Pulling fs layer
bfbf91c84bbe: Pulling fs layer
f6b29b259c5c: Pulling fs layer
09b6f03ffac4: Verifying Checksum
09b6f03ffac4: Download complete
dc3f0c679f0f: Download complete
7e2b2a5af8f6: Verifying Checksum
7e2b2a5af8f6: Download complete
6ebea4a9a306: Verifying Checksum
6ebea4a9a306: Download complete
fd4b47407fc3: Verifying Checksum
fd4b47407fc3: Download complete
bfbf91c84bbe: Verifying Checksum
bfbf91c84bbe: Download complete
f6b29b259c5c: Verifying Checksum
f6b29b259c5c: Download complete
22a2327cd1ca: Verifying Checksum
22a2327cd1ca: Download complete
bb7b28578995: Verifying Checksum
bb7b28578995: Download complete
7e2b2a5af8f6: Pull complete
09b6f03ffac4: Pull complete
dc3f0c679f0f: Pull complete
fd4b47407fc3: Pull complete
bb7b28578995: Pull complete
6ebea4a9a306: Pull complete
22a2327cd1ca: Pull complete
bfbf91c84bbe: Pull complete
f6b29b259c5c: Pull complete
Digest: sha256:6cd232ed00e729b4d4d3aa57c1764dddfab70f616042b7f36536e2c3d70c4c11
Status: Downloaded newer image for python@sha256:6cd232ed00e729b4d4d3aa57c1764dddfab70f616042b7f36536e2c3d70c4c11
---> 114ae8bdb954

即使这个步骤的最终散列是相同的:

---> 114ae8bdb954

据我所知,摘要(sha256:...(是不可变的
那么它们毕竟是可变的吗
或者缓存的版本以某种方式被删除了
发生了什么事,我该如何解决?

考虑到这并不是每次运行都会发生的,而且如果您在本地测试,也可能不会发生,所以问题似乎不在Dockerfile或FROM行。Docker不会自动清理缓存,因此您需要调查哪些外部进程正在删除缓存。由于您使用kubernetes插件在Jenkins中运行构建,因此问题似乎来自该插件在超时后清理构建代理。从文档中,您可以看到各种设置来调整这个构建器:

  • podRetention控制保留从属pod的行为。可以是"never(("、"onFailure((","always(("或"default(("-如果为空则默认为在activeDeadlineSeconds通过后删除pod
  • activeDeadlineSeconds如果podRetention设置为'never(('或'onFailure((',则pod将在此截止日期后删除
  • idleMinutes允许Pod保持活动状态以供重复使用,直到自上次步骤之后经过配置的分钟数对其执行

解决临时生成代理的一种方法是使用docker build命令中的--cache-from选项。对于经典构建(vs buildkit(,您需要首先在本地提取此图像。该图像将来自以前的构建,并且您可以为缓存使用多个图像,这对于多阶段构建特别有用,因为您需要为每个阶段提取缓存。这个标志告诉docker信任从注册表中提取的图像,因为通常只有本地构建的图像是可信的(有人可能会注入恶意图像,该图像声称在流行图像中运行了步骤,但在该层的tar中包含恶意软件(。

有两种摘要:注册表中图像清单的摘要和本地图像的JSON配置的摘要,其中还包含图像内容的摘要。

第一摘要:python:3.6.10@sha256:6cd232ed00e729b4d4d3aa57c1764dddfab70f616042b7f36536e2c3d70c4c11是Docker Hub中清单的摘要作为引用。

尊严是不可变的。

如果两个不同的东西产生相同的摘要值,那么散列函数(本例中使用的是sha256(将被破坏,无法再使用。请参见碰撞。

在您的案例中,由于某种原因,它不再找到缓存的图像。它再次下载了同一张图片。

最后得到的摘要(---> 114ae8bdb954(是该图像(图像ID(的结果配置的摘要。

您可以确认下载了正确的清单:

docker inspect 114ae8bdb954 

其中包括:

"RepoDigests": [
"python@sha256:6cd232ed00e729b4d4d3aa57c1764dddfab70f616042b7f36536e2c3d70c4c11"
],

由于图像id在两种情况下都是相同的,我认为没有什么可修复的。但是,如果总是发生这种情况,那么缓存就会出现一些问题。

关于缓存的编辑:如果这是在docker场景中的docker中完成的,那么如果在父docker中构建阶段之前发生了变化,它将始终再次重建此映像。

有关图像id的详细信息:https://windsock.io/explaining-docker-image-ids/

运行此时

docker run -d -p 4445:4444 --platform linux/amd64 selenium/standalone-chrome:4.2.2

我看到这个

Status: Downloaded newer image for selenium/standalone-chrome:4.2.2

这让我觉得docker忽略了我对4.2.2的请求,转而获取更新的图像。我特别不想让它这么做。

然而,这只是来自docker的一条模棱两可/误导性的信息。这意味着Docker在DockerHub上发现了一个比我在本地拥有的selenium/standalone-chrome:4.2.2映像更新的版本,尽管它们都有标签4.2.2。这并不意味着Docker拉了一个4.2.2以外的版本。

注意(2022年4月(:有一个用于钉扎的RFC"来源":moby/buildkit第2794期,来自Akihiro Suda(NTT公司软件工程师(
它将介绍:

Dockerfile.sum是go.sum的等价物,但s/go/Dockerfile/除外。

内容是BuildInfo:的子集

{
"sources": [
{
"type": "docker-image",
"ref": "docker.io/library/alpine:latest",
"pin": "sha256:4edbd2beb5f78b1014028f4fbb99f3237d9561100b6881aabbf5acce2c4f9454"
},
{
"type": "http",
"ref": "https://raw.githubusercontent.com/moby/buildkit/v0.10.1/README.md",
"pin": "sha256:6e4b94fc270e708e1068be28bd3551dc6917a4fc5a61293d51bb36e6b75c4b53"
}
]
}
When `Dockerfile.sum` exists in the context, the Dockerfile builder does:
- Pinning the digest of docker-image sources (`FROM ...`)
- Pinning the digest of http sources (`ADD https://...`)
- Recording the consumed entries to the build info structure (`["containerimage.buildinfo"].consumedPin`)
In the future, Dockerfile should also support `ADD git://...` and pinning its commit hash.

这是一种向最终用户提供/显示buildinfo功能的方式,参与构建再现性。


2023年9月更新:须田昭弘现在添加:

我们现在有了源策略文件:Buildkit/复制固定的依赖项(自Buildkit v0.112023年1月以来(:

示例:

{
"rules": [
{
"action": "CONVERT",
"selector": {
"identifier": "docker-image://docker.io/library/alpine:latest"
},
"updates": {
"identifier": "docker-image://docker.io/library/alpine:latest@sha256:4edbd2beb5f78b1014028f4fbb99f3237d9561100b6881aabbf5acce2c4f9454"
}
},
{
"action": "CONVERT",
"selector": {
"identifier": "https://raw.githubusercontent.com/moby/buildkit/v0.10.1/README.md"
},
"updates": {
"attrs": {"http.checksum": "sha256:6e4b94fc270e708e1068be28bd3551dc6917a4fc5a61293d51bb36e6b75c4b53"}
}
}
]
}

最新更新