镜像管理
创建镜像
docker pull
、docker build
、docker commit
、docker import
、docker load
都可以创建一个新的镜像,关于这些命令的使用详见命令行参考镜像管理。
注意事项
避免并发
docker load
和docker rmi
操作。 如果同时满足如下两个条件,可能导致并发性问题:- 某个镜像存在于系统中。
- 同时对该镜像进行
docker rmi
和docker load
操作。
所以使用时应该避免这种场景(注:所有的镜像创建操作如 tag,build,load 和 rmi 并发都有可能会导致类似的错误,应该尽量避免这类操作与 rmi 的并发)。
如果 Docker 操作镜像时系统掉电,可能导致镜像损坏,需要手动恢复。
由于 Docker 在操作镜像(pull/load/rmi/build/combine/commit/import 等)时,镜像数据的操作是异步的、镜像元数据是同步的。所以如果在镜像数据未全部刷到磁盘时掉电,可能导致镜像数据和元数据不一致。对用户的表现是镜像可以看到(有可能是 none 镜像),但是无法启动容器,或者启动后的容器有异常。这种情况下应该先使用
docker rmi
删除该镜像,然后重新进行之前的操作,系统可以恢复。生产环境节点应避免存留超大数量镜像,请及时清理不使用的镜像。
镜像数目过多会导致
docker image
等命令执行过慢,从而导致docker build/docker commit
等相关命令执行失败,并可能导致内存堆积。在生产环境中,请及时清理不再使用的镜像和中间过程镜像。使用
--no-parent
参数 build 镜像时,如果有多个 build 操作同时进行,并且 Dockerfile 里 FROM 的镜像相同,则可能会残留镜像,分为以下两种情况:- FROM 的镜像不是完整镜像,则有可能会残留 FROM 的镜像运行时生成的镜像。残留的镜像名类似 base_v1.0.0-app_v2.0.0,或者残留镜像。
- 如果 Dockerfile 里的前几条指令相同,则有可能会残留镜像。
可能会产生 none 镜像场景
- none 镜像是指没有 tag 的最顶层镜像,比如 ubuntu 的 imageID,只有一个 tag 是 ubuntu,如果这个 tag 没了,但是 imageID 还在,那么这个 imageID 就变成了 none 镜像。
- Save 镜像的过程中因为要把镜像的数据导出来,所以对 image 进行保护,但是如果这个时候来一个删除操作,可能会 untag 成功,删除镜像 ID 失败,造成该镜像变成 none 镜像。
- 执行
docker pull
时掉电,或者系统 panic,可能出现 none 镜像,为保证镜像完整性,此时可通过docker rmi
删除镜像后重新拉取。 - 执行
docker save
保存镜像时,如果指定的名字为镜像 ID,则 load 后的镜像也没有 tag,其镜像名为 none。
build 镜像的同时删除该镜像,有极低概率导致镜像 build 失败
目前的 build 镜像的过程是通过引用计数来保护的,当 build 完一个镜像后,紧接着就给该镜像的引用计数加1( holdon 操作),一旦 holdon 操作成功,该镜像就不会被删除了,但是在 holdon 之前,有极低的概率,还是可以删除成功,导致 build 镜像失败。
查看镜像
查看本地镜像列表:
docker images
删除镜像
注意事项
禁止使用 docker rmi –f XXX
删除镜像。如果使用强制删除, docker rmi
会忽略过程中的错误,可能导致容器或者镜像关元数据残留。如果使用普通删除,如果删除过程出错,则会删除失败,不会导致元数据残留。