随着容器概念的普及,越来越多的系统以容器的形式部署升级,但随着时间的推移,我们会发现主机中的镜像文件越来越多,其中有很多旧版本的镜像,占用了大量的存储空间,此时就需要定期清理那些没有价值的镜像。

本文会根据笔者所负责的节点进行介绍。

一、介绍

节点特点:

  1. 节点中部署着多个指定版本的应用系统。
  2. 节点中存在应用系统历史版本的docker镜像文件。

清理目标:

  1. 清理非当前使用版本的镜像文件。
  2. 后续更新时不必花大量的时间重新拉取中间镜像层。

二、 分析现状

a. 主机镜像文件现状

docker镜像能删除吗 docker镜像清理_docker镜像能删除吗

b. 主机容器运行现状

docker镜像能删除吗 docker镜像清理_存储空间_02

c. 制作镜像的Dockerfile

docker镜像能删除吗 docker镜像清理_批量删除_03

d. 存储空间大小

docker镜像能删除吗 docker镜像清理_docker镜像能删除吗_04

分析:从上面的图中可知,主机中有如下几种镜像:

  1. 使用中的镜像:32.1.0.84/test/athena:develop_1749
  2. 历史版本镜像:32.1.0.84/test/athena:develop_1747
  3. 基础镜像:java:8
  4. dangling镜像:ID为1a9f88c0c230的镜像。(是由于使用同一个tag多次构建内容不同的镜像,导致较早的镜像变为dangling镜像)

dangling镜像和历史版本镜像是不再需要的镜像文件,白白占用了一定的存储空间,需要清理。使用中的镜像很明显不应该被清理。为了避免后续更新时花大量的时间重新拉取,所以基础镜像不应该被清理。

三、 分别处理各种镜像

3.1 dangling镜像

dangling是一种特殊的,不会再被使用到的镜像,docker有专门清理dangling镜像的命令。

docker image prune -f

从图中可以看出部分docker镜像已经被清理,并且提示释放了39.45MB的空间。

docker镜像能删除吗 docker镜像清理_docker镜像能删除吗_05

检查一下剩余的镜像,可以看见dangling镜像已经不存在了,符合预期。

docker镜像能删除吗 docker镜像清理_docker_06

检查当前的存储空间大小,可以发现释放了40MB的空间,也是符合预期的。

docker镜像能删除吗 docker镜像清理_批量删除_07

3.2 历史版本镜像

直接使用docker删除镜像的命令即可。

docker rmi [image]

从图中可以看出历史版本的镜像已经被清理。

docker镜像能删除吗 docker镜像清理_存储空间_08

检查一下剩余的镜像,可以看见历史版本镜像已经不存在了。

docker镜像能删除吗 docker镜像清理_批量删除_09

检查当前的存储空间大小,可以发现又释放了40MB的空间,也是符合预期的。

docker镜像能删除吗 docker镜像清理_批量删除_10

3.3 使用中的镜像

笔者需要在批量删除无用镜像的时候,保留使用中的镜像。幸运的是,docker的删除命令无法直接删除正在被容器使用的镜像。测试一下让自己放心。

docker镜像能删除吗 docker镜像清理_批量删除_11

3.4 基础镜像

为了后续更新的效率,笔者需要在批量删除无用镜像的时候,保留基础镜像。
由于基础镜像没有被容器直接使用,所以删除命令可以执行。测试如下:

docker镜像能删除吗 docker镜像清理_批量删除_12

刚开始看见命令被成功执行时,笔者心中是崩溃的,但是仔细看了一下显示的删除过程,发现只有“Untagged”而没有“Deleted”,心中窃喜,猜测是不是只删除了tag,镜像层并没有被删除。赶紧检查一下,果然发现和笔者猜想的一样,由于基础镜像中的镜像层目前正被容器使用着,所以并未被删除。

docker镜像能删除吗 docker镜像清理_docker镜像能删除吗_13

为了证实更新应用镜像时不会消耗大量时间去拉取基础镜像,笔者再次构建应用的镜像进行检查从而得以验证。

docker镜像能删除吗 docker镜像清理_docker_14

四、结论

  1. dangling镜像通过命令 docker image prune -f 清理。
  2. 通过命令 docker images | awk 'NR!=1{print $1":"$2}' | xargs docker rmi 可以批量清除无用的镜像,且不会影响使用中的镜像和基础镜像,满足笔者的需求。