一.什么是Docker 仓库?
仓库是集中存放镜像文件的场所。有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。(之间的关系是:仓库注册服务器 —> 各种各样的仓库 —> 每个仓库中有大量的镜像)
仓库分为公开仓库(Public)和私有仓库(Private)两种形式。最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。 国内的公开仓库包括 Docker Pool 等,可以提供大陆用户更稳定快速的访问。私有仓库和共有仓库类似,不同之处在于前者不会在搜索结果中显示,也没有访问它的权限。只有用户设置为合作者才能访问私有仓库。
用户也可以在本地网络内创建一个私有仓库。当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。
二、 私有仓库registry的优势
有时候使用Docker Hub这样的公共仓库可能不方便,这种情况下用户可以使用registry创建一个本地仓库供私人使用。
使用私有仓库有许多优点:
1)节省网络带宽,针对于每个镜像不用每个人都去中央仓库上面去下载,只需要从私有仓库中下载即可;
2)提供镜像资源利用,针对于公司内部使用的镜像,推送到本地的私有仓库中,以供公司内部相关人员使用。
目前Docker Registry已经升级到了v2,最新版的Docker已不再支持v1。Registry v2使用Go语言编写,在性能和安全性上做了很多优化,重新设计了镜像的存储格式。如果需要安装registry v2,只需下载registry:2.2即可。
Docker官方提供的工具docker-registry可以用于构建私有的镜像仓库。
三.创建私有仓库
1.Docker 官方已经把仓库封装为镜像,直接通过启动容器就可以部署完成仓库
cd /opt/registry/
ls
docker
docker load -i registry.tar ##官方将创建私有仓库封装成了镜像
docker images registry (注意标签TAG)
REPOSITORY TAG IMAGE ID CREATED SIZE
registry 2.3.1 83139345d017 3 years ago 166MB
docker run -d --name registry -p 5000:5000 -v /opt/registry:/var/lib/registry registry:2.3.1 ##就相当于安装了一个空的仓库,运行上述命令后,会从DockerHub上拉取registry镜像并在本地启动Registry服务,并监听5000端口。上面的操作已经将镜像导入了,会直接使用上面的镜像。基于容器的运行方式
docker load -i registry ###加载一个已经存在的镜像
docker tag registry localhost:5000/registry ##修改加载的镜像的标签,将原有的镜像标记为本地的一个版本
docker push localhost:5000/registry ##将修改好的镜像上传到私有的仓库里
docker rmi localhost:5000/registry ###在这之前先执行如下命令移除本地未使用的镜像,保证拉取的镜像是从本地仓库的,而不是从缓存中获取的。
docker pull localhost:5000/registry ##拉取镜像
docker images registry ##查看拉取的自己的私有的仓库中的镜像信息
REPOSITORY TAG IMAGE ID CREATED SIZE
registry latest 0a3eb3fde7fd 4 years ago 140MB
然后就可以利用这个自己私有仓库拉取的镜像,创建需要的容器。
=====================================================================================
(1)使用标签的目的是:
docker将文件等信息的变动抽象为一次次的commit,每一次commit以后可能走向不同的分支,当我们完成dockerfile的构建后,会生成一串无规则的字符串代表此次生成的ID。此时,tag的作用就是为他创建一个友好的NAME,方便我们对镜像库的管理。docker tag image image:v1
,系统又帮我们加上了latest,也就是说,当我们不指定tag的时候,系统会自动帮我们补上latest的tag,然后去匹配,如果命中,就用对应的容器ID去创建新的tag。
(2)latest
这个latest其实在使用中不是最新的意思,而是默认值(defalut)的意思。也就是说,如果在tag为可选的命令中,我们没有写上tag,如 docker pull image:v1;docker pull image
,前者有确定的tag,而后者没有,这时系统会自动给后者添加一个:latest的标签,然后去匹配。这时如果latest对应的镜像不存在就会报错!
(3)docker的tag(标签)的语法:
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
docker run image ##默认使用的是标签为latest的镜像
docker run image:v1 ##使用的是指定的镜像
(4)docker镜像的版本控制
如果需要升级某个docker镜像,我们可以这样做。
-
1.给每个新生成的镜像都打上相应版本的tag。此时可能存在image:latest、image:v1、image:v2等。
-
2.我们要从v1升级到v2,首先我们将导入的v2镜像强制重命名为image:latest,命令为 docker tag -f image:v2 image:latest
-
3.docker stop之前正在运行的容器
-
4.启用docker run image,此时image的等价镜像image:latest就是最新的V2镜像。
=====================================================================================
2.给私有库添加证书 原来的库任何人都可以访问,这样不安全,接下来我们要增加库的安全性
(1)创建服务端key以及证书
cd /opt/docker/
mkdir -p certs
openssl req ##生成证书请求
> -newkey rsa:4096 -nodes -sha256 -keyout certs/westos.org.key
##“-new”表示新生成一个新的证书请求文件,"-key"指定私钥文件。"-keyout"选项可以指定私钥保存位置,"-nodes"选项禁止加密私钥文件,"-newkey"选项可以直接指定私钥的算法和长度,所以它主要用在openssl req自动创建私钥时。它的使用格式为"-newkey arg",其中arg的格式为"rsa:numbits",rsa表示创建rsa私钥,numbits表示私钥的长度,如果不给定长度(即"-newkey rsa")则默认从配置文件中读取长度值。其实不止支持rsa私钥,只不过现在基本都是用rsa私钥,所以默认就使用rsa。
> -x509 -days 365 -out certs/westos.org.crt
##"-out"指定输出文件,此处输出文件即为证书请求文件。使用openssl req自签署证书时,需要使用"-x509"选项,由于是签署证书请求文件,所以可以指定"-days"指定所颁发的证书有效期
(2)添加本地解析
vim /etc/hosts
172.25.254.1 westos.org
(3)创建仓库
docker rm -f registry ##之前基于容器安装的仓库,不支持证书,因此需要重新的配置。
netstat -antlp | grep :443
docker run -d
> --restart=always
> --name registry
> -v "$(pwd)"/certs:/certs
> -e REGISTRY_HTTP_ADDR=0.0.0.0:443 ## -e 设置相应的环境变量
> -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/westos.org.crt ## -e 设置相应的环境变量 添加了相应的证书的环境变量的设置
> -e REGISTRY_HTTP_TLS_KEY=/certs/westos.org.key ## -e 设置相应的环境变量 添加了相应的私钥的环境变量的设置
> -p 443:443
> -v /opt/registry:/var/lib/registry registry:2.3.1
e97292700fe680c6124c6b3491fc8101b2658adfce7867050f488b519e71375d
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d91ba651fb74 registry:2.3.1 "/bin/registry /etc/…" 10 seconds ago Up 8 seconds 0.0.0.0:443->443/tcp, 5000/tcp registry
(4)创建证书存放目录,并复制证书
cd /etc/docker/
mkdir certs.d
cd certs.d/
mkdir westos.org
cd westos.org/
ls
ca.crt
cp /opt/docker/certs/westos.org.crt ca.crt
(5)导入一个镜像并上传到私有仓库
docker load -i game2048.tar
docker tag game2048:latest westos.org/game2048
docker push westos.org/game2048
3.创建虚拟机然后试着将刚才push的虚拟机再拉取下来
(1)创建一个虚拟机 在 server1 上安装docker
systemctl start docker
vim /etc/hosts
172.25.254.1 westos.org
(2)创建同样的证书目录,并将服务端证书传到此位置
cd /etc/docker
mkdir certs.d
cd certs.d/
mkdir westos.org
cd westos.org/
pwd
/etc/docker/certs.d/westos.org
ls
ca.crt ##将服务器上的证书传到server1上
(4)下拉上传的镜像
docker pull westos.org/game2048
四.配置用户权限,给证书加密
如果想要控制registry的使用权限,使其只有在登录用户名和密码之后才能使用的话,还需要做额外的设置。registry的用户名密码文件可以通过htpasswd来生成
1.设置用户密码并查看
cd /opt/docker/
mkdir auth
docker run --entrypoint htpasswd registry:2.3.1 -Bbn wang westos > auth/htpasswd
docker run --rm --entrypoint htpasswd registry:2.3.1 -Bbn admin westos >> auth/htpasswd
cat auth/htpasswd
wang:$2y$05$lyM5fqXxNOqWQLIlMUplxet.dPLMZMlZutV6oJk7AxyZCcDUkTyZ.
admin:$2y$05$eFez8FCfUBM7BQG.uoxY9OtioSZNaaGJudyjDDm3gb4U0XBJg8q8q
2.创建仓库
docker stop registry
docker rm registry
docker run -d --restart=always --name registry -v "$(pwd)"/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 "$(pwd)"/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry:2.3.1 ##这个新安装的仓库设置安装,包含了:证书和用户权限
docker tag rhel7:latest westos/rhel7
netstat -antlp | grep :443 ##过滤443端口
tcp6 0 0 :::443 :::* LISTEN 27631/docker-proxy
docker push westos/rhel7
no basic auth credentials ##此时上传显示没有基础认证,在没有登录相应的docker仓库的情况下,无法上传拉取相应的容器。
3.登录库,输入用户名和设置的密码
docker login westos.org
Username: wang
Password: westos
Login Succeeded ##显示成功即可
4.在文件config.json 中可以看到记录的认证(认证一次,永久保存)
cd /root/.docker/
ls
config.json
vim config.json
{
"auths": {
"westos.org": {
"auth": "aHVpOndlc3Rvcw=="
}
},
"HttpHeaders": {
"User-Agent": "Docker-Client/18.06.1-ce (linux)"
}
}
5.再次上传刚才没有上传的那个镜像
docker push westos/rhel7 ##上传成功
The push refers to repository [westos/rhel7]
18af9eb19b5f: Pushed
latest: digest: sha256:58cd9120a4194edb0de4377b71bd564953255a1422baa1bbd9cb23d521c6873b size: 528
五.给创建的私有仓库添加web的UI界面
1.导入相应的镜像
docker load -i docker-registry-web.tar
docker load -i docker-registry-frontend.tar
2.重新创建仓库(增加了一个删除参数)
docker rm -f registry
docker rm -f registry-web
docker run -d --restart=always --name registry -v "$(pwd)"/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 "$(pwd)"/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -e REGISTRY_STORAGE_DELETE_ENABLED=true registry:2.3.1 ##允许执行删除操作
docker run -it -p 8080:8080 --name registry-web --lnk registry:westos.org -e REGISTRY_URL=https://westos.org/v2 -e REGISTRY_TRUST_ANY_SSL=true -e REGISTRY_BASIC_AUTH="aHVpOndlc3Rvcw==" -e REGISTRY_NAME=westos.org -e REGISTRY_READONLY=false docker-registry-web ##运行web界面
3.测试
在网页的页面上输入:localhost:8080