Docker 官方提供了一个搭建私有仓库的镜像 registry ,只需把镜像下载下来,运行容器并暴露5000端口,就可以使用了
docker pull registry docker run -it -d -v /opt/registory:/var/lib/registry -p 5000:5000 --restart=always --name registry registry:latest
参数说明
-it:在容器中打开一个伪终端进行交互操作
-d:容器在后台运行
-v:把宿主机的/opt/registory目录绑定 到 容器/var/lib/registry目录(这个目录是registry容器中存放镜像文件的目录),来实现数据的持久化
-p:映射端口;访问宿主机的5000端口就访问到registry容器的服务了
--restart=always:这是重启的策略,假如这个容器异常退出会自动重启容器
--name registry:创建容器命名为registry,你可以随便命名
registry:latest:这个是刚才pull下来的镜像
Registry服务默认会将上传的镜像保存在容器的/var/lib/registry,我们将主机的/opt/registry目录挂载到该目录,即可实现将镜像保存到主机的/opt/registry目录了
然后浏览器访问http://127.0.0.1:5000/v2,出现{}说明registry部署好了
也可以使用curl命令测试
curl http://127.0.0.1:5000/v2/_catalog 返回 {"repositories":[]}
接着我们试着推入一些镜像到私有仓库试试
docker pull nginx:latest #先拉取一个nginx镜像
然后改标签名,如果要推入私有仓库有一个改名规范,需要将私有仓库的地址192.168.122.59:5000/添加到标签前面,192.168.122.59是我本机IP,也是registry仓库的服务器IP
docker tag nginx:latest 192.168.122.59:5000/nginx:v1
nginx:latest这是刚才pull下来的镜像,192.168.122.59:5000/nginx:v1是修改后的标签
接着我们上传镜像到私有仓库
docker push 192.168.122.59:5000/nginx:v1 The push refers to repository [192.168.122.59:5000/nginx] Get https://192.168.122.59:5000/v2/: http: server gave HTTP response to HTTPS client
这类报错我们需要修改支持http协议
sudo vim /etc/docker/daemon.json { "registry-mirrors": [ "http://hub-mirror.c.163.com" ], "insecure-registries": [ "192.168.122.59:5000" ] }
主要是添加insecure-registries这一段,保存后,重启下docker
sudo systemctl restart docker
然后再次推送镜像到私有仓库
docker push 192.168.122.59:5000/nginx:v1
这次就没有问题了
同时我们也可以试试从私有仓库拉取镜像到本地
docker pull 192.168.122.59:5000/nginx:v1
registry一些常用的API
发起请求格式
GET /v2/<name>/tags/list #查询镜像是否存在以及标签列表 GET /v2/_catalog #列出所有镜像 GET /v2/<name>/manifests/<reference> #其中<name>为镜像名,<reference>可以是"tag"或"digest" DELETE /v2/<name>/manifests/<reference> #<name>为镜像名,<reference>只能是"digest" sudo docker push docker.yun.ccb.com/<name>:<tag> #查看本地镜像的digest方法 docker images --digests #此命令也能获取digest
然后下面提供了一个registry操作类
#!/usr/bin/python3 #coding:utf-8 import requests class Registory_api(): def __init__(self, host, port): self.host = host self.port = port self.headers = {"Content-Type": "application/json"} def get_all_images(self): url = "http://{}:{}/v2/_catalog".format(self.host, self.port) try: r = requests.get(url, headers=self.headers) except Exception as e: raise IOError(e) return r def get_tags(self, name): url = "http://{}:{}/v2/{}/tags/list".format(self.host, self.port, name) try: r = requests.get(url, headers=self.headers) except Exception as e: raise IOError(e) return r def get_manifests(self, name, reference): #reference可以是镜像的tag或者digest url = "http://{}:{}/v2/{}/manifests/{}".format(self.host, self.port, name, reference) try: r = requests.get(url, headers=self.headers) except Exception as e: raise IOError(e) return r def reomve_images(self, name, digest): url = "http://{}:{}/v2/{}/manifests/{}".format(self.host, self.port, name, digest) try: r = requests.get(url, headers=self.headers) except Exception as e: raise IOError(e) return r if __name__ == "__main__": host = "192.168.122.59" port = 5000 reg = Registory_api(host, port) r = reg.get_all_images() print(r.json())
执行打印结果