1.仓库分为公开仓库(Public)和私有仓库(Private)两种形式。最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。 国内的公开仓库包括 Docker Pool等,可以提供大陆用户更稳定快速的访问。
2.当然,用户也可以在本地网络内创建一个私有仓库。当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。
3.私有仓库的优势:
(1)有时候使用Docker Hub这样的公共仓库可能不方便,这种情况下用户可以使用registry创建一个本地仓库供私人使用,
(2)使用私有仓库可以节省网络带宽,针对于每个镜像不用每个人都去中央仓库上面去下载,只需要从私有仓库中下载即可。而且提供镜像资源利用,针对于公司内部使用的镜像,推送到本地的私有仓库中,以供公司内部相关人员使用。
(3)Docker官方提供的工具docker-registry可以用于构建私有的镜像仓库。
Docker仓库是用来包含镜像的位置,Dokcer提供一个注册服务器(Registry)来保存多个仓库,每个仓库又可以包含多个具备不同tag的镜像
Docker运行中使用的默认仓库是Docker Hub公共仓库,Docker hub是docker公司维护的公共仓库,用户可以免费使用,也可以购买私有仓库
1.首先在以下网址中注册一个帐号(注意:帐号名不要写成电话号码,这里鄙人就犯错了,所以以下所有看不清的皆为鄙人的电话号码)
https://cloud.docker.com/
2.在docker主机中登录帐号(此处需要联网,因为此处相当于登陆网页中的docker)
[root@server1 ~]# docker login
[root@server1 ~]# docker tag nginx:latest 1***5/nginx:vv1
[root@server1 ~]# docker images 1***5/nginx:vv1
4.在docker hub(网页中)新建一个公共仓库
6.在docker hub中查看,发现此时的tag中有刚上传的标签为vv1的镜像
7.从docker hub拉取镜像,会发现如果docker主机中有要拉取的镜像,那么会更新,如果没有,那么会拉取
[root@server1 ~]# docker pull 18909238335/nginx:vv1
docker主机中有镜像:
docker主机中没有镜像:
8.删除镜像(避免影响之后的实验)
[root@server1 ~]# docker rmi 18909238335/nginx:vv1
1.Docker Hub 虽然方便,但是还是有限制:
(1)需要internet连接,速度慢
(2)所有人都可以访问
(3)由于安全原因企业不允许将镜像放到外网
好消息是docker公司已经将registry开源,我们可以快速构建企业私有仓库
2.Registry工作原理
一次docker pull/push背后发生的事情
(1)index服务只要提供镜像索引以及用户认证的功能。当下载一个镜像的时候,首先会去index服务上做认证,然后查找镜像所在的registry的地址并放回给docker客户端,docker客户端再从registry下载镜像,在下载过程中 registry会去index校验客户端token的合法性,不同镜像可以保存在不同的registry服务上,其索引信息都放在index服务上。
(2)Docker Registry有三个角色,分别是index、registry和registry client。
(3)index负责并维护有关用户帐户、镜像的校验以及公共命名空间的信息。
(4)registry是镜像和图表的仓库,它不具有本地数据库以及不提供用户认证,通过Index Auth service的Token的方式进行认证。
(5)Registry Client:Docker充当registry客户端来维护推送和拉取,以及客户端的授权。
3.情景A:用户要获取并下载镜像。
情景A:具体工作流程如下:
4.情景B:用户要推送镜像到registry中
情景B:具体工作流程如下:
5.情景C:用户要从index或registry中删除镜像。
情景C:具体工作流程如下:
(一):搭建私有仓库
Docker官方已经把仓库封装成镜像,直接通过启动容器就可以部署完成仓库
1.查看registry镜像(官方打包的仓库)并进行拉取(也可以直接使用已经成功下载好的镜像),并查看镜像是否存在以及镜像的分层结构
[root@server1 ~]# docker search registry
[root@server1 ~]# docker pull registry
[root@server1 ~]# docker images
[root@server1 ~]# docker history registry:latest
2.运行ocker Registry容器
#首先查看的所有的容器(开启的以及未开启的)
[root@server1 ~]# docker ps -a
[root@server1 ~]# docker run -d --name registry -p 5000:5000 -v /opt/registry:/var/lib/registry registry:latest
[root@server1 ~]# docker ps
#查看5000端口是否成功开启
[root@server1 ~]# netstat -antlp
总结:
1.Docker registry容器可以通过以上步骤完成部署
2.-v是做挂接,如果路径不存在,那么会自动生成,将本机的目录挂载到容器的目录上
3.Docker 镜像的命名规则 localhost:5000/nginx:latest 中,localhost:5000 表示Registry 的地址和端口。
(二):上传镜像到本地仓库
1.更改nginx镜像的标签,并上传至搭建的私人仓库中,然后查看
#更改nginx标签,但是镜像“/nginx”前必须是localhost:5000,因为之前搭建的私人仓库的端口是本地的5000端口
[root@server1 ~]# docker tag nginx:latest localhost:5000/nginx
#查看标签为localhost:5000/nginx的镜像
[root@server1 ~]# docker images localhost:5000/nginx
#上传镜像到私有仓库中(通过localhost:5000端口进行对应上传)
[root@server1 ~]# docker push localhost:5000/nginx
[root@server1 ~]# docker images
2.下载tree并查看docker的树状图(会发现/opt/registry目录下有相对应的第有仓库的镜像数据)
[root@server1 ~]# yum install tree -y
#查看私有仓库下的数状图
[root@server1 ~]# cd /opt/registry/
[root@server1 registry]# ls
[root@server1 registry]# tree docker/
(三)在私有仓库中下载镜像
1.获取registry仓库中的镜像
[root@server1 ~]# curl http://localhost:5000/v2/_catalog
[root@server1 ~]# curl http://172.25.66.1:5000/v2/nginx/tags/list
[root@server1 ~]# docker images
[root@server1 ~]# docker rmi nginx:latest
[root@server1 ~]# docker images
[root@server1 ~]# docker rmi localhost:5000/nginx:latest
[root@server1 ~]# docker images
[root@server1 ~]# docker pull localhost:5000/nginx
[root@server1 ~]# docker images
[root@server1 ~]# docker tag localhost:5000/nginx:latest nginx
[root@server1 ~]# docker images
(一)配置私有仓库registry加密访问控制证书
1.在certs目录下创建certs证书并生成服务器私钥
[root@server1 ~]# cd /tmp/
[root@server1 tmp]# mkdir docker
[root@server1 tmp]# cd docker/
[root@server1 docker]# mkdir certs
[root@server1 docker]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/westos.org.key -x509 -days 365 -out certs/westos.org.crt
# 需要输入的内容如下(可自定义,但是域名westos.org必须和命令行的一致)
Country Name (2 letter code) [XX]:cn
State or Province Name (full name) []:shaanxi
Locality Name (eg, city) [Default City]:xi'an
Organization Name (eg, company) [Default Company Ltd]:westos
Organizational Unit Name (eg, section) []:linux
Common Name (eg, your name or your server's hostname) []:westos.org
Email Address []:[email protected]
[root@server1 docker]# ls certs/
#私有仓库不属于这台主机,所以需要加域名解析
[root@server1 docker]# vim /etc/hosts
[root@server1 docker]# ping westos.org
172.25.66.1 server1 westos.org
[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:latest
[root@server1 docker]# docker ps
[root@server1 docker]# netstat -antlp
注意:
参数说明:
-v 挂载的不是仓库的目录,而是本机的certs
-d:后台静默运行容器。
–restart:设置容器重启策略。
–name:命名容器。
-v:挂载信息
-e表示编辑,改变其内部的端口号(动态变更改变配置文件中的选项)
-e REGISTRY_HTTP_ADDR:设置仓库主机地址格式。
#指定证书,可以在容器内直接调用
-e REGISTRY_HTTP_TLS_CERTIFICATE:设置环境变量告诉容器证书的位置。
-e REGISTRY_HTTP_TLS_KEY:设置环境变量告诉容器私钥的位置。
-p:将容器的 443 端口映射到Host主机的 443 端口
6.将certs证书放到新建的docker数据目录中
[root@server1 docker]# cd /etc/docker
[root@server1 docker]# mkdir certs.d
[root@server1 docker]# cd certs.d/
[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
[root@server1 ~]# docker load -i game2048.tar
[root@server1 ~]# docker images
[root@server1 ~]# docker tag game2048:latest redhat.org/game2048
[root@server1 ~]# docker images
[root@server1 ~]# docker push westos.org/game2048
补充:
如果镜像的名称与之前证书的域名不一样,会出现以下报错(The push refers to repository [redhat.org/game2048] Get https://redhat.org/v2/: dial tcp: lookup redhat.org on 114.114.114.114:53: no such host
(二)在客户端测试(server2)
1.将docker主机(server1)中的docker文件中的安装包发送至server2,并在server2中下载
[root@server2 ~]# ls
[root@server2 ~]# cd docker/
[root@server2 docker]# ls
[root@server2 docker]# yum install -y *
[root@server2 docker]# systemctl start docker
3.创建放置证书的目录
[root@server2 docker]# cd /etc/docker/
[root@server2 docker]# ls
[root@server2 docker]# mkdir certs.d/westos.org -p
[root@server2 docker]# ls
[root@server2 docker]# cd certs.d/westos.org/
4.在docker主机(server1)中将证书同步到server2中
[root@server1 ~]# cd /etc/docker/certs.d/westos.org/
[root@server1 westos.org]# ls
[root@server1 westos.org]# scp ca.crt [email protected]:/etc/docker/certs.d/westos.org/
[root@server2 westos.org]# vim /etc/hosts
更改的内容如下:
172.25.66.1 server1 westos.org
6.在server2中下载镜像,发现可以成功下载,说明服务端根据证书可以下载镜像,说明配置私有仓库registry加密访问控制证书成功
[root@server2 ~]# docker pull westos.org/game2048
[root@server2 ~]# docker images
总结:
服务端可以上传,下载镜像,客户端如果有证书,可以下载镜像,也可以上传镜像
(三)通过基本身份验证实现私有仓库registry加密访问控制
因为之前生成过服务器私钥,所以此处不需要再生成
1.创建一个auth目录(放docker用户以及密码)
[root@server1 ~]# cd /tmp/docker/
[root@server1 docker]# ls
[root@server1 docker]# mkdir auth
[root@server1 docker]# docker run --rm --entrypoint htpasswd registry:latest -Bbn bgg westos >auth/htpasswd
[root@server1 docker]# cat auth/htpasswd
[root@server1 docker]# docker run --rm --entrypoint htpasswd registry:latest -Bbn user1 redhat >> auth/htpasswd
[root@server1 docker]# cat auth/htpasswd
注意:
–entrypoint string:覆盖镜像默认的ENTRYPOINT,之前我们说过,ENTRYPOINT是不可以被覆盖的,如果实在要覆盖需要使用此参数
-B:强制密码加密
-b:使用命令行中的密码而不是提示输入密码
-n:不更新加密文件,只将加密后的用户名密码显示在屏幕上
3.将之前创建的仓库registry删除,防止冲突
[root@server1 docker]# docker rm -f registry
[root@server1 docker]# docker images
[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 \
> -v /tmp/docker/auth:/auth \
> -e "REGISTRY_AUTH=htpasswd" \
> -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
> -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
> registry:latest
注意:
参数说明:
REGISTRY_AUTH:验证方式,固定写法
REGISTRY_AUTH_HTPASSWD_REALM:验证域名,固定写法
REGISTRY_AUTH_HTPASSWD_PATH:容器中验证文件的路径,要写文件的路径
(四)测试
1.将ubuntu镜像导入并修改标签名,然后查看镜像
[root@server1 ~]# docker load -i ubuntu.tar
[root@server1 ~]# docker tag ubuntu:latest westos.org/ubuntu
[root@server1 ~]# docker images
[root@server1 ~]# docker push westos.org/ubuntu
3.此时使用之前的用户名和密码进行登陆并下载,发现可以成功登陆并下载
[root@server1 ~]# docker login westos.org
Username: bgg
[root@server1 ~]# docker push westos.org/ubuntu
4.查看记录用户密码的文件/root/.docker/config.json,发现会自动生成密码,说明下次下载镜像不用再登陆 ,之后推出用户
[root@server1 ~]# cat /root/.docker/config.json
[root@server1 ~]# docker logout westos.org
5.使用另外一个用户登陆,此时会发现文件中的内容会被覆盖,生成新的密码
[root@server1 ~]# docker login westos.org
Username: user1
Password:
[root@server1 ~]# docker logout westos.org
[root@server1 ~]# cat /root/.docker/config.json
6.此种方法与上述使用证书的区别在,此时查看文件_catalog中的内容时,发现是加密过的,无法显示的
[root@server1 ~]# curl http://westos.org:443/v2/_catalog
[root@server1 ~]# curl -k http://westos.org:443/v2/_catalog
[root@server1 ~]# curl -k https://westos.org/v2/_catalog