Docker仓库
Docker的仓库就是存储容器镜像的地方。拥有便利的镜像发布和管理平台,是Docker优于其前任们的根本特质。
总体来看Docker 仓库可以分为两大类:
- 公共仓库:最经典的公共仓库就是Docker Hub(https://hub.docker.com)。当Docker装好后,其默认的镜像源头就是这个功能仓库。当运行Docker run或者Docker pull等命令时系统会自动从Docker Hub下载现有镜像到本地。除了Docker Hub之外还有一些第三方的公共仓库,对外提供服务,比如Quay、阿里云等。
- 私有仓库:私有仓库是互联网企业的生产中心的实际操作中的主流选择。不采用公共仓库通常出于以下两个原因:
- 公共仓库通常建于海外,下载速度受限,对于大量节点频繁更新的互联网应用场景不太友好。
- 公共仓库位于外网,直接将生产中心的应用和外网相连,存在明显安全隐患。黑客等容易通过网络漏洞渗透到企业内网;并且公共仓库内的容器镜像未通过企业内部的静态文件扫描,无法保证镜像中所采用的运行时和依赖库的安全性。
搭建私有仓库
搭建私有仓库最简单的方法是在容器管理节点(物理机或者虚拟机)上搭建registry容器,并将其作为企业内部的私有仓库,存放所有需要部署的容器镜像。
首先,让我们来看看registry仓库的搭建过程。
如前面的章节所述,在容器启动时通过-d定义为daemon后台运行;通过-it表明可以用户交互;通过-p 5000:5000指定将容器的应用端口5000映射为主机TCP端口5000,对外提供访问;通过-v /root/registry:/var/lib/registry指定了主机中的/root/registry目录mount到容器的/var/lib/registry目录,用于容器镜像的持久化保存;通过—restart=always确保容器故障时可以自动重启;通过-name registry指定容器的名称;通过registry:latest完成从公有仓库的最新registry镜像的下载。[root@training1 ~]# docker run -it -d -p 5000:5000 -v /root/registry:/var/lib/registry --restart=always --name registry registry:latest
Unable to find image 'registry:latest' locally
latest: Pulling from library/registry
c87736221ed0: Pull complete
1cc8e0bb44df: Pull complete
54d33bcb37f5: Pull complete
e8afc091c171: Pull complete
b4541f6d3db6: Pull complete
Digest: sha256:8004747f1e8cd820a148fb7499d71a76d45ff66bac6a29129bfdbfdc0154d146
Status: Downloaded newer image for registry:latest
818502a6d7f2db451e8d1551a5e65c0356d95f8c806986e8a316faa924014883
查看一下当前的运行状态,可以看到registry容器已经运行在那里了:[root@training1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
818502a6d7f2 registry:latest "/entrypoint.sh /etc…" 26 minutes ago Up 26 minutes 0.0.0.0:5000->5000/tcp registry
上传镜像
现在整个仓库里空空如也,我们尝试从另一台机器(training2)上传镜像到registry仓库里。
首先从公共仓库下载一个镜像:
然后重新给这个镜像打标签。这一步是每次镜像上传之前的必须操作。本环境中training1(172.19.46.183)为registry仓库所在。[root@training2 ~]# docker pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:451ce787d12369c5df2a32c85e5a03d52cbcef6eb3586dd03075f3034f10adcd
Status: Downloaded newer image for hello-world:latest
docker.io/library/hello-world:latest
[root@training2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 7 months ago 1.84kB
可以看到新的镜像的换成了172.19.46.183:5000/newhello,暗含这个容器对应172.19.46.183仓库的5000端口的newhello镜像。但是当前还只是存在training2主机的本地。[root@training2 ~]# docker tag hello-world 172.19.46.183:5000/newhello
[root@training2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
172.19.46.183:5000/newhello latest fce289e99eb9 7 months ago 1.84kB
hello-world latest fce289e99eb9 7 months ago 1.84kB
下一步,指定该镜像的完整新名称,正式进行上传操作:
很不幸,第一次上传失败,提示需要开通https服务。这是registry启动私有仓库的最常见错误。比较取巧的一个方式是相信内网的安全性,在终端主机(training2)上取消https的限制:[root@training2 ~]# docker push 172.19.46.183:5000/newhello
The push refers to repository [172.19.46.183:5000/newhello]
Get https://172.19.46.183:5000/v2/: http: server gave HTTP response to HTTPS client
原文为:[root@training2 ~]# vi /lib/systemd/system/docker.service
将其修改为:...
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
...
再重启服务,重新上传:ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry 172.19.46.183:5000
我们发起http请求去产看一下仓库主机的实际镜像存储情况:[root@training2 system]# systemctl daemon-reload
[root@training2 system]# systemctl restart docker
[root@training2 system]# docker push 172.19.46.183:5000/newhello
The push refers to repository [172.19.46.183:5000/newhello]
af0b15c8625b: Pushed
latest: digest: sha256:92c7f9c92844bbbb5d0a101b22f7c2a7949e40f8ea90c8b3bc396879d95e899a size: 524
可以看到Registry仓库里已经存有最新上传的镜像newhello了。[root@training2 ~]# curl -X GET http://172.19.46.183:5000/v2/_catalog
{"repositories":["newhello"]}
注:为了实现对于仓库的http连接,对于不同的Docker daemon的部署情况下,修改的Dockerd配置文件略有不同,可能是/etc/sysconfig/docker或/etc/init/docker或/etc/dafault/docker等配置文件的OPTIONS字段等。下载镜像
下一步就到了最精彩的部分了:从私有仓库下载镜像。这也是容器部署过程中,最反复发生的操作。当各个应用新版本制作完成后,将打包成新的镜像传输到生产的Registry中。生产的各个主机节点将并发地从Registry仓库下载容器。还是以training2节点为例,首先删除主机中现有的镜像缓存:
然后,尝试从Regisry仓库(172.19.46.183端口5000)中下载newhello镜像:[root@training2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
172.19.46.183:5000/newhello latest fce289e99eb9 7 months ago 1.84kB
hello-world latest fce289e99eb9 7 months ago 1.84kB
[root@training2 ~]# docker rmi 172.19.46.183:5000/newhello hello-world
Untagged: 172.19.46.183:5000/newhello:latest
Untagged: 172.19.46.183:5000/newhello@sha256:92c7f9c92844bbbb5d0a101b22f7c2a7949e40f8ea90c8b3bc396879d95e899a
Untagged: hello-world:latest
Untagged: hello-world@sha256:451ce787d12369c5df2a32c85e5a03d52cbcef6eb3586dd03075f3034f10adcd
Deleted: sha256:fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e
Deleted: sha256:af0b15c8625bb1938f1d7b17081031f649fd14e6b233688eea3c5483994a66a3
[root@training2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
可以看到,镜像已经成功下载,我们可以以这个镜像的完整名称 172.19.46.183:5000/newhello用docker run命令启动容器,也可以用docker tag命令尝试简化镜像名称后,再启动容器。[root@training2 ~]# docker pull 172.19.46.183:5000/newhello
Using default tag: latest
latest: Pulling from newhello
1b930d010525: Pull complete
Digest: sha256:92c7f9c92844bbbb5d0a101b22f7c2a7949e40f8ea90c8b3bc396879d95e899a
Status: Downloaded newer image for 172.19.46.183:5000/newhello:latest
172.19.46.183:5000/newhello:latest
[root@training2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
172.19.46.183:5000/newhello latest fce289e99eb9 7 months ago 1.84kB
小结
在本节课程中,我们介绍了两种Docker仓库类型 - 公共仓库和私有仓库,对使用场景做了分析比较,然后详细介绍了私有仓库的搭建和使用。接下来,我们将带着大家Docker生态圈部分,看看容围绕着Docker,各大企业、各类技术是如何百家争鸣的。