Docker 私有仓库搭建,私有库镜像的推送 、拉取和删除

一.搭建私有库

docker run -d -p 5000:5000 -v /opt/data/registry:/var/lib/registry  -v /data/config.yml:/etc/docker/registry/config.yml --name myregistry registry

第一个-v 是挂载的私有镜像存放的目录,挂载到本机后即使容器被删除,私有库中的镜像不会丢失

第二个-v 是挂载 config.yml 配置文件,如果想要支持删除私有库中的镜像,需要修改该配置文件

执行这个命令会报错,如下:
在这里插入图片描述
有问题的是 -v /data/config.yml:/etc/docker/registry/config.yml 这段命令,
报错的意思是说:我们是否将文件挂载到目录上或者将目录挂载到文件上了
这时我进入我挂载该配置文件的路径看看,
发现挂载时自动创建的config.yml 是个目录而不是文件。
在这里插入图片描述
解决方法:
我们先删掉之前没跑成功的容器

docker rm myregistry

再运行一个registry 容器

docker run –d –name registryTemp registry

将容器内的config.yml 复制到 我们想挂载的目录下

docker cp registryTemp:/etc/docker/registry/config.yml /data/

然后停掉这个容器并删除

docker stop registryTemp

docker rm registryTemp

最后再重新运行registry 容器并挂载目录和文件

docker run -d -p 5000:5000 -v /opt/data/registry:/var/lib/registry  -v /data/config.yml:/etc/docker/registry/config.yml –name myregistry registry

小结:在使用docker 挂载单个文件时,需要我们的挂载目录下存在该同名文件,当然,在挂载目录下新建一个同名文件再挂载也可以避免报错,但是这样可能导致容器跑不起来。最好是将容器内的源文件拷贝到需要挂载的目录下,再运行容器并挂载文件。

容器跑起来后可以查看容器内的镜像

查看所有的镜像(localhost可换成ip)
curl localhost:5000/v2/_catalog

查看某个镜像的所有tags( <镜像repository> 为push前执行tag命令时自定义的repository)
curl localhost:5000/ v2/<镜像repository>/tags/list

二,推送镜像到私有库
如果推送已有的镜像必须先打tag ,

注意:自定义repository 不能有大写字母!!!

docker tag <Image ID 或者repository:tag> 私有仓库IP:端口/<自定义repository>:<自定tag>

例:docker tag registry:latest 192.168.120.107:5000/my-registry:1.0

如果是想将某个容器保存为镜像并推送的话,则需要在commit的时候将私有库的ip和端口放到repository中

docker commit <容器ID或者容器名> <新repository>:<新TAG>

例: docker commit myregistry  192.168.120.107:5000/my-registry:1.0

执行完tag 命令或者 commit 命令后,我们执行docker images 可以发现,多出了一条repository 为 192.168.120.107:5000/my-registry , TAG 为 1.0 的镜像

然后将这个镜像推送到私有库
docker push 192.168.120.107:5000/my-registry:1.0

执行命令报错:
在这里插入图片描述
这个问题可能是由于客户端采用https,docker registry未采用https服务所致。
第一种处理方式是把客户端对地址“192.168.120.107:5000”的请求改为http。
步骤如下:

在客户端服务器的”/etc/docker/“目录下,创建”daemon.json“文件。在文件中写入:

{ "insecure-registries":["192.168.120.107:5000"] }

保存退出后,重启docker,再push 就可以成功了。

第二种方法在私有库所在的服务器 安装 nginx 和ssl并进行配置,使私有库支持https的访问,详细步骤自行百度。

三.从私有库拉取镜像

docker pull <私有库ip>:<端口>/ < 镜像repository> :<镜像tag>

例:docker pull 192.168.120.107:5000/my-registry:1.0

四.从私有库删除镜像
私有库默认是不支持删除镜像的,需要修改config.yml配置文件,在storage节点下加入 delete: enable: true ,然后重启私有库。
在这里插入图片描述
docker 提供的镜像删除api为:

