在 Docker 中,当我们执行 docker pull xxx 的时候,docker 会去哪儿查找并下载镜像呢?
它实际上是从 registry.hub.docker.com这个地址去查找,这就是Docker公司为我们提供的公共仓库,上面的镜像,大家都可以看到,也可以使用。所以,我们也可以带上仓库地址去拉取镜像,如:docker pull registry.hub.docker.com/library/alpine,不过要注意,这种方式下载的镜像的默认名称就会长一些。
如果要在公司中使用Docker,但是我们不可能把商业项目上传到公共仓库中,那如果要多个机器共享,又能怎么办呢?私有仓库也就有用武之地了。
所谓私有仓库,也就是在本地(局域网)搭建的一个类似公共仓库的东西,搭建好之后,我们可以将镜像提交到私有仓库中。这样我们既能使用
Docker 来运行我们的项目镜像,也避免了商业项目暴露出去的风险。
1.搭建私有仓库
我们用官方提供的registry镜像来搭建私有镜像仓库
Docker Registry有三个角色
index
负责并维护有关用户帐户、镜像的校验以及公共命名空间的信息。
Web UI
元数据存储
认证服务
符号化registry
registry是镜像和图表的仓库,它不具有本地数据库以及不提供用户认证,通过Index Auth service的Token的方式进行认证。registry client
Docker充当registry客户端来维护推送和拉取,以及客户端的授权
[root@foundation78 test]# pwd
/opt/docker/test
[root@foundation78 test]# systemctl start docker
[root@foundation78 test]# cd ..
[root@foundation78 docker]# docker volume ls # 查看所有的数据卷
[root@foundation78 docker]# docker volume prune # 删除没有用的数据卷
[root@foundation78 docker]# docker volume ls
[root@foundation78 test]# cd /var/www/html/images/
[root@foundation78 images]# docker load -i registry.tar # 下载registry镜像,如果你没有,可以直接从网上pull
[root@foundation78 images]# cd /opt/
[root@foundation78 opt]# docker run -d -p 5000:5000 -v /opt/registry:/var/lib/registry registry # 运行registry容器
[root@foundation78 opt]# ll /var/lib/docker/ # 这是docker的所有数据目录,一旦删除,docker的所有数据将会全部丢失
[root@foundation78 opt]# docker tag nginx localhost:5000/nginx # tag表示重命名,一般本地镜像在命名时需要加上仓库的ip和端口。当然这个和自己的需求有关
[root@foundation78 opt]# docker push localhost:5000/rhel:v5 # 上传镜像到本地仓库
[root@foundation78 opt]# cd registry/ # 会自动生成这个目录
[root@foundation78 registry]# ls
docker
[root@foundation78 registry]# docker images localhost:5000/nginx
[root@foundation78 registry]# docker tag localhost:5000/nginx rhel7:v1 # 我为了查看方便,把镜像名称改为我认为比较方便的名称
[root@foundation78 registry]# docker images rhel7
[root@foundation78 registry]# docker rmi localhost:5000/rhel:v5 # 为了避免冲突,删除多余的镜像,如果你没有的话,可以不用删除
[root@foundation78 registry]# netstat -antlp | grep 5000
2.制作证书
[root@foundation78 docker]# openssl req \
-newkey rsa:4096 -nodes -sha256 -keyout certs/westos.org.key \ # 请求key
-x509 -days 365 -out certs/westos.org.crt
[root@foundation78 docker]# vim /etc/hosts # 写解析
172.25.254.78 westos.org
[root@foundation78 docker]# ping westos.org
[root@foundation78 docker]# docker run -d --restart=always \
--name registry \
-v "$(pwd)"/certs:/certs \ # 在当前目录
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-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
bb783a9fa0ebb8f311fa6edbb02d101d4d62447281677f2b94e7e9ea0bfb30df
-v # 把宿主机的/opt/registry目录绑定到容器/var/lib/registry目录(这个目录是registry容器中存放镜像文件的目录),来实现数据的持久化;
-p # 映射端口;访问宿主机的5000端口就访问到registry容器的服务了;
--restart=always # 这是重启的策略,假如这个容器异常退出会自动重启容器;
--name registry # 创建容器命名为registry,你可以随便命名;
registry # 这个是registry镜像;
[root@foundation78 docker]# docker start registry
registry
[root@foundation78 docker]# docker ps
[root@foundation78 docker]# docker rm -f 7478ae88da1a # 删除无用的registry
[root@foundation78 docker]# cd /etc/docker/
[root@foundation78 docker]# mkdir -p certs.d # 名字必须为certs.d,否则上传不成功
[root@foundation78 docker]# cd certs.d/
[root@foundation78 certs.d]# mkdir westos.org
[root@foundation78 certs.d]# cd westos.org/
[root@foundation78 westos.org]# ls
[root@foundation78 westos.org]# cp /opt/docker/certs/westos.org.crt ca.crt
[root@foundation78 westos.org]# ls
ca.crt
[root@foundation78 docker]# docker tag game2048 westos.org/game2048
[root@foundation78 westos.org]# docker push westos.org/game2048 # 上传成功说明证书生效
[root@foundation78 westos.org]# netstat -antlp | grep :443
3.添加加密认证
[root@foundation78 westos.org]# cd /opt/docker/
[root@foundation78 docker]# mkdir auth
[root@foundation78 docker]# docker run --entrypoint htpasswd registry -Bbn wzt westos > auth/htpasswd # 使用registry镜像生成用户名和密码文件
[root@foundation78 docker]# cat auth/htpasswd
wxh:$2y$05$D1PIgQAkcnl.fTHs6UTpU.ol/Mx0RsCIkB2KMvaGwos04pxflPF.W
[root@foundation78 docker]# docker run --rm --entrypoint htpasswd registry -Bbn admin westos >> auth/htpasswd # 追加用户
[root@foundation78 docker]# cat auth/htpasswd
wxh:$2y$05$D1PIgQAkcnl.fTHs6UTpU.ol/Mx0RsCIkB2KMvaGwos04pxflPF.W
admin:$2y$05$5eRPrz6aS5QDog32T3pWguy6an3QEwIsLcbAYiB0efgOQQDHlB1Tq
[root@foundation78 docker]# 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
5e772c5ab96998b94b2d51c4752b2752f511b3ffb91a0a3916a7e3b1782019c5
[root@foundation78 docker]# docker push westos.org/ubuntu # 不能上传成功,因为有认证用户,但是没有认证
[root@foundation78 docker]# docker login westos.org # 用添加的用户登录,看是否可以通过认证
Username: admin
Password:
[root@foundation78 docker]# cat ~/.docker/config.json
[root@foundation78 docker]# docker push westos.org/ubuntu # 再次上传,成功上传
4.创建Web镜像仓库管理界面
[root@foundation78 docker]# cd /var/www/html/images/
[root@foundation78 images]# ls
busybox.tar demo.tar game2048.tar rhel7.tar
centos.tar docker-registry-web.tar nginx.tar ubuntu.tar
[root@foundation78 images]# docker load -i docker-registry-web.tar
[root@foundation78 docker]# docker run -it -p 8080:8080 \
--name registry-web \
--link registry:westos.org \
-e REGISTRY_URL=https://westos.org/v2 \ # 怎样访问仓库
-e REGISTRY_TRUST_ANY_SSL=true \ # 信任所有的ssl
-e REGISTRY_BASIC_AUTH="d3p0Ondlc3Rvcw==" \ # 认证功能
-e REGISTRY_NAME=westos.org \ # 指定registry名称
-e REGISTRY_READONLY=false \
docker-registry-web
访问web页面镜像仓库