搭建 Docker 私有镜像仓库
我们获取镜像,绝大多数情况下,从 Docker 官方仓库或者知名第三方仓库(如阿里云)中获取,但是对于公司内基于自身的业务生成的 Docker 镜像,很有可能涉及到商业利益,肯定不能对外公开,因此需要存放在公司的 Docker 私有镜像仓库中。
有关 Docker 的私有仓库的搭建过程,也非常简单,一般是获取和运行 Docker 官方提供的 Registry 镜像来实现。但是官网没有提供图形化界面,第三方提供了图形化界面 docker-registry-ui 镜像可以使用。本篇博客就展示带有图形化界面的 Docker 私有镜像仓库搭建过程。
DockerRegistry 的官网地址为:https://hub-stage.docker.com/_/registry
一、配置 Docker 信任地址
本篇博客基于之前已经安装好 Docker 的虚拟机进行演示,虚拟机的 ip 地址是:192.168.216.128
使用命令 vim /etc/docker/daemon.json
编辑 docker 服务配置文件,内容如下:
{
//这个是之前添加的 docker 阿里云仓库地址(这里隐藏了我个人账号登录阿里云后看到的仓库地址)
"registry-mirrors": ["https://xxxxxxxxxx.mirror.aliyuncs.com"],
//这个新增加的 docker 私有镜像仓库 web 页面的地址(这里假设 web 使用的是 8050 端口)
"insecure-registries":["http://192.168.216.128:8050"]
}
以上内容新增加了即将要搭建的 Docker 私有镜像仓库的 web 图形化界面访问的地址和端口。
添加完成之后,需重新加载 daemon 服务以及重启 docker 服务:
# 重新加载 daemon
systemctl daemon-reload
# 重启 docker
systemctl restart docker
二、搭建私有镜像仓库
我个人喜欢把软件安装在 /app 目录中,因此我先在 app 目录下创建一个目录:mkdir /app/registry-ui
然后进入目录:cd /app/registry-ui/
,然后创建并编辑 docker-compose.yml 文件:vim docker-compose.yml
version: '3.2'
services:
registry:
container_name: registry
restart: always
image: registry
volumes:
- ./registry-data:/var/lib/registry
ports:
- 7050:5000
networks:
- reg_net
registry-ui:
container_name: registry-ui
restart: always
image: joxit/docker-registry-ui:1.5-static
ports:
- 8050:80
networks:
- reg_net
environment:
- REGISTRY_TITLE=乔豆豆的私有仓库
- REGISTRY_URL=http://registry:5000
- CATALOG_ELEMENTS_LIMIT="1000"
depends_on:
- registry
networks:
reg_net:
driver: bridge
对于 docker-compose 程序说,docker-compose.yml 就是它的配置文件,不要更改配置文件的名字。
当前我们已经进入了 /app/registry-ui/ 目录中,在该目录中指定 docker-compose 命令后,就会读取当前目录下的 docker-compose.yml 配置文件,去拉去两个镜像:registry 和 joxit/docker-registry-ui:1.5-static ,然后运行这两个镜像。其中 joxit/docker-registry-ui:1.5-static 镜像配置了 depends_on 为 registry ,因此 joxit/docker-registry-ui:1.5-static 镜像会在 registry 镜像运行后再运行。
对于 docker-compose 编排的多个容器,如果其内部需要互相访问的话,则需要指定服务名称,比如这里的 joxit/docker-registry-ui:1.5-static 镜像启动后的容器需要访问 registry 镜像运行的容器,因为 registry 镜像运行的容器的服务名称是 registry ,内部启动的端口是 5000 ,因此 joxit/docker-registry-ui:1.5-static 启动的容器,可以通过 http://registry:5000
访问 registry 启动的容器。
在 registry 镜像下配置了数据卷的映射:./registry-data:/var/lib/registry
,因为我们运行 docker-compose 命令是在 /app/registry-ui/ 目录下运行,因此后续我们上传的私有 Docker 镜像,就会存放在 /app/registry-ui/registry-data 目录中。
最后,让我们在 /app/registry-ui/ 下运行 docker-compose 命令吧:docker-compose up -d
最后通过 docker ps -a
查看启动的两个容器:
然后我们就可以打开浏览器输入 http://192.168.216.128:8050
访问搭建好的 docker 私有镜像仓库页面:
三、向私有仓库上传镜像
使用 docker images 命令查看本地系统中的镜像列表:
我们就以之前自己通过 dockerfile 制作的 fileupdown 镜像为例,介绍如何将其上传到私有镜像仓库中。
要想将自己本地机器上的 Docker 镜像推送到刚才搭建的 Docker 私有镜像仓库中,首先需要重新指定 tag 标签。
比如运行命令:docker tag fileupdown:1.0 192.168.216.128:8050/fileupdown:v1
,可以发现新的 tag 标签必须包含有私有仓库的 web 页面访问地址,这里将版本号修改成了 v1 进行区别。
使用 docker images
重新查看镜像列表,能够发现打了新 tag 标签的镜像,并且其与原镜像具有相同的 image id
执行命令推送镜像到私有仓库:docker push 192.168.216.128:8050/fileupdown:v1
刷新私有镜像仓库的网址:http://192.168.216.128:8050
就能展示出我们上传的镜像:
点击 fileupdown 可以看到该镜像下的版本列表,当前只有一个版本 v1 ,所以只有一条记录:
四、从私有仓库下载镜像
使用 docker images 命令查看本地系统中的镜像列表:
为了方便识别和区分从私有仓库中下载的镜像,我们先将本地中两个 fileupdown 镜像删除掉,由于两个镜像的 image id 相同,因此只能通过镜像名称和 tag 的组合来删除这两个镜像,运行以下命令:
docker rmi fileupdown:1.0 192.168.216.128:8050/fileupdown:v1
然后执行以下命令从私有仓库中下载镜像:
docker pull 192.168.216.128:8050/fileupdown:v1
五、删除私有仓库中的镜像
默认情况下,不提供删除私有仓库镜像的功能,web 图形化界面中也没有提供,如果想要删除的话,需要进行以下操作。
查看当前运行的容器,找到 registry 容器的 id,执行命令 docker ps -a
查看到了 registry 的容器 id 为:3550836066ed ,然后执行以下命令进入容器中:
docker exec -it 3550836066ed sh
然后编辑文件:vi /etc/docker/registry/config.yml
version: 0.1
log:
fields:
service: registry
storage:
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /var/lib/registry
## 增加 delete 下的 enabled 配置,启用删除镜像功能
delete:
enabled: true
http:
addr: :5000
headers:
X-Content-Type-Options: [nosniff]
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
修改完成保存后,退出容器,重启 registry 的容器:docker restart 3550836066ed
在本篇博客上面【搭建私有仓库】中有关 docker-compose.yml 配置文件中,我们对于 registry 服务暴露出来的端口是 7050,之所以暴露出这个端口,目的也是为了通过命令直接操作私有镜像仓库,我们首先执行以下命令获取要删除的镜像的 sh256 值:
# 访问地址的格式是:http://私有仓库地址:端口号/v2/镜像名称/manifests/镜像的tag
curl -I -XGET --header "Accept:application/vnd.docker.distribution.manifest.v2+json" \
http://192.168.216.128:7050/v2/fileupdown/manifests/v1
获取的结果为:sha256:6f6351900d2ed40826d85dcbbfd6cf3b12b36d42026e9c06f10f86b51096685f
当然最简单的获取方式就是,直接从 web 图形化界面中进行复制:
然后就可以删除镜像了,如果采用图形化界面删除的话,可以采用 Postman 发送 delete 请求:
http://192.168.216.128:7050/v2/fileupdown/manifests/sha256:6f6351900d2ed40826d85dcbbfd6cf3b12b36d42026e9c06f10f86b51096685f
当然也可以采用 linux 命令,如下所示:
# 反斜杠( \ )表示换行,由于命令太长,不方便查看,所以进行了换行
curl -I -X DELETE \
http://192.168.120.107:5000/v2/fileupdown/manifests/\
sha256:4d523adb3c653bab7dfd0326081860b3cba24dc393f69d6731daa513c435ec0c
以上操作完成后,虽然在 web 图形化界面中看不到了,实际上被删除镜像对于空间的占用并没有释放,因此还需要进入容器中执行命令进行空间垃圾回收:
docker exec -it 3550836066ed sh -c ' registry garbage-collect /etc/docker/registry/config.yml'
最终 web 界面中展示的效果如下所示:
如果你想彻底删除的话,就直接进入数据卷映射的目录中进行删除镜像的名称。
例如:本篇博客映射到本地的数据卷目录为 /app/registry-ui/registry-data ,执行以下命令进入镜像存放的目录:
# 进入存放镜像的目录中
cd /app/registry-ui/registry-data/docker/registry/v2/repositories/
然后执行 ll
查看上传到私有仓库的镜像列表,我们发现只有一个:fileupdown
然后执行删除命令,删除 fileupdown 目录即可:rm -rf fileupdown/
最后再执行命令,进行一下空间的垃圾回收即可:
docker exec -it 3550836066ed sh -c ' registry garbage-collect /etc/docker/registry/config.yml'
最后强烈建议重启一下私有镜像仓库的容器服务:docker restart 3550836066ed
然后我们再看一下 web 图形化界面,发现就比较干净了: