继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Docker仓库-Docker优于前任们的根本特质

Java架构师讲师团
关注TA
已关注
手记 80
粉丝 4584
获赞 2541

Docker的仓库就是存储容器镜像的地方。拥有便利的镜像发布和管理平台,是Docker优于其前任们的根本特质。
图片描述
总体来看Docker 仓库可以分为两大类:

  • 公共仓库:最经典的公共仓库就是Docker Hub(https://hub.docker.com)。当Docker装好后,其默认的镜像源头就是这个功能仓库。当运行Docker run或者Docker pull等命令时系统会自动从Docker Hub下载现有镜像到本地。除了Docker Hub之外还有一些第三方的公共仓库,对外提供服务,比如Quay、阿里云等。
  • 私有仓库:私有仓库是互联网企业的生产中心的实际操作中的主流选择。不采用公共仓库通常出于以下两个原因:
    • 公共仓库通常建于海外,下载速度受限,对于大量节点频繁更新的互联网应用场景不太友好。
    • 公共仓库位于外网,直接将生产中心的应用和外网相连,存在明显安全隐患。黑客等容易通过网络漏洞渗透到企业内网;并且公共仓库内的容器镜像未通过企业内部的静态文件扫描,无法保证镜像中所采用的运行时和依赖库的安全性。

搭建私有仓库最简单的方法是在容器管理节点(物理机或者虚拟机)上搭建registry容器,并将其作为企业内部的私有仓库,存放所有需要部署的容器镜像。
首先,让我们来看看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

如前面的章节所述,在容器启动时通过-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镜像的下载。
查看一下当前的运行状态,可以看到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仓库里。
首先从公共仓库下载一个镜像:

[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

然后重新给这个镜像打标签。这一步是每次镜像上传之前的必须操作。本环境中training1(172.19.46.183)为registry仓库所在。

[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

可以看到新的镜像的换成了172.19.46.183:5000/newhello,暗含这个容器对应172.19.46.183仓库的5000端口的newhello镜像。但是当前还只是存在training2主机的本地。
下一步,指定该镜像的完整新名称,正式进行上传操作:

[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

很不幸,第一次上传失败,提示需要开通https服务。这是registry启动私有仓库的最常见错误。比较取巧的一个方式是相信内网的安全性,在终端主机(training2)上取消https的限制:

[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

再重启服务,重新上传:

[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

我们发起http请求去产看一下仓库主机的实际镜像存储情况:

[root@training2 ~]# curl -X GET http://172.19.46.183:5000/v2/_catalog
{"repositories":["newhello"]}

可以看到Registry仓库里已经存有最新上传的镜像newhello了。
注:为了实现对于仓库的http连接,对于不同的Docker daemon的部署情况下,修改的Dockerd配置文件略有不同,可能是/etc/sysconfig/docker/etc/init/docker/etc/dafault/docker等配置文件的OPTIONS字段等。

下一步就到了最精彩的部分了:从私有仓库下载镜像。这也是容器部署过程中,最反复发生的操作。当各个应用新版本制作完成后,将打包成新的镜像传输到生产的Registry中。生产的各个主机节点将并发地从Registry仓库下载容器。还是以training2节点为例,首先删除主机中现有的镜像缓存:

[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

然后,尝试从Regisry仓库(172.19.46.183端口5000)中下载newhello镜像:

[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

可以看到,镜像已经成功下载,我们可以以这个镜像的完整名称 172.19.46.183:5000/newhellodocker run命令启动容器,也可以用docker tag命令尝试简化镜像名称后,再启动容器。

在本篇文章中,我们介绍了两种Docker仓库类型 - 公共仓库和私有仓库,对使用场景做了分析比较,然后详细介绍了私有仓库的搭建和使用。

·············
更多精彩内容,欢迎关注课程:

国内外一线大厂技术大咖与慕课网组成专家团队12个月磨一剑

千万级电商项目从0到1到100全过程

涵盖Java程序员不同成长阶段的问题及最佳解决方案

打开App,阅读手记
1人推荐
发表评论
随时随地看视频慕课网APP