如何删除docker-register镜像及none无效镜像详解

背景介绍

我们大家在服务器上搭建了docker registry,所有的构建镜像都会集中在一个服务器上,久而久之硬盘就被塞满了。本文会着重介绍两种清理方式。一是<none>标签的镜像,二是删除docker物理镜像。下面话不多说了,来一起看看详细的介绍吧。

docker<none>镜像

有效的 none 镜像

为了理解 <none> 镜像,我们先要理解 Docker镜像系统的工作机制,以及 layers是如何组织起来的。

当我拉取一个stresser镜像的时候,运行 docker images -a命令,会发现我凭空多出来一个< none>:< none> 镜像。

➜ docker images -a
REPOSITORY  TAG   IMAGE ID  CREATED  SIZE
stresser   latest  68ee9b96793e 9 days ago  242MB
<none>   <none>  dbcff8952263 9 days ago  242MB

当我要删除这个< none>镜像的时候,执行下面的命令,会提示失败,我要删除stresser镜像才能顺带把<none>镜像删除。

➜ docker rmi dbcff8952263
Error response from daemon: conflict: unable to delete dbcff8952263 (cannot be forced) - image has dependent child images

➜ docker rmi 68ee9b96793e
Untagged: stresser:latest
Deleted: sha256:68ee9b96793e0a3b3a77ec713f1bf4eb19446bd13fb933557dc401e452ca04c4
Deleted: sha256:dbcff895226371eba2640c178414f5828aa5e6f417978b63ffa490d3865dc79a
Deleted: sha256:875a0b6d28d1f52fc980a0948055d3ec3a38158ff7aa6a1a2c19c4243b96a57a

➜ docker rmi dbcff8952263
Error response from daemon: No such image: dbcff8952263:latest

<none>:<none> 镜像是干嘛的?我们先看看Docker文件系统的组成,docker镜像是由很多 layers组成的,每个 layer之间有父子关系,所有的docker文件系统层默认都存储在/var/lib/docker/graph目录下,docker称之为图层数据库,在这个例子中 stresser 由两层(layer)组成,我们可以在/var/lib/docker/graph目录下找到层。

当我们pull stresser镜像的时候,最先下载的是 dbcff8952263 < none>父层,接下来才会下载stresser:latest,stresser由两层组成。 我们可以进入 cat /car/lib/docker/graph/${containerId}/json ,查看镜像的元数据来了解详细信息(下面样例是其他的容器信息)

