首页 > 运维 > Docker > Docker镜像none:none原因剖析
2019
11-01

Docker镜像none:none原因剖析

images <none>:<none>

要了解这一点,我们需要了解Docker的镜像文件系统如何工作以及镜像层的组织方式。出于本文的目的,我将使用debian:stretch作为示例。Docker守护程序正在我的笔记本电脑上运行,我将从docker hub中提取一个debian:stretch镜像。

我的Dockerfile

运行它 docker build -t debain:testv1 .

运行完成后 docker images -a

如您在上面的屏幕截图中所见,
docker images -a显示了多个none镜像
debian:stretch
9个<none>:<none>
作为Docker用户,您会发现这些
<none>:<none>镜像随着我们下载的镜像数量呈指数增长。
这些:图像代表什么?要了解这一点,让我们深入看看Docker的文件系统层的组织方式。 我们知道每个镜像均由镜像层组成,这些镜像层之间具有父子层次关系。就像洋葱一样,一层一层,默认情况下,所有docker文件系统层均存储在/var/lib/docker/graph。Docker将其称为镜像仓库。在此示例debian:stretch中,我们由10层组成/var/lib/docker/graph。我们来看下图就不难发现(下图为执行dokcerfile文件安装时候的日志)

我们说过Docker镜像是一层一层的,也就是说,一层为一个镜像,这镜像当中存在继承,子镜像啊这类关系。

打开刚才安装获取的源数据目录查看

cd /var/lib/docker/image/overlay2/imagedb/metadata/sha256/

这里就是安装日志中产生的源镜像,与之对应的是为 <none>:<none>的 镜像

如你所见,镜像ID对应与上图目录中的镜像层,要完成docker pull debain:staretch 这条命令. 他的执行过程是,一次下载一层镜像. 来看张图

所以我们说对了。现在我们了解了这些<none>:<none>图像的含义。它们代表中间镜像,可以使用命令看到docker images -a。它们不会导致磁盘空间问题,但是占用屏幕显示空间。由于所有这些<none>:<none>图像在其含义上都可能会造成混乱。

错误的<none>:<none>

<none>:<none>映像的另一种样式是悬挂的映像,它可能导致磁盘空间问题。

在Java或Golang等编程语言中,空的内存块是任何代码段都未引用的块。这些语言的垃圾回收系统会定期标记空的块,并将其返回到堆,以便这些内存块可用于将来的分配。同样,Docker中空的文件系统层是未使用的,并且未被任何镜像引用。因此,我们需要Docker清除这些悬空镜像的机制。

这些空的或者说未被引用的镜像我们知道他们需要被清理,但是他们来自哪里呢?

之前看一篇老外文章说是这些空镜像是build或者pull来的,我觉得他说的还不够完善,确切的说打标签tag ,提交commit 都会造成这种情况。

举例:

  • 当前我们pull了一个镜像,名字叫hello 标签叫 v1
  • 然后过了半个月官方的这个镜像更新了,
  • 然后你再从官方pull了下这个镜像,名字依然叫hello,标签叫v1。新的标签的引用使旧的镜像变得没有标签,或者说丢失掉了标签。

这样说可能不太直观,但是这个的更新需要时间,我不好立马复现错误。

这样我用提交镜像commit来复现一下,这个旧的镜像被新的镜像剥夺标签的过程

从图中可以看出第二次提交的容器剥夺了第一次提交容器的存储库名称和标签名称,使得第一次提交的容器镜像库名称与标签都变成了<none>:<none>

同理,pull ,build也是这个道理。

删除办法

执行命令:

回过头来再想想我的debian:stretch build为什么出现了这种情况呢

打开这个Dockerfile脚本看看我们发现了什么?

正式因为这条apt-get update更新,导致的,我们删除这条update再build试试

<none>:<none>的问题没有了

最后编辑:
作者:shooter
这个作者貌似有点懒,什么都没有留下。