05 镜像仓库:该怎样用好Docker Hub这个宝藏
你好,我是Chrono。
上一次课里我们学习了“Dockerfile”和“docker build”的用法,知道了如何创建自己的镜像。那么镜像文件应该如何管理呢,具体来说,应该如何存储、检索、分发、共享镜像呢?不解决这些问题,我们的容器化应用还是无法顺利地实施。
今天,我就来谈一下这个话题,聊聊什么是镜像仓库,还有该怎么用好镜像仓库。
什么是镜像仓库(Registry)
之前我们已经用过 docker pull
命令拉取镜像,也说过有一个“镜像仓库”(Registry)的概念,那到底什么是镜像仓库呢?
还是来看Docker的官方架构图(它真的非常重要):
图里右边的区域就是镜像仓库,术语叫Registry,直译就是“注册中心”,意思是所有镜像的Repository都在这里登记保管,就像是一个巨大的档案馆。
然后我们再来看左边的“docker pull”,虚线显示了它的工作流程,先到“Docker daemon”,再到Registry,只有当Registry里存有镜像才能真正把它下载到本地。
当然了,拉取镜像只是镜像仓库最基本的一个功能,它还会提供更多的功能,比如上传、查询、删除等等,是一个全面的镜像管理服务站点。
你也可以把镜像仓库类比成手机上的应用商店,里面分门别类存放了许多容器化的应用,需要什么去找一下就行了。有了它,我们使用镜像才能够免除后顾之忧。
什么是Docker Hub
不过,你有没有注意到,在使用 docker pull
获取镜像的时候,我们并没有明确地指定镜像仓库。在这种情况下,Docker就会使用一个默认的镜像仓库,也就是大名鼎鼎的“Docker Hub”(https://hub.docker.com/)。
Docker Hub是Docker公司搭建的官方Registry服务,创立于2014年6月,和Docker 1.0同时发布。它号称是世界上最大的镜像仓库,和GitHub一样,几乎成为了容器世界的基础设施。
Docker Hub里面不仅有Docker自己打包的镜像,而且还对公众免费开放,任何人都可以上传自己的作品。经过这8年的发展,Docker Hub已经不再是一个单纯的镜像仓库了,更应该说是一个丰富而繁荣的容器社区。
你可以看看下面的这张截图,里面列出的都是下载量超过10亿次(1 Billion)的最受欢迎的应用程序,比如Nginx、MongoDB、Node.js、Redis、OpenJDK等等。显然,把这些容器化的应用引入到我们自己的系统里,就像是站在了巨人的肩膀上,一开始就会有一个高水平的起点。
但和GitHub、App Store一样,面向所有人公开的Docker Hub也有一个不可避免的缺点,就是“良莠不齐”。
在Docker Hub搜索框里输入关键字,比如Nginx、MySQL,它立即就会给出几百几千个搜索结果,有点“乱花迷人眼”的感觉,这么多镜像,应该如何挑选出最适合自己的呢?下面我就来说说自己在这方面的一些经验。
如何在Docker Hub上挑选镜像
首先,你应该知道,在Docker Hub上有官方镜像、认证镜像和非官方镜像的区别。
官方镜像是指Docker公司官方提供的高质量镜像(https://github.com/docker-library/official-images),都经过了严格的漏洞扫描和安全检测,支持x86_64、arm64等多种硬件架构,还具有清晰易读的文档,一般来说是我们构建镜像的首选,也是我们编写Dockerfile的最佳范例。
官方镜像目前有大约100多个,基本上囊括了现在的各种流行技术,下面就是官方的Nginx镜像网页截图:
你会看到,官方镜像会有一个特殊的“Official image”的标记,这就表示这个镜像经过了Docker公司的认证,有专门的团队负责审核、发布和更新,质量上绝对可以放心。
第二类是认证镜像,标记是“Verified publisher”,也就是认证发行商,比如Bitnami、Rancher、Ubuntu等。它们都是颇具规模的大公司,具有不逊于Docker公司的实力,所以就在Docker Hub上开了个认证账号,发布自己打包的镜像,有点类似我们微博上的“大V”。
这些镜像有公司背书,当然也很值得信赖,不过它们难免会带上一些各自公司的“烙印”,比如Bitnami的镜像就统一以“minideb”为基础,灵活性上比Docker官方镜像略差,有的时候也许会不符合我们的需求。
除了官方镜像和认证镜像,剩下的就都属于非官方镜像了,不过这里面也可以分出两类。
第一类是“半官方”镜像。因为成为“Verified publisher”是要给Docker公司交钱的,而很多公司不想花这笔“冤枉钱”,所以只在Docker Hub上开了公司账号,但并不加入认证。
这里我以OpenResty为例,看一下它的Docker Hub页面,可以看到显示的是OpenResty官方发布,但并没有经过Docker正式认证,所以难免就会存在一些风险,有被“冒名顶替”的可能,需要我们在使用的时候留心鉴别一下。不过一般来说,这种“半官方”镜像也是比较可靠的。
第二类就是纯粹的“民间”镜像了,通常是个人上传到Docker Hub的,因为条件所限,测试不完全甚至没有测试,质量上难以得到保证,下载的时候需要小心谨慎。
除了查看镜像是否为官方认证,我们还应该再结合其他的条件来判断镜像质量是否足够好。做法和GitHub差不多,就是看它的下载量、星数、还有更新历史,简单来说就是“好评”数量。
一般来说下载量是最重要的参考依据,好的镜像下载量通常都在百万级别(超过1M),而有的镜像虽然也是官方认证,但缺乏维护,更新不及时,用的人很少,星数、下载数都寥寥无几,那么还是应该选择下载量最多的镜像,通俗来说就是“随大流”。
下面的这张截图就是OpenResty在Docker Hub上的搜索结果。可以看到,有两个认证发行商的镜像(Bitnami、IBM),但下载量都很少,还有一个“民间”镜像下载量虽然超过了1M,但更新时间是3年前,所以毫无疑问,我们应该选择排在第三位,但下载量超过10M、有360多个星的“半官方”镜像。
看了这么多Docker Hub上的镜像,你一定注意到了,应用都是一样的名字,比如都是Nginx、Redis、OpenResty,该怎么区分不同作者打包出的镜像呢?
如果你熟悉GitHub,就会发现Docker Hub也使用了同样的规则,就是“用户名/应用名”的形式,比如 bitnami/nginx
、ubuntu/nginx
、rancher/nginx
等等。
所以,我们在使用 docker pull
下载这些非官方镜像的时候,就必须把用户名也带上,否则默认就会使用官方镜像:
Docker Hub上镜像命名的规则是什么
确定了要使用的镜像还不够,因为镜像还会有许多不同的版本,也就是“标签”(tag)。
直接使用默认的“latest”虽然简单方便,但在生产环境里是一种非常不负责任的做法,会导致版本不可控。所以我们还需要理解Docker Hub上标签命名的含义,才能够挑选出最适合我们自己的镜像版本。
下面我就拿官方的Redis镜像作为例子,解释一下这些标签都是什么意思。
通常来说,镜像标签的格式是应用的版本号加上操作系统。
版本号你应该比较了解吧,基本上都是主版本号+次版本号+补丁号的形式,有的还会在正式发布前出rc版(候选版本,release candidate)。而操作系统的情况略微复杂一些,因为各个Linux发行版的命名方式“花样”太多了。
Alpine、CentOS的命名比较简单明了,就是数字的版本号,像这里的 alpine3.15
,而Ubuntu、Debian则采用了代号的形式。比如Ubuntu 18.04是 bionic
,Ubuntu 20.04是 focal
,Debian 9是 stretch
,Debian 10是 buster
,Debian 11是 bullseye
。
另外,有的标签还会加上 slim
、fat
,来进一步表示这个镜像的内容是经过精简的,还是包含了较多的辅助工具。通常 slim
镜像会比较小,运行效率高,而 fat
镜像会比较大,适合用来开发调试。
下面我就列出几个标签的例子来说明一下。
- nginx:1.21.6-alpine,表示版本号是1.21.6,基础镜像是最新的Alpine。
- redis:7.0-rc-bullseye,表示版本号是7.0候选版,基础镜像是Debian 11。
- node:17-buster-slim,表示版本号是17,基础镜像是精简的Debian 10。
该怎么上传自己的镜像
现在,我想你应该对如何在Docker Hub上选择镜像有了比较全面的了解,那么接下来的问题就是,我们自己用Dockerfile创建的镜像该如何上传到Docker Hub上呢?
这件事其实一点也不难,只需要4个步骤就能完成。
第一步,你需要在Docker Hub上注册一个用户,这个就不必再多说了。
第二步,你需要在本机上使用 docker login
命令,用刚才注册的用户名和密码认证身份登录,像这里就用了我的用户名“chronolaw”:
第三步很关键,需要使用 docker tag
命令,给镜像改成带用户名的完整名字,表示镜像是属于这个用户的。或者简单一点,直接用 docker build -t
在创建镜像的时候就起好名字。
这里我就用上次课里的镜像“ngx-app”作为例子,给它改名成 chronolaw/ngx-app:1.0
:
第四步,用 docker push
把这个镜像推上去,我们的镜像发布工作就大功告成了:
你还可以登录Docker Hub网站验证一下镜像发布的效果,可以看到它会自动为我们生成一个页面模板,里面还可以进一步丰富完善,比如添加描述信息、使用说明等等:
现在你就可以把这个镜像的名字(用户名/应用名:标签)告诉你的同事,让他去用 docker pull
下载部署了。
离线环境该怎么办
使用Docker Hub来管理镜像的确是非常方便,不过有一种场景下它却是无法发挥作用,那就是企业内网的离线环境,连不上外网,自然也就不能使用 docker push
、docker pull
来推送拉取镜像了。
那这种情况有没有解决办法呢?
方法当然有,而且有很多。最佳的方法就是在内网环境里仿造Docker Hub,创建一个自己的私有Registry服务,由它来管理我们的镜像,就像我们自己搭建GitLab做版本管理一样。
自建Registry已经有很多成熟的解决方案,比如Docker Registry,还有CNCF Harbor,不过使用它们还需要一些目前没有讲到的知识,步骤也有点繁琐,所以我会在后续的课程里再介绍。
下面我讲讲存储、分发镜像的一种“笨”办法,虽然比较“原始”,但简单易行,可以作为临时的应急手段。
Docker提供了 save
和 load
这两个镜像归档命令,可以把镜像导出成压缩包,或者从压缩包导入Docker,而压缩包是非常容易保管和传输的,可以联机拷贝,FTP共享,甚至存在U盘上随身携带。
需要注意的是,这两个命令默认使用标准流作为输入输出(为了方便Linux管道操作),所以一般会用 -o
、-i
参数来使用文件的形式,例如:
小结
好了,今天我们一起学习了镜像仓库,了解了Docker Hub的使用方法,整理一下要点方便你加深理解:
- 镜像仓库(Registry)是一个提供综合镜像服务的网站,最基本的功能是上传和下载。
- Docker Hub是目前最大的镜像仓库,拥有许多高质量的镜像。上面的镜像非常多,选择的标准有官方认证、下载量、星数等,需要综合评估。
- 镜像也有很多版本,应该根据版本号和操作系统仔细确认合适的标签。
- 在Docker Hub注册之后就可以上传自己的镜像,用
docker tag
打上标签再用docker push
推送。 - 离线环境可以自己搭建私有镜像仓库,或者使用
docker save
把镜像存成压缩包,再用docker load
从压缩包恢复成镜像。
课下作业
最后是课下作业时间,给你留两个思考题:
- 很多应用(如Nginx、Redis、Go)都已经有了Docker官方镜像,为什么其他公司(Bitnami、Rancher)还要重复劳动,发布自己打包的镜像呢?
- 你能否对比一下GitHub和Docker Hub,说说它们两个在功能、服务对象、影响范围等方面的异同点呢?
记得在留言区留言参与讨论哦,如果我看到,也会第一时间给你回复。我们下节课再见。
- 朱雯 👍(13) 💬(5)
老师您好,在文中提到的arm架构和x86架构支持,请问一下,能否使用dockerfile创建同时支持两种服务的镜像呢。
2022-07-01 - 拾掇拾掇 👍(9) 💬(1)
1.我猜是把自己的工具打包进去或者官方镜像满足不了他们自己的需求 2.github 和docker hub都是仓库,不过一个是代码仓库,一个是容器仓库,面向的都是程序员或者是计算机爱好者,都提供了存储和分发功能
2022-07-01 - lesserror 👍(8) 💬(1)
请问老师: docker官网的内容我感觉很多,如何找到重点快速学习呢?
2022-07-01 - 美妙的代码 👍(5) 💬(3)
老师,很期待后面的自建镜像仓库啊
2022-07-01 - pyhhou 👍(4) 💬(1)
思考题: 1. 感觉还是为了方便用户,就拿 ubuntu 举例,官方的基本上就是一个空操作系统,而商业公司就会在其中配置一些环境或安装一些跟公司相关的应用,用户 pull 下来直接使用即可无需从头配置 2. 一个主要是为了管理代码,一个主要为了管理容器。代码仓库主要是面向开发人员,让开发人员能够更好更方便地提出问题、审查代码、流程版本控制等等。而容器仓库主要是面向运维人员,这里面相比代码仓库少了很多的环节,毕竟面对的是一个直接 pull 下来就可以使用的应用,不需要过多的审核和提示等等。个人感觉还是 GitHub 的影响范围更大吧,毕竟所有的应用归根结底都是程序,而并不是所有的程序都需要打包成镜像 最后想请教老师,能否指定镜像仓库而不是从默认的 dockerHub 上面抓取镜像?是使用 `docker pull --platform` 指令吗?有名的镜像仓库有哪些?
2022-07-03 - peter 👍(4) 💬(4)
老师的专栏很不错,不过看到的比较晚。知道以后就抓紧赶,终于同步了。 前面几篇的学习中,积累了如下几个问题: Q1:04篇中,如果run命令有多行,即包含多个“\”以及多个“&&”,那么,最后是生成一个layer还是多个layer?(文中有一句“每个指令都会生成一个 Layer”)。 Q2:04篇的问题:基于某个系统创建的镜像,可以运行在其他系统上吗?比如,基于ubuntu18创建的镜像,可以运行在centos等系统上吗? Q3:05篇的问题:除了docker Hub以及国外的其他几个仓库外,国内有docker仓库吗? Q4:“课前准备”篇中,提到了VMWare Fusion。 我用的虚拟机是VMWare workstation16,这个可以吗?
2022-07-01 - 逗逼师父 👍(3) 💬(2)
1. 其他公司有自己的环境配置需求,还可以顺便刷存在感。 2. Github是代码托管,侧重服务软件的开发阶段,范围主要是使用开源软件的开发者;DockerHub是托管镜像,侧重服务软件的部署,使用阶段,范围主要是运维工作者。
2022-07-02 - Lorry 👍(2) 💬(1)
国内Docker镜像仓库一般都是配置阿里云的吧,老师应该提一下,否则拉取镜像太慢了。
2023-01-03 - YueShi 👍(1) 💬(2)
Docker继承git和github的好多优秀的概念,pull/push/commit/tag/。。。。 想问一下老师,在编程中经常会有一些循环依赖的问题,想请问一下,会不会Dockerfile中也有,例如 A from B, B from C, C from A,这种问题存在吗? 假想一下,alpine的镜像被投毒了,是不是整个docker image镜像世界崩塌了一半?
2022-07-22 - Aaron Liu 👍(0) 💬(1)
自己搭建一个私有的Registry,一般用docker registry还是harbor?目的是简单易用易维护,公司内部有jfrog artifactory,但申请流程/权限都比较复杂,只是项目组维护自己用到的镜像,自己搭建一个比较自由
2025-01-06 - 夜空中最亮的星 👍(0) 💬(2)
https://hub.docker.com/ 这个地址国内访问不了啊
2024-02-27 - William 👍(0) 💬(1)
如何上传镜像到hub仓库? 1、在 docker hub 上注册用户 2、在本机使用 docker login 命令登陆 docker login -u username 会提示输入密码: 直接输入密码, 3、适用docker tag 命令, 对本地构建出来的镜像要命名 命名规则: 用户名/镜像名称:版本号 如: username/docker-build-demo:v1.0 //[...]内的可选-默认latest docker tag docker-build-demo username/docker-build-demo[:v1.0] 4、使用docker push 命令发布镜像道hub仓库 docker push username/docker-build-demo:v1.0
2023-12-28 - 王中阳 👍(0) 💬(1)
2. 你能否对比一下 GitHub 和 Docker Hub,说说它们两个在功能、服务对象、影响范围等方面的异同点呢? 回答:GitHub和Docker Hub是两个不同的平台,它们在功能、服务对象、影响范围等方面存在一些异同点。 功能 GitHub是一个面向开发者的代码托管平台,提供了代码托管、版本控制、协作开发、问题跟踪、代码审查等一系列功能。而Docker Hub则是一个面向容器的镜像仓库,提供了Docker镜像的存储、分享、构建、管理等一系列功能。 服务对象 GitHub的服务对象主要是开发者和开源社区,提供了一个开放的平台,让开发者可以共享代码、协作开发、提高代码质量和效率。而Docker Hub的服务对象主要是容器开发者和运维人员,提供了一个方便的平台,让用户可以轻松地构建、存储、分享和管理Docker镜像。 影响范围 GitHub的影响范围较广,涉及到各个领域的开发者和开源社区,是一个全球性的平台。而Docker Hub的影响范围相对较窄,主要涉及到容器开发者和运维人员,是一个相对专业化的平台。 异同点 GitHub和Docker Hub在一些方面存在一些异同点。例如,GitHub和Docker Hub都提供了一些基本的免费服务,但是在一些高级功能和服务上,需要付费才能使用。此外,GitHub和Docker Hub都提供了一些API和插件,可以方便地与其他工具和平台进行集成和扩展。 总的来说,GitHub和Docker Hub是两个不同的平台,它们在功能、服务对象、影响范围等方面存在一些异同点。GitHub主要面向开发者和开源社区,提供了代码托管、版本控制、协作开发等一系列功能;而Docker Hub主要面向容器开发者和运维人员,提供了Docker镜像的存储、分享、构建、管理等一系列功能。虽然两个平台的服务对象和功能不同,但是它们都是开放的平台,可以方便地与其他工具和平台进行集成和扩展,为开发者和运维人员提供更加便捷和高效的服务。 此外,GitHub和Docker Hub在一些方面也存在一些相似之处。例如,它们都是基于云计算的平台,可以方便地进行远程协作和管理;它们都提供了一些基本的免费服务,但是在一些高级功能和服务上,需要付费才能使用;它们都提供了一些API和插件,可以方便地与其他工具和平台进行集成和扩展。 综上所述,GitHub和Docker Hub是两个不同的平台,它们在功能、服务对象、影响范围等方面存在一些异同点,但是它们都是开放的平台,可以为开发者和运维人员提供更加便捷和高效的服务。
2023-05-16 - 王中阳 👍(0) 💬(1)
1. 很多应用(如 Nginx、Redis、Go)都已经有了 Docker 官方镜像,为什么其他公司(Bitnami、Rancher)还要重复劳动,发布自己打包的镜像呢? 回答:其他公司发布自己打包的镜像,一方面是为了满足不同用户的需求,另一方面是为了提供更加专业化和定制化的服务。 首先,Docker 官方镜像虽然提供了很多常用的应用镜像,但是并不能满足所有用户的需求。例如,一些用户可能需要特定版本的应用或者需要特定的配置和插件,这些需求可能无法通过官方镜像来满足。此时,其他公司发布自己打包的镜像,可以提供更加定制化的服务,满足用户的个性化需求。 其次,其他公司发布自己打包的镜像,也可以提供更加专业化的服务。这些公司可能有更加深入的了解和研究,可以提供更加优化和高效的镜像,从而提高用户的使用体验和效率。此外,这些公司还可以提供更加全面的支持和服务,包括安全性、可靠性、性能优化等方面的支持,从而帮助用户更好地使用和管理镜像。 综上所述,其他公司发布自己打包的镜像,可以提供更加定制化和专业化的服务,满足用户的个性化需求,提高用户的使用体验和效率,同时也可以提供更加全面的支持和服务。
2023-05-16 - snake 👍(0) 💬(1)
1. 加点私活或者官方镜像某些功能不满足特定的需求 2. GitHub可以上传自己或者公司的开源代码,Docker Hub只是docker的镜像管理,功能比GitHub少
2022-11-03