{"id":"37dd4150474449629e8a7b576eed26cb8583d2fe5a3edf10fd84323dfd538678","parent":"5cf74bcb1bde2e2249824a682f45235954543a5d57081db22c96402342db49e9","created":"2017-04-06T16:28:35.51523979Z","container_config":{"Hostname":"","Domainname":"","User":"","Memory":0,"MemorySwap":0,"CpuShares":0,"Cpuset":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"ExposedPorts":null,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":["/bin/sh -c set -e; \u0009NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; \u0009found=''; \u0009for server in \u0009\u0009ha.pool.sks-keyservers.net \u0009\u0009hkp://keyserver.ubuntu.com:80 \u0009\u0009hkp://p80.pool.sks-keyservers.net:80 \u0009\u0009pgp.mit.edu \u0009; do \u0009\u0009echo \"Fetching GPG key $NGINX_GPGKEY from $server\"; \u0009\u0009apt-key adv --keyserver \"$server\" --keyserver-options timeout=10 --recv-keys \"$NGINX_GPGKEY\" \u0026\u0026 found=yes \u0026\u0026 break; \u0009done; \u0009test -z \"$found\" \u0026\u0026 echo \u003e\u00262 \"error: failed to fetch GPG key $NGINX_GPGKEY\" \u0026\u0026 exit 1; \u0009exit 0"],"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"NetworkDisabled":false,"MacAddress":"","OnBuild":null,"Labels":null},"author":"NGINX Docker Maintainers \"docker-maint@nginx.com\"","Size":4901}

最后做一个总结::镜像是一种中间镜像,我们可以使用`docker images -a`来看到,他们不会造成硬盘空间占用的问题(因为这是镜像的父层,必须存在的),但是会给我们的判断带来迷惑。

无效的 none 镜像

另一种类型的 < none>:< none> 镜像是dangling images ,这种类型会造成磁盘空间占用问题。

像Java和Golang这种编程语言都有一个内存区,这个内存区不会关联任何的代码。这些语言的垃圾回收系统优先回收这块区域的空间,将他返回给堆内存,所以这块内存区对于之后的内存分配是有用的

docker的悬挂(dangling)文件系统与上面的原理类似,他是没有被使用到的并且不会关联任何镜像,因此我们需要一种机制去清理这些悬空镜像。

我们在上文已经提到了有效的< none>镜像,他们是一种中间层,那无效的< none>镜像又是怎么出现的?这些 dangling镜像主要是我们触发 docker build docker pull命令产生的。

用一个例子来讲解:

假设我们要构建一个新的镜像,Dockerfile 文件如下

FORM Ubuntu:latest
RUN echo 'hello world'

当我们构建 docker build -t hello-world ./ 的时候,会生成一个新的镜像。

可是过了一个月之后,Ubuntu发布了新的镜像,这个时候我们再次构建一个 hello world镜像,会依赖于最新的 Ubuntu

问题来了,我们引用旧的Ubuntu的hello-world镜像,这个时候就会成为没有标签的 dangling镜像!使用下面的命令可以清理

docker rmi $(docker images -f "dangling=true" -q)

docker没有自动垃圾回收处理机制,未来可能会有这方面的改进,但是目前我们只能这样手动清理(写个脚本就好)。

删除本地硬盘的镜像

当我们registry服务器存在很多tag标签的镜像,但是硬盘空间不够用的时候,我们会希望删除存量的镜像给服务器腾出空间,registry自带了API接口删除镜像,但是即使我们调用了,他也只是逻辑层面的删除,软删除(soft delete),只是把二进制和镜像的关系解除罢了,实际上镜像一直存在我们的硬盘中,我们需要一种方式彻底物理删除存量空间。网上有第三方的解决方案:delete-docker-registry-image,接下来列出操作步骤,操作之前先把 registry服务停掉。

安装:

curl https://raw.githubusercontent.com/burnettk/delete-docker-registry-image/master/delete_docker_registry_image.py | sudo tee /usr/local/bin/delete_docker_registry_image >/dev/null
sudo chmod a+x /usr/local/bin/delete_docker_registry_image

设置环境变量:数据存放地址:

我服务器上registry的配置如下:

 volumes:
 - /root/docker-data/registry/data:/var/lib/registry
root@iZ94ft8hgzqZ:~/docker-data/registry/data/docker/registry/v2/repositories# ls -al
total 108
drwxr-xr-x 27 root root 4096 Aug 21 18:29 .
drwxr-xr-x 4 root root 4096 Oct 30 2015 ..
drwxr-xr-x 5 root root 4096 Mar 27 2016 example
drwxr-xr-x 5 root root 4096 Mar 20 19:25 gitlab_ansible
drwxr-xr-x 5 root root 4096 Mar 22 2016 hlpays-job
drwxr-xr-x 5 root root 4096 Jan 26 2016 hlpays-oa
drwxr-xr-x 5 root root 4096 Mar 24 2016 hlpays-portal
drwxr-xr-x 5 root root 4096 Mar 27 18:32 ifex-crm
export REGISTRY_DATA_DIR=/root/docker-data/registry/data/docker/registry/v2

逻辑删除:

delete_docker_registry_image –image tickets –dry-run ; 只是逻辑删除,没什么用,演示一下而已。。。

root@iZ94ft8hgzqZ:~/docker-data/registry/data/docker/registry/v2/repositories# delete_docker_registry_image --image tickets --dry-run

INFO [2017-09-13 18:21:04,505] DRY_RUN: would have deleted /root/docker-data/registry/data/docker/registry/v2/blobs/sha256/27/27dedd9200ff607e76eb9d0e10beb103f53551e4ed39829d767cfbc208b79581
INFO [2017-09-13 18:21:04,506] DRY_RUN: would have deleted /root/docker-data/registry/data/docker/registry/v2/blobs/sha256/1b/1b2aade332a7133b1a03cae7695a3dcf9413dd017ff41f35a1bb1506becbacf3

物理数据删除:

删除物理内存,能看到硬盘空间已经空出来了。

delete_docker_registry_image --image tickets

df -h 

删除指定标签:

delete_docker_registry_image --image testrepo/awesomeimage:supertag

其他用法请参照官网

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • 详解docker强制批量删除none的image镜像

    说正题,今天遇到的问题是自己在开发机做坏了几个image镜像,删不了   我想大家也遇到过这样类似的问题  -. 他的名字和tag都是为none,空- 以前看过一个帖子说,给他标记一个tag,就可以干掉,瞎扯- [ruifengyun@bj-buzz-dev01 extractor_docker]$ [ruifengyun@bj-buzz-dev01 extractor_docker]$ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL

  • docker 如何删除none镜像

    删除none的镜像,要先删除镜像中的容器.要删除镜像中的容器,必须先停止容器. $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE <none> <none> 168b258ceea3 34 seconds ago 460.6 MB <none> <none> b2c5d34941c6 23 minutes ago 588.7 MB tankzhang/es v1 85fc66558c37 13 days

  • Docker 最常用的镜像命令和容器命令详解

    本文列出了 Docker 使用过程中最常用的镜像命令和容器命令,以及教大家如何操作容器数据卷,实现容器数据的备份.熟练练习这些命令以后,再来一些简单的应用部署练习,大家就可以学习 Docker 的镜像构建.备份恢复迁移.镜像仓库.网络.集群等等更多的内容. 镜像相关命令 官方文档:https://docs.docker.com/reference/ 查看镜像 [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZ

  • Docker创建自己的镜像与上传流程详解

    目录 引入 了解Docker的资源隔离和主机模式 创建 centos7 容器 部署mysql5.7 创建Docker Hub仓库 生成镜像 提交镜像 引入 在部署毕节服务器时遇到了个问题:   因为在三台服务器做好ovirt-engine超融合后,在主节点服务器上部署可视化平台需要安装mysql5.7,但是安装mysql时需要卸载一些依赖,但是由于怕影响原有的postgresql数据库和ovirt-engine的服务组件,选择了用docker容器部署mysql数据库.   在顺利创建好容器,配置

  • docker swarm 集群故障与异常详解

    本文介绍了docker swarm 集群故障与异常详解,分享给大家,具体如下: 在上次遭遇 docker swarm 集群故障后,我们将 docker 由 17.10.0-ce 升级为最新稳定版 docker 17.12.0-ce . 前天晚上22:00之后集群中的2个节点突然出现CPU波动,在CPU波动之后,在凌晨夜深人静.访问量极低的时候,整个集群出现了故障,访问集群上的所有站点都出现了502,过了一段时间后自动恢复正常. ECS实例:swarm1-node5,CPU百分比于00:52发生告

  • Docker如何部署Python项目的实现详解

    Docker 是一个开源项目,为开发人员和系统管理员提供了一个开放平台,可以将应用程序构建.打包为一个轻量级容器,并在任何地方运行.Docker 会在软件容器中自动部署应用程序. 在本篇中,我将介绍如何 docker 化一个 Python Django 应用程序,然后使用一个 docker-compose 脚本将应用程序作为容器部署到 docker 环境. 环境 操作系统 dbnuo@localhost ~ sw_vers ProductName: Mac OS X ProductVersion

  • docker容器的创建及常用操作命令详解

    目录 docker容器简介 1.创建容器 2.查看本机的容器列表 3.停止和启动一个容器 4.删除容器 5.查看容器内容 6.复制命令 7.进入容器 docker容器简介 容器就是对外提供服务的一个实例. 容器启动的必要条件:容器内至少有一个进程运行在前台 1.创建容器 # 格式 docker run [参数] [镜像名称] [运行容器的启动命令] # 参数 -d : 以守护进程的方式运行一个容器 docker run -d [镜像名称] [cmd] --name : 指定容器的名称 docke

  • docker 安装ElasticSearch 6.x的教程详解

    首先是拉去镜像(或者直接创建容器自然会拉去) docker pull elasticSearch:6.5.4 创建容器 docker run --name elasticsearch --net host -e "discovery.type=single-node" -e "network.host=IP地址" elasticsearch:6.5.4 启动 docker start elasticsearch 查看日志 docker logs elasticsea

  • Docker部署安装Redash中文版的方法详解

    1安装说明 相比Linux环境本地安装而言,Docker安装方式更为简便,Docker脚本化安装过程会自动获取Redis.postgres.Python3.7镜像,构造Redash最新的后台server.worker.schedule镜像.前端npm依赖包安装和前端最新代码打包是通过卷映射方式挂载到server容器,因此这些工作需要人工一次执行:另外构建初始数据库表结构也需要人工一次执行.这些动作执行完毕,启动Docker容器就可以访问了.由于安装过程需要访问国外服务器,极难一次安装成功,需要反

  • docker下的 redis 之持久化存储详解

    本章节开始 我们在docker下 进行 spring Boot项目操作redis 准备工作: (1) 创建文件夹:usr/local/work/share (2) 拉取项目,这是一个打包好的jar包 (3) 将拉取的 jar包放到刚刚创建的文件夹下,同时再创建一个名字为 docker-compose.yml的文件 (4) 在 tmp目录中创建一个 data 文件夹 (5) 并在 docker-compose.yml文件中写入以下内容: redis: image: redis:3 ports: -

  • 使用 Docker 搭建 Laravel 本地环境的教程详解

    Laravel 官方提供 Homestead 和 Valet 作为本地开发环境,Homestead 是一个官方预封装的 Vagrant Box,也就是一个虚拟机,但是跟 docker 比,它占用体积太大,启动速度慢,同时响应速度很慢,现在有了 docker 这种更好的方式,可以轻松方便的搭建整套 PHP 开发环境. 本文就介绍如何使用 docker 搭建 Laravel 本地环境. 安装 docker 首先安装 docker. 克隆 laradock laradock 官方文档: http://

  • Oracle删除表及查看表空间的实例详解

    Oracle常用的基本命令 --1.用户下表中注释模糊查询: 例如查询与优惠券关联的表 SELECT * FROM user_tab_comments t WHERE t.comments LIKE '%优惠券%'; ![这里写图片描述](http://img.blog.csdn.net/20170321112728053?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDQyNzkzNQ==/font/5a6L5L2T/fontsize/40

随机推荐