1、使用registry镜像创建私有仓库

 docker run -d -p 5000:5000   --restart=always --name registry registry:2

这条命令将自动下载并启动一个registry容器,创建本地的私有仓库

--restart=always:表示当docker服务重启时,registry也会自动启动

记得修改/etc/docker/daemon.json 配置文件,将私有仓库地址写入到配置文件中

{
  "registry-mirrors": ["https://1a4frcsa.mirror.aliyuncs.com"],
  "insecure-registries": ["http://172.16.2.14:5000"]
}



2、 从配置的公共registry地址下载ubuntu:16.04 镜像到本地

docker pull ubuntu:16.04



3、将镜像重新打一个tag

# docker tag ubuntu:16.04 localhost:5000/my-ubuntu
[root@OPS01-LINTEST02 ~]# docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
localhost:5000/my-ubuntu   latest              5e8b97a2a082        7 days ago          114MB
ubuntu                     16.04               5e8b97a2a082        7 days ago          114MB


4、将镜像push到自己搭建的私有仓库中

# docker push localhost:5000/my-ubuntu
The push refers to repository [localhost:5000/my-ubuntu]
2de391e51d73: Pushed 
d73dd9e65295: Pushed 
686245e78935: Pushed 
d7ff1dc646ba: Pushed 
644879075e24: Pushed 
latest: digest: sha256:689aa49d87d325f951941d789f7f7c8fae3394490cbcf084144caddba9c1be12 size: 1357


5、删除本地缓存的ubuntu:16.04localhost:5000/my-ubuntu 镜像,这不会删除私有仓库中的镜像。然后测试从私有仓库pull镜像。

# docker image remove ubuntu:16.04
# docker image remove localhost:5000/my-ubuntu


6、从本地私有仓库下载镜像

# docker pull localhost:5000/my-ubuntu
Using default tag: latest
latest: Pulling from my-ubuntu
b234f539f7a1: Pull complete 
55172d420b43: Pull complete 
5ba5bbeb6b91: Pull complete 
43ae2841ad7a: Pull complete 
f6c9c6de4190: Pull complete 
Digest: sha256:689aa49d87d325f951941d789f7f7c8fae3394490cbcf084144caddba9c1be12
Status: Downloaded newer image for localhost:5000/my-ubuntu:latest


7、stop 本地registry

# docker container stop registry

停止私有仓库的容器

docker container stop registry && docker container rm -v registry

停止容器并删除


8、自定义registry的端口,当5000端口被占用时,可以使用其他端口替代

# docker run -d -p 5001:5000 --name registry-test registry:2
29f769711de0c981abf7b2dff7e79297338e860abf01ec330d09036da8045a42
[root@OPS01-LINTEST02 ~]# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      506/rpcbind         
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      73954/sshd          
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1197/master         
tcp        0      0 0.0.0.0:10050           0.0.0.0:*               LISTEN      960/zabbix_agentd   
tcp6       0      0 :::5001                 :::*                    LISTEN      111483/docker-proxy 
tcp6       0      0 :::111                  :::*                    LISTEN      506/rpcbind         
tcp6       0      0 :::21                   :::*                    LISTEN      953/vsftpd          
tcp6       0      0 :::22                   :::*                    LISTEN      73954/sshd          
tcp6       0      0 :::10050                :::*                    LISTEN      960/zabbix_agentd

-p后面第一个5001是docker服务器对外的端口,第二个5000是容器的端口。


9、如果想修改容器内的registry服务器监听的端口,可以使用下面的命令

docker run -d -e REGISTRY_HTTP_ADDR=0.0.0.0:5001 -p 5001:5001 --name registry-test registry:2


10、将自定义仓库中的镜像存储到主机上

默认情况下,我们上传到私有仓库中的镜像存储在容器的/var/lib/registry路径下,如果想将镜像保存到本地,可以在容器启动时,创建一个卷

docker run -d \
  -p 5000:5000 \
  --restart=always \
  --name registry \
  -v /mnt/registry:/var/lib/registry \
  registry:2

这样重新上传的镜像也会保存在本地的/mnt/registry下

通过API来查询本地仓库镜像信息

# curl http://172.16.2.14:5000/v2/_catalog
{"repositories":["my-ubuntu"]}


#  curl http://172.16.2.14:5000/v2/my-ubuntu/tags/list
{"name":"my-ubuntu","tags":["latest"]}

API官方介绍参考:https://docs.docker.com/registry/spec/api/#deleting-a-layer



搭建私有仓库,可以参考官方文档:https://docs.docker.com/registry/deploying/



