1、什么是Docker仓库
仓库是集中存放镜像文件的场所。有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
仓库分为公开仓库(Public)和私有仓库(Private)两种形式。最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。 国内的公开仓库包括 Docker Pool等,可以提供大陆用户更稳定快速的访问。
当然,用户也可以在本地网络内创建一个私有仓库。当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。
2、私有仓库(registry)的优势
- 有时候使用Docker Hub这样的公共仓库可能不方便,这种情况下用户可以使用registry创建一个本地仓库供私人使用,这点跟Maven的管理类似。
- 使用私有仓库有许多优点:
1)节省网络带宽,针对于每个镜像不用每个人都去中央仓库上面去下载,只需要从私有仓库中下载即可;
2)提供镜像资源利用,针对于公司内部使用的镜像,推送到本地的私有仓库中,以供公司内部相关人员使用。 - 目前Docker Registry已经升级到了v2,最新版的Docker已不再支持v1。Registry v2使用Go语言编写,在性能和安全性上做了很多优化,重新设计了镜像的存储格式。如果需要安装registry v2,只需下载registry:2.2即可。
- Docker官方提供的工具docker-registry可以用于构建私有的镜像仓库。
3、创建私有仓库
[root@server1 ~]# docker load -i registry2.tar
d9ff549177a9: Loading layer 4.671MB/4.671MB
f641ef7a37ad: Loading layer 1.587MB/1.587MB
d5974ddb5a45: Loading layer 20.08MB/20.08MB
5bbc5831d696: Loading layer 3.584kB/3.584kB
73d61bf022fd: Loading layer 2.048kB/2.048kB
Loaded image: registry:2
[root@server1 ~]# docker history registry:2
[root@server1 ~]# docker run -d --name registry -p 5000:5000 -v /opt/registry:/var/lib/registry registry:2 ##重命名并上传本地镜像到仓库
WARNING: IPv4 forwarding is disabled. Networking will not work.
2ed552e2044166c2811efed12ee3d8aeb3900b43d739f43763f2ba0848bfee7c
[root@server1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2ed552e20441 registry:2 "/entrypoint.sh /etc…" 20 seconds ago Up 20 seconds 0.0.0.0:5000->5000/tcp registry
[root@server1 ~]# netstat -tnlp
[root@server1 ~]# docker tag nginx:latest localhost:5000/nginx
[root@server1 ~]# docker images localhost:5000/nginx
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost:5000/nginx latest 62c261073ecf 4 days ago 109MB
[root@server1 ~]# docker push localhost:5000/nginx ##拉取镜像
The push refers to repository [localhost:5000/nginx]
ea06a73e56fc: Pushed
22c458a3ff08: Pushed
6270adb5794c: Pushed
latest: digest: sha256:8c3cdb5acd050a5a46be0bb5637e23d192f4ef010b4fb6c5af40e45c5b7a0a71 size: 948
[root@server1 ~]# cd /opt/registry/
[root@server1 registry]# tree docker/
docker/
└── registry
└── v2
├── blobs
│ └── sha256
│ ├── 62
│ │ └── 62c261073ecffe22a28f2ba67760a9320bc4bfe8136a83ba9b579983346564be
│ │ └── data
│ ├── 74
│ │ └── 743f2d6c1f65c793009f30acb07845ba2ef968192732afdab2ecf9a475515393
│ │ └── data
│ ├── 8c
│ │ └── 8c3cdb5acd050a5a46be0bb5637e23d192f4ef010b4fb6c5af40e45c5b7a0a71
│ │ └── data
│ ├── d4
│ │ └── d4da6ff1b55515ba872e954c6ffeb6dcf53221247a6c6f2a6078af4d9f4dd51f
│ │ └── data
│ └── d6
│ └── d6c2f01b1daeeaf17e9da575b0f1b2094eadab9b923360b86ea4b7f1932a0166
│ └── data
└── repositories
└── nginx
├── _layers
│ └── sha256
│ ├── 62c261073ecffe22a28f2ba67760a9320bc4bfe8136a83ba9b579983346564be
│ │ └── link
│ ├── 743f2d6c1f65c793009f30acb07845ba2ef968192732afdab2ecf9a475515393
│ │ └── link
│ ├── d4da6ff1b55515ba872e954c6ffeb6dcf53221247a6c6f2a6078af4d9f4dd51f
│ │ └── link
│ └── d6c2f01b1daeeaf17e9da575b0f1b2094eadab9b923360b86ea4b7f1932a0166
│ └── link
├── _manifests
│ ├── revisions
│ │ └── sha256
│ │ └── 8c3cdb5acd050a5a46be0bb5637e23d192f4ef010b4fb6c5af40e45c5b7a0a71
│ │ └── link
│ └── tags
│ └── latest
│ ├── current
│ │ └── link
│ └── index
│ └── sha256
│ └── 8c3cdb5acd050a5a46be0bb5637e23d192f4ef010b4fb6c5af40e45c5b7a0a71
│ └── link
└── _uploads
33 directories, 12 files
[root@server1 registry]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2ed552e20441 registry:2 "/entrypoint.sh /etc…" 15 minutes ago Up 15 minutes 0.0.0.0:5000->5000/tcp registry
[root@server1 registry]# curl http://localhost:5000/v2/_catalog
{"repositories":["nginx"]}
[root@server1 registry]# docker pull localhost:5000/nginx
Using default tag: latest
latest: Pulling from nginx
Digest: sha256:8c3cdb5acd050a5a46be0bb5637e23d192f4ef010b4fb6c5af40e45c5b7a0a71
Status: Image is up to date for localhost:5000/nginx:latest
[root@server1 registry]# docker rmi localhost:5000/nginx:latest
Untagged: localhost:5000/nginx:latest
Untagged: localhost:5000/nginx@sha256:8c3cdb5acd050a5a46be0bb5637e23d192f4ef010b4fb6c5af40e45c5b7a0a71
[root@server1 registry]# docker images nginx
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 62c261073ecf 4 days ago 109MB
3.给私有库添加证书
仓库所有人都可以访问,这样不安全,所以可以为仓库添加证书增加安全性
1.创建服务端key以及证书
[root@server1 registry]# cd /tmp/docker/
[root@server1 docker]# ls
Dockerfile yum.repo
[root@server1 docker]# mkdir -p certs
[root@server1 docker]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/westos.org.key -x509 -days 365 -out cert/westos.org.crt
2.添加本地解析
[root@server1 docker]# vim /etc/hosts
4 172.25.80.1 server1 westos.org
[root@server1 docker]# ping westos.org
PING server1 (172.25.80.1) 56(84) bytes of data.
64 bytes from server1 (172.25.80.1): icmp_seq=1 ttl=64 time=0.030 ms
3.创建仓库
[root@server1 docker]# netstat -antlp | grep :443
[root@server1 docker]# docker rm -f registry
[root@server1 docker]# docker run -d \
> --restart=always \
> --name registry \
> -v /tmp/docker/certs:/certs \
> -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
> -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/westos.org.crt \
> -e REGISTRY_HTTP_TLS_KEY=/certs/westos.org.key \
> -p 443:443 \
> -v /opt/registry:/var/lib/registry \
> registry:2
[root@server1 docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7bf134404d6f registry:2 "/entrypoint.sh /etc…" 16 seconds ago Up 16 seconds 0.0.0.0:443->443/tcp, 5000/tcp registry
[root@server1 docker]# netstat -antlp | grep :443
tcp6 0 0 :::443 :::* LISTEN 5852/docker-proxy
参数说明:
-d:后台静默运行容器。
–restart:设置容器重启策略。
–name:命名容器。
-v:挂载信息
-e REGISTRY_HTTP_ADDR:设置仓库主机地址格式。
-e REGISTRY_HTTP_TLS_CERTIFICATE:设置环境变量告诉容器证书的位置。
-e REGISTRY_HTTP_TLS_KEY:设置环境变量告诉容器私钥的位置。
-p:将容器的 443 端口映射到Host主机的 443 端口
注意!
如果此时出现报错:
必须删除错误的容器,修改配置文件
[root@server1 certs]# vim /usr/lib/sysctl.d/00-system.conf
10 net.ipv4.ip_forward=1 ##添加此代码
重启网络
[root@server1 certs]# systemctl restart network
重新创建容器!!!!
4.创建证书存放目录,并复制证书
[root@server1 docker]# cd /etc/docker/
[root@server1 docker]# ls
daemon.json key.json
[root@server1 docker]# mkdir certs.d
[root@server1 docker]# cd certs.d/
[root@server1 certs.d]# ls
[root@server1 certs.d]# mkdir westos.org
[root@server1 certs.d]# cd westos.org/
[root@server1 westos.org]# cp /tmp/docker/certs/westos.org.crt ca.crt
[root@server1 westos.org]# ls
ca.crt
5.导入一个镜像并上传到私有仓库
[root@server1 ~]# docker load -i game2048.tar
[root@server1 ~]# docker tag game2048:latest westos.org/game2048
[root@server1 ~]# docker push westos.org/game2048
1.在server2上安装docker并启动,添加解析
[root@server2 docker]# ls
container-selinux-2.21-1.el7.noarch.rpm
docker-ce-18.06.1.ce-3.el7.x86_64.rpm
libsemanage-2.5-8.el7.x86_64.rpm
libsemanage-python-2.5-8.el7.x86_64.rpm
pigz-2.3.4-1.el7.x86_64.rpm
policycoreutils-2.5-17.1.el7.x86_64.rpm
policycoreutils-python-2.5-17.1.el7.x86_64.rpm
[root@server2 docker]# yum install -y *
[root@server2 docker]# systemctl start docker
[root@server2 certs.d]# vim /etc/hosts
4 172.25.80.1 server1 westos.org
2.创建同样的证书目录,并将服务端证书传到此位置
[root@server2 docker]# cd /etc/docker/
[root@server2 docker]# ls
key.json
[root@server2 docker]# mkdir -p certs.d/westos.org
[root@server1 westos.org]# scp ca.crt server2:/etc/docker/certs.d/westos.org/
root@server2's password:
ca.crt 100% 2094 2.0KB/s 00:00
[root@server2 westos.org]# ls
ca.crt
[root@server2 westos.org]# pwd
/etc/docker/certs.d/westos.org
3.下拉镜像
[root@server2 westos.org]# docker pull westos.org/game2048
Using default tag: latest
latest: Pulling from game2048
534e72e7cedc: Pull complete
f62e2f6dfeef: Pull complete
fe7db6293242: Pull complete
3f120f6a2bf8: Pull complete
4ba4e6930ea5: Pull complete
Digest: sha256:8a34fb9cb168c420604b6e5d32ca6d412cb0d533a826b313b190535c03fe9390
Status: Downloaded newer image for westos.org/game2048:latest
成功下拉,如果之前的警告不处理,这一步就会报错
4、配置用户权限 ,为证书加密
1.设置用户密码并查看
[root@server1 docker]# cd /tmp/docker/
[root@server1 docker]# mkdir auth
[root@server1 docker]# docker run --rm --entrypoint htpasswd registry:2 -Bbn rht westos > auth/htpasswd
[root@server1 docker]# cat auth/htpasswd
rht:$2y$05$mSwOoVx0S1peyoMjR3Tmnu8eyIehgqRTk9HfoS/bWUy/6lbxpgZ.2
添加用户
[root@server1 docker]# docker run --rm --entrypoint htpasswd registry:2 -Bbn user1 redhat >> auth/htpasswd ##改为追加
[root@server1 docker]# cat auth/htpasswd
rht:$2y$05$mSwOoVx0S1peyoMjR3Tmnu8eyIehgqRTk9HfoS/bWUy/6lbxpgZ.2
user1:$2y$05$7bE9wUOykNDdV/TRENPYke2Z826mzBXKALyKGsF0yRtKFAfIg.Pz6
2.创建仓库
[root@server1 auth]# docker rm -f registry
registry
[root@server1 auth]# docker run -d --restart=always --name registry -v /tmp/docker/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/westos.crt -e REGISTRY_HTTP_TLS_KEY=/certs/westos.org.key -p 443:443 -v /opt/registry:/var/lib/registry -v /tmp/docker/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry:2
4c234f8790540ba6320e28aa96db4e89693ee3f65b7e1b4ced1d6ee5ccbd5704wd registry:2
此时上传会显示没有基础认证
[root@server1 auth]# docker push westos.org/nginx
The push refers to repository [westos.org/nginx]
Get https://westos.org/v2/: dial tcp 172.25.80.1:443: connect: connection refused
3.输入用户名和密码登陆库
[root@server1 docker]# docker login westos.org
Username: rht
Password:
Login Succeeded
4.在文件config.json 中可以看到记录的认证
[root@server1 .docker]# cat config.json
{
"auths": {
"westos.org": {
"auth": "cmh0OnJlZGhhdA=="
}
},
"HttpHeaders": {
"User-Agent": "Docker-Client/18.06.1-ce (linux)"
}
5.此时再次上传就成功了
[root@server1 ~]# docker push westos.org/ubuntu
The push refers to repository [westos.org/ubuntu]
5f70bf18a086: Pushed
11083b444c90: Pushed
9468150a390c: Pushed
56abdd66ba31: Pushed
latest: digest: sha256:4e709bde11754c2a27ed6e9b9ba55569647f83903f85cd8107e36162c5579984 size: 1151
当容器出现端口没有映射、容器无法运行等问题时,可以使用
docker logs +容器名
查看日志,解决90%的问题!