写在前面

请先看第五节,这很重要。
请先看第五节,这很重要。
请先看第五节,这很重要。

重要的事情说三遍。

一、查询镜像digest值

命令如下,注意请求头需要加入"Accept: application/vnd.docker.distribution.manifest.v2+json",不然会返回错误的digest。

curl --header "Accept:application/vnd.docker.distribution.manifest.v2+json" -I -XGET http://10.19.154.240:5000/v2/test(镜像路径)/tomcat(镜像名称)/manifests/V1.1.0(镜像版本)

返回示例:

HTTP/1.1 200 OK
Content-Length: 1583
Content-Type: application/vnd.docker.distribution.manifest.v2+json
Docker-Content-Digest: sha256:fb26b27060091b971a1e9ec332c15eeac09a079a4c201808426adae940cb4d86
Docker-Distribution-Api-Version: registry/2.0
Etag: “sha256:fb26b27060091b971a1e9ec332c15eeac09a079a4c201808426adae940cb4d86”
X-Content-Type-Options: nosniff
Date: Wed, 22 Dec 2021 08:10:27 GMT

二、根据digest进行删除操作

1.命令行调用删除接口

上一步获取到digest后使用命令行调用如下接口:

curl -X DELETE http://10.19.154.240:5000/v2/test/tomcat/manifests/sha256:fb26b27060091b971a1e9ec332c15eeac09a079a4c201808426adae940cb4d86

此时若删除成功,则调用
curl -X GET http://10.19.154.240:5000/v2/test/tomcat/tags/list
返回结果中tags为null,示例:

{“name”:“test/tomcat”,“tags”:null}

2.可能出现的问题,删除时返回UNSUPPORTED

如果删除失败,且返回如下内容:

{“errors”:[{“code”:“UNSUPPORTED”,“message”:“The operation is unsupported.”}]}

是由于docker registry默认不允许删除镜像,有两种方式解决。

解决方式1

在配置文件config.yml中增加delete:enabled: true字段
① 进入docker容器(只有在运行中的容器才能进去)

docker exec -it <容器ID|容器名称> /bin/sh
cd /var/lib/registry/

② 修改config.yml文件

打开config.yml文件

cd /etc/docker/registry/
vi config.yml

在storage:下加入delete:enabled: true,示例如下,注意enabled:后面是有空格的,不可以省略,如果不加空格,容器会无法启动。

version: 0.1
log:
  fields:
    service: registry
storage:
  cache: 
    blobdescriptor: inmemory
  filesystem:
    rootdirectory: /var/lib/registry
  delete:
    enabled: true
http:        
  addr: :5000                        
  headers:                           
    X-Content-Type-Options: [nosniff]
health:          
  storagedriver: 
    enabled: true
    interval: 10s
    threshold: 3

③ 退出容器:输入exit或者按键Ctrl + D
④ 重启容器以使改动生效

docker restart docker-registry

⑤ 如果重启发现容器未正常启动,并且docker start也不能启动容器,很有可能就是由于之前的config.yml文件改坏了,可以通过docker logs -f CONTAINER_NAME查看错误日志。如果确实是config.yml文件的问题,由于容器未启动没法进入容器,就只能把文件copy出来改了再copy回去覆盖原来的文件,示例如下:

[yogi@master ~]$ docker cp docker-registry:/etc/docker/registry/config.yml .
[yogi@master ~]$ vi config.yml 
[yogi@master ~]$ docker cp config.yml docker-registry:/etc/docker/registry
[yogi@master ~]$ docker start docker-registry
解决方式2

在启动registry时指定以下环境变量:-e REGISTRY_STORAGE_DELETE_ENABLED=true
注意启动时指docker run 而不是docker start,所以如果已经有容器在运行了,则不推荐使用这种方式,因为这种方式只能把之前的registry容器stop后,重新run一个新的registry容器(不能和之前的重名,但由于之前的容器已经stop,端口号可以一样,相当于直接弃用了之前的容器)。

三、使用registry gc清除blobs

第二步成功后,只是无法再pull镜像,但磁盘空间没有被释放,需要使用registry gc清理无效blobs。

docker exec docker-registry(容器名) bin/registry garbage-collect /etc/docker/registry/config.yml

也可以进入容器后再使用registry gc,在使用前后通过du -sch命令来看磁盘占用,以判断空间是否释放。

docker exec -it docker-registry /bin/sh
cd /var/lib/registry/
du -sch
registry garbage-collect /etc/docker/registry/config.yml
du -sch

四、删除目录

在清除blobs后,使用curl http://10.19.154.240:5000/v2/_catalog依旧能查询到镜像目录,因此还需要进行目录删除操作。注意这里的镜像名是包含路径的,例如test/tomcat。

docker exec <容器名> rm -rf /var/lib/registry/docker/registry/v2/repositories/<镜像名>

执行该步骤后,就无法查询到该镜像啦~

五、其实可以只进行第三、四步(!)

如果需要彻底删除,只需进行第三四步,也就是先进行第四步的删除目录,再进行第三步的gc操作,就可以到达彻底删除的目的。
如果只需要软删除,则只需进行第一、二步,无需进行后面两步。

为什么我把这个写在了第五步呢…因为这个就是我的踩坑过程,一边踩坑一边完成的这篇博客,因此当我发现彻底删除只需要4->3这两步的时候,前面的我都已经写好了…所以将就着看吧。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