DELETE ip:端口/v2/<repository>/manifests/<reference>

repository 为镜像的repository
reference 为镜像push成功后生成的 digest:sha256 值

获取 digest :

curl --header “Accept: application/vnd.docker.distributton.manifest.v2+json” -I -XGET <私有库ip>:端口号/v2/<镜像repository>/manifests/<镜像tag>
注意:
–header “Accept: application/vnd.docker.distributton.manifest.v2+json” 这个header 是必须要加的,不加的话,获取的digest是错误的!!

例:curl --header “Accept: application/vnd.docker.distributton.manifest.v2+json” -I -XGET 192.168.120.107:5000/v2/my-registry/manifests/1.0
在这里插入图片描述
删除镜像:
例:curl -I -X DELETE http://192.168.120.107:5000/v2/my-repository/manifests/sha256:4d523adb3c653bab7dfd0326081860b3cba24dc393f69d6731daa513c435ec0c

删除后我们查看下私有库

curl 192.168.120.107:5000/ v2/my-repository/tags/list

就会发现刚删除的那个tag不见了。但是这只是删除了元数据,层数据并没有被删除。
我们还需要运行docker 提供的垃圾回收命令。

垃圾回收

我们需要登录 私有库所在的服务器,然后执行命令:

docker exec -it <私有库的容器ID或者容器名> sh -c ' registry garbage-collect /etc/docker/registry/config.yml'

当然,也可以进入到私有库的容器中,再执行:

registry garbage-collect /etc/docker/registry/config.yml

这里我写了一个简单的删除镜像的sh脚本,内容如下:

#!/bin/bash

registryUrl='http://120.78.215.177:8161'
registryContainerName='registry'

if [ $1 == 'sr' ]; then

echo $registryUrl/v2/_catalog

curl $registryUrl/v2/_catalog

exit 0

fi

if [ $1 == 'st' ]; then

if [ ! $2 ]; then

echo "please input image repositry"

exit 2

fi

echo $registryUrl/v2/$2/tags/list

curl $registryUrl/v2/$2/tags/list

exit 0

fi


if [ ! $1 ]; then

echo "please input image repositry"

exit 2

fi

if [ ! $2 ]; then

echo "please input image tag "

exit 2

fi

#获取digest, --header “Accept: application/vnd.docker.distribution.manifest.v2+json” 这一段必须要,不然拿到的是个错误的digest
digest=`curl --header "Accept: application/vnd.docker.distribution.manifest.v2+json" -I -X GET $registryUrl/v2/$1/manifests/$2 | awk '($1=="Docker-Content-Digest:") {print $2}'`

# digest=`cat /hs/$1-version.txt | awk -v keyword=$2: '($1==keyword) {print $3}'`

#将拿到的digest进行处理,删除其中的/r ,否则 curl 命令会报错 curl: (3) Illegal characters found in URL
digest=${digest%$'\r'}

echo $digest

if [ ! $digest ]; then

echo 'no such version :' $2

exit 0

fi

echo $registryUrl/v2/$1/manifests/$digest

curl -I -X DELETE $registryUrl/v2/$1/manifests/$digest

docker exec -it $registryContainerName sh -c ' registry garbage-collect /etc/docker/registry/config.yml'

修改下 registryUrl(私有库ip和端口)和registryContainName(私有库容器ID或者容器名),然后将脚本放到私有库所在的服务器,便可以执行 脚本,传入需要删除的镜像 的 repository 和 tag 删除镜像了,同时还可以 通过传入 sr 或者 st + repository 进行镜像或者tag的查询。

sh 脚本名 <镜像repository> <镜像tag> 		//删除镜像
sh 脚本名  sr  							//查询所有repository
sh 脚本名 st <.镜像repository>     	    // 查询某镜像的tags 

猜你喜欢

转载自blog.csdn.net/Fickle_actor/article/details/88688793