删除私有仓库中的镜像方法一:

1、进入到容器中,修改配置文件

ersion: 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


2、

$ curl -v --silent -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X GET http://172.16.33.1:5000/v2/mytest/manifests/latest 2>&1 | grep Docker-Content-Digest | awk '{print ($3)}'
# 删除tag
$ curl -v --silent -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X DELETE http://172.16.33.1:5000/v2/mytest/manifests/sha256:1f57b0eddcb21cb798e4841c8e5634a2b0269f4500c750d503a2e54dd91fe0e4
# 上一步删除后需要到registry容器中回收
$ docker exec -it registry_container_id sh
$ registry garbage-collect /etc/docker/registry/config.yml


删除镜像方法二

使用github上别人所写的工具,地址https://github.com/burnettk/delete-docker-registry-image


1、安装脚本,会将脚本下载到本地/usr/local/bin/delete_docker_registry_image

$ 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


2、给脚本添加执行权限

$ sudo chmod +x /usr/local/bin/delete_docker_registry_image


3、通过环境变量设置镜像保存在本地的路径

export REGISTRY_DATA_DIR=/opt/registry_data/docker/registry/v2

我本地测试环境的路径为

export REGISTRY_DATA_DIR=/mnt/registry/docker/registry/v2


4、测试执行删除一个repo,查看哪些目录需要删除

$ delete_docker_registry_image --image testrepo/awesomeimage --dry-run

这里testrepo/aweomeimage  就是你需要删除的,保存在本地的某个repo下的某个镜像,例如我上面上传的my-ubuntu

改命令不会立即删除镜像,而是测试

# delete_docker_registry_image --image my-ubuntu --dry-run         
INFO     [2018-06-14 09:24:47,481]  DRY_RUN: would have deleted /mnt/registry/docker/registry/v2/blobs/sha256/43/43ae2841ad7a7fd1aeae30028105cac7f6ee0ec955e5229e52b3333fea3c17b5
INFO     [2018-06-14 09:24:47,481]  DRY_RUN: would have deleted /mnt/registry/docker/registry/v2/blobs/sha256/5e/5e8b97a2a0820b10338bd91674249a94679e4568fd1183ea46acff63b9883e9c
INFO     [2018-06-14 09:24:47,482]  DRY_RUN: would have deleted /mnt/registry/docker/registry/v2/blobs/sha256/68/689aa49d87d325f951941d789f7f7c8fae3394490cbcf084144caddba9c1be12
INFO     [2018-06-14 09:24:47,482]  DRY_RUN: would have deleted /mnt/registry/docker/registry/v2/blobs/sha256/55/55172d420b43cf03feeec11bcc917c7ddfc192036102e065ab57aa9abb95311e
INFO     [2018-06-14 09:24:47,482]  DRY_RUN: would have deleted /mnt/registry/docker/registry/v2/blobs/sha256/f6/f6c9c6de41905e9a66f2bc2c4a19858c8dc5b0a94f01e03eafc719afe25888aa
INFO     [2018-06-14 09:24:47,482]  DRY_RUN: would have deleted /mnt/registry/docker/registry/v2/blobs/sha256/5b/5ba5bbeb6b91e2676c98255c6babc66d7b05cac40185eeba4b3773199c701da0
INFO     [2018-06-14 09:24:47,482]  DRY_RUN: would have deleted /mnt/registry/docker/registry/v2/blobs/sha256/b2/b234f539f7a1d65eabae1617e63c81ac01768abffd48b5cbbf7166efca6a3429
INFO     [2018-06-14 09:24:47,482]  DRY_RUN: would have deleted /mnt/registry/docker/registry/v2/repositories/my-ubuntu

查看本地镜像是否还在

# curl http://172.16.2.14:5000/v2/_catalog
{"repositories":["my-ubuntu"]}

可以看到镜像还没有被删除


5、执行删除repo的操作(先停掉registry服务)

$ delete_docker_registry_image --image testrepo/awesomeimage

例如:我要删除上传的my-ubuntu镜像

# delete_docker_registry_image --image my-ubuntu
INFO     [2018-06-14 09:31:11,688]  Deleting /mnt/registry/docker/registry/v2/blobs/sha256/43/43ae2841ad7a7fd1aeae30028105cac7f6ee0ec955e5229e52b3333fea3c17b5
INFO     [2018-06-14 09:31:11,689]  Deleting /mnt/registry/docker/registry/v2/blobs/sha256/5e/5e8b97a2a0820b10338bd91674249a94679e4568fd1183ea46acff63b9883e9c
INFO     [2018-06-14 09:31:11,689]  Deleting /mnt/registry/docker/registry/v2/blobs/sha256/68/689aa49d87d325f951941d789f7f7c8fae3394490cbcf084144caddba9c1be12
INFO     [2018-06-14 09:31:11,689]  Deleting /mnt/registry/docker/registry/v2/blobs/sha256/55/55172d420b43cf03feeec11bcc917c7ddfc192036102e065ab57aa9abb95311e
INFO     [2018-06-14 09:31:11,689]  Deleting /mnt/registry/docker/registry/v2/blobs/sha256/f6/f6c9c6de41905e9a66f2bc2c4a19858c8dc5b0a94f01e03eafc719afe25888aa
INFO     [2018-06-14 09:31:11,690]  Deleting /mnt/registry/docker/registry/v2/blobs/sha256/5b/5ba5bbeb6b91e2676c98255c6babc66d7b05cac40185eeba4b3773199c701da0
INFO     [2018-06-14 09:31:11,690]  Deleting /mnt/registry/docker/registry/v2/blobs/sha256/b2/b234f539f7a1d65eabae1617e63c81ac01768abffd48b5cbbf7166efca6a3429
INFO     [2018-06-14 09:31:11,699]  Deleting /mnt/registry/docker/registry/v2/repositories/my-ubuntu

执行下面的命令,再次查看镜像是否存在

# curl http://172.16.2.14:5000/v2/_catalog      
{"repositories":[]}

可以看到my-ubuntu被删除了


6、删除某个tag

$ delete_docker_registry_image --image testrepo/awesomeimage:tag

测试:将从公共仓库pull下来的centos:7 镜像打两个tag,然后push到私有仓库

docker tag centos:7 localhost:5000/my-centos:7 
docker tag centos:7 localhost:5000/my-centos:latest

将镜像push到私有仓库

 docker push localhost:5000/my-centos:7
 curl http://172.16.2.14:5000/v2/my-centos/tags/list
{"name":"my-centos","tags":["7"]}


将my-centos:latest也push到本地私有仓库,会提示镜像已存在,这是因为这两个镜像完全相同,从镜像ID可以看出来

$ docker push localhost:5000/my-centos:latest
The push refers to repository [localhost:5000/my-centos]
bcc97fbfc9e1: Layer already exists 
latest: digest: sha256:eed5b251b615d1e70b10bcec578d64e8aa839d2785c2ffd5424e472818c42755 size: 529

##查看my-centos镜像的所有tag,可以看到有两个,分别是7和latest
[root@OPS01-LINTEST02 bin]# curl http://172.16.2.14:5000/v2/my-centos/tags/list                  
{"name":"my-centos","tags":["7","latest"]}


删除latest这个tag执行下面的命令

$ delete_docker_registry_image --image my-centos:latest
INFO     [2018-06-14 09:45:00,802]  Deleting /mnt/registry/docker/registry/v2/repositories/my-centos/_manifests/tags/latest

$ curl http://172.16.2.14:5000/v2/my-centos/tags/list  
{"name":"my-centos","tags":["7"]}


7、添加访问权限和用户认证

生产环境中,对私有仓库还需要进行访问代理,以及提供认证和用户管理

我们可以用nginx代理来实现访问控制和用户管理。

安装nginx

yum -y install nginx

注释掉/etc/nginx/nginx.conf中默认的index页面的配置

在/etc/nginx/conf.d中新建一个配置文件docker-registry.conf,内容如下:

upstream docker-registry {
    server localhost:5000;
}
server {
    listen 15000;
    server_name mydockerrepo.com;
    add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forward-Proto $scheme;
    proxy_read_timeout  600;
    client_max_body_size 0;
    chunked_transfer_encoding on;
   location / {

      auth_basic "Please Input usernme/password";
##    auth_basic_user_file /etc/nginx/conf.d/passwd.txt; 
## 可以写绝对路径,也可以写相对路径
      auth_basic_user_file conf.d/passwd.txt;
      proxy_pass http://docker-registry;
   }
}


生成账号密码配置文件

安装httpd,使用htpasswd命令创建

htpasswd -c /etc/nginx/conf.d/passwd.txt user1

# cat passwd.txt 
user1:$apr1$yyMVokyA$gM8n1QEvLF7AyYI1yTdSi/

输入两次密码即可,生成账户密码文件保存在passwd.txt中,通常将该文件隐藏。再次访问docker registry时,会要求输入账号密码

image.png