写点什么

Docker 基础修炼 4--Docker 仓库及相关命令

用户头像
黑马腾云
关注
发布于: 2020 年 07 月 21 日
Docker基础修炼4--Docker仓库及相关命令

前文介绍了 Docker 镜像及容器的基本概念和操作命令,本节继续讨论 Docker 仓库相关概念及镜像加速配置方法。


一、Docker 仓库简介


1.1 仓库概念


仓库(Repository)是集中存放镜像的地方,支持镜像分发和更新。


前文提到容器是通过镜像来创建,那么镜像就需要存放在一定的地方,而存放镜像的地方就称为仓库。因此根据仓库存放的位置不同,又分为共有仓库私有仓库


公有仓库是放在互联网上供大家免费使用的仓库,而私有仓库则是创建于公司或组织内部局域网中仅供内部使用。


目前世界上最大最知名的公有仓库是 Docker 官方提供的 Docker Hub。截至笔者写此文时为止,官宣已有超过 10 万个镜像,其中包括软件商提供、开源项目、社区提供的镜像。这些镜像直接拉取就可以使用,几乎能满足日常工作的所有需求。(Browse over 100,000 container images from software vendors, open-source projects, and the community)摘自官网。


但遗憾的是,有时候在国内直接访问官方的 Docker Hub 会比较慢,因此国内几大云厂商都提供了镜像服务,供国内下载使用。简单说就是可以理解为把官方的 Docker Hub 拷贝一份放到国内服务器并保持与官方同步。根据使用经验一般采用阿里云的镜像加速器比较稳定


仓库包括镜像存储系统账户管理系统,镜像存储是通过注册服务(registry)实现,而账户管理系统则使得多个不同账户可以各自管理自己的仓库中的镜像。


1.2 仓库与镜像的关系


注册服务器(Registry)是存放仓库的具体的服务器,一个注册服务器上可以有多个仓库,而每个仓库里可以有多个镜像。


以官方 Docker Hub 中的 Nginx 镜像为例,注册服务器、仓库、镜像之间的关系如下:



如图所示,在我们 Docker Hub 所在的服务器为注册服务器(通常直接称为官方仓库),存在一个 Nginx 的仓库,而该 Nginx 仓库中又包含非常多不同版本的 Nginx 镜像,不同版本之间通过 tag 标识其版本号。


Nginx 只是 Docker Hub 中众多仓库中的一个,其中还包括非常多的其它类型的镜像如:MySQL、Apache、Redis、mongoDB、golang 等等,想要的镜像基本上都可以找到。


接下来我们就演示下 Docker Hub 使用


二、官方仓库 Docker Hub


官方 Docker Hub 地址为:https://hub.docker.com/。我们既可以直接在 Web 页面进行账号及镜像管理,也可以直接在 Docker 中使用命令进行管理。


2.1 Docker Hub 账号管理


Docker Hub 账户不是必须的,如果你仅仅是下载镜像的话,也可以不用注册


只有当你需要将自己制作的镜像上传到 Docker Hub 仓库,这时就需要拥有账户并且再登陆成功后才能执行 push 命令将自己本地的镜像推送到远程仓库。


说明:官网可能会随时更新,以下界面均为笔者写作时最新的界面,如果以后你看到这篇文章时界面与官网有出入,请以官方为准。大多数情况下,大概步骤都相同,请举一反三。


初次进入网站进行注册



在注册界面输入 Docker ID、邮箱、密码后进行人机验证,验证通过后点击注册按钮即可,进入注册流程。


后续流程按照官网提示一步一步操作,注册过程中会进行邮箱验证,根据提示操作即可,在此就不在赘述了。


注册并登陆成功后,即可进入主界面



在这里可以创建仓库、修改密码以及对账号进行管理。


2.2 仓库管理


在 Docker Hub 上创建镜像仓库


点击仓库按钮进入仓库页面,点击页面上的创建仓库按钮



进入创建仓库页面



在页面中填写仓库名称、仓库的描述即可,其他都可以保持默认,然后点击创建即可。


说明

1、仓库可见性:默认为公有,所有人都可以查看;如果是私有仓库则只能自己查看。一个注册账户默认可以创建一个私有仓库,每月交 7 美元可以创建 5 个私有仓库(以官方最新为准)。

2、自动构建:镜像可以和源代码托管仓库(github 或 bitbacket)进行关联,每当源代码更新后就 Docker Hub 就会自动构建新版本的镜像。这将在以后文章中进行演示。


创建成功之后,自动跳转到该仓库页面



至此,一个名为 test 的仓库就创建好了,后续就可以在本地使用 docker 命令将本地镜像上传到此仓库下。


2.3 仓库命名规则


前面我们刚创建的仓库名为:heimatengyun/test,很显然默认由:用户名/仓库名,的形式构成。


以后上传镜像就上传到 heimatengyun/test 仓库下,假设上传 test 的第一个版本 test:1.0,则镜像为 heimatengyun/test:1.0。


细心的读者,如果还记得第一篇文章中提到的 hello-world 镜像,或许你就会觉得疑惑了,为什么 hello-world 镜像没有用户名前缀,而我刚创建的镜像还要加上用户名呢?


非常棒!其实这就是官方设计来区别镜像究竟是官方提供的还是用户自定义的。所有官方提供的镜像如 hello-world、mysql、nginx 等等都是不带前缀的,而用户自己创建的则需要带上用户名进行标识。


三、Docker 仓库管理


3.1 Docker 仓库相关命令


Docker 与仓库相关的命令主要包括 docker search、docker pull、docker push、docker login 等命令。


这些命令在前面的文章中都略有介绍,因此接下来我们直接通过一个案例来进行演示 docker 仓库相关命令的操作,我们还是以上一篇文章的 apache 镜像为例进行演示。


3.2 镜像仓库管理实战


需求:


拉取官方 apache 镜像,在本地运行容器并修改网站首页,将修改首页后的容器打包为镜像,上传到 docker hub 上前面创建的仓库 heimatengyun/test 中,供以后下载使用。


步骤:


(1)下载 httpd 镜像


[root@docker ~]# docker pull httpd:2.42.4: Pulling from library/httpdDigest: sha256:946c54069130dbf136903fe658fe7d113bd8db8004de31282e20b262a3e106fbStatus: Image is up to date for httpd:2.4docker.io/library/httpd:2.4
复制代码


上一篇文章中已经下载过了,如果没下载的话此处会看到层层下载的结果。


(2)运行容器并修改首页


这个过程就是模拟制作镜像,制作镜像通常有两种方式:一种是通过现有的镜像运行容器,然后在容器内进行各种定制化操作,完成后再 commit 为新镜像;第二种是直接通过 DockerFile 文件来编写镜像。很显然此次演示的是第一种方法


[root@docker ~]# docker run --name mywebsite -p 8080:80 -d httpd:2.4 dfdc1c5909cbee23ba78354d7ce42aa1e4143b0a7510f50c6bbf1eae26a31d5e[root@docker ~]# docker psCONTAINER ID     IMAGE      COMMAND     CREATED      STATUS    PORTS       NAMESdfdc1c5909cb     httpd:2.4     "httpd-foreground"   7 seconds ago  Up 2 seconds        0.0.0.0:8080->80/tcp   mywebsite[root@docker ~]# 
复制代码


根据前一篇文章的介绍,很显然现在就可以访问该容器 mywebsite 中运行的默认网站了。


此时访问网站默认页面显示的内容为:It works! 接下来我们要修改该首页内容为:wellcome to heimatengyun's website! (此处就不详细介绍了,忘记的返回查看上一篇文章)


[root@docker ~]# echo "wellcome to heimatengyun's website">index.html [root@docker ~]# cat index.html wellcome to heimatengyun's website[root@docker ~]# docker cp index.html mywebsite:/usr/local/apache2/htdocs/index.html
复制代码


此时再在浏览器中访问,就会发现已经变为自己修改后的首页内容了。


(3)将容器打包为新镜像


将容器打包为镜像使用 docker commit 命令,我们先来看看该命令的基本用法。


语法:docker commit [选项] 容器 ID 或名称 [仓库[:版本]]


选项:


[root@docker ~]# docker commit -a "heimatengyun <2319704788@qq.com>" -m "my test imgages based on httpd:2.4" mywebsite test:0.1sha256:6036477c63eef58da0ce7219f67f9d21c389d51d129826e496e49a8161d94cfc[root@docker ~]# docker images          REPOSITORY       TAG        IMAGE ID         CREATED             SIZEtest             0.1        6036477c63ee     3 seconds ago       165MB
复制代码


这样我们就将 mywebsite 容器打包为了一个我们自定义的镜像 test,版本为 0.1,接下来将进行上传到远程仓库。


(4)将镜像上传到仓库


还记得 2.3 中仓库页面上提示上传的命令吗?页面上明确提示用命令 docker push heimatengyun/test:tagname ,但是上一步我们打包的镜像名称为 test:0.1,这在本地使用是没有任何问题的,但是如果要上传到远程仓库就要遵守他的规则,在打包镜像名称前需要添加用户名。


因此有两种选择:


第一种是在上一步打包时,镜像名称前要加用户名前缀:heimatengyun/test:0.1;


另外一种用法是可以用 docker tag 命令重命名镜像。此处是为了演示 docker tag 的用法因此上一步故意没有加上前缀。在具体使用时你可以任意选择一种。


docker tag 命令的作用是新建一个新名称的镜像指向原来的镜像,其语法:


docker tag 原来镜像名[:TAG] 新镜像名[:TAG]


[root@docker ~]# docker tag test:0.1 heimatengyun/test:0.1[root@docker ~]# docker imagesREPOSITORY          TAG        IMAGE ID            CREATED             SIZEheimatengyun/test   0.1        6036477c63ee        14 minutes ago      165MBtest                0.1        6036477c63ee        14 minutes ago      165MB
复制代码


这样我们就准备好了镜像。根据输出可以看到很明确的看到新老镜像 id 相同,因此 tag 命令并非真正意义上新创建镜像。


上传之前需要先在 docker 客户端登录到仓库中,否则将会得到权限拒绝的提示


[root@docker ~]# docker push heimatengyun/test:0.1The push refers to repository [docker.io/heimatengyun/test]4b5531dd46d8: Preparing 25a92d79dbfe: Preparing b5432b464616: Preparing e6699b4fc2e3: Preparing 762ba19e7ef1: Preparing f2cb0ecef392: Waiting denied: requested access to the resource is denied[root@docker ~]# 
复制代码


登录采用 docker login 命令。


基于安全性考虑,建议不要在一行命令中输入用户名和密码直接登录,而是直接不带账号密码等参数进行登录,在根据提示输入账号密码。


[root@docker ~]# docker login...省略输入账号密码步骤Login Succeeded[root@docker ~]#
复制代码


登录成功后,会在当前用户根目录下创建.docker/config.json 文件,用于保存用户的认证信息,下次就无须再手动登录。


[root@docker ~]# ll .docker/config.json -rw------- 1 root root 181 Mar  4 10:14 .docker/config.json[root@docker ~]# 
复制代码


万事具备,只欠上传


[root@docker ~]# docker push heimatengyun/test:0.1The push refers to repository [docker.io/heimatengyun/test]4b5531dd46d8: Pushed 25a92d79dbfe: Mounted from library/httpd b5432b464616: Mounted from library/httpd e6699b4fc2e3: Mounted from library/httpd 762ba19e7ef1: Mounted from library/httpd f2cb0ecef392: Mounted from library/httpd 0.1: digest: sha256:0aadd890c2b083fcf52c1ab8b09aef1630ebf612de57429a36f7387bfacba6b3 size: 1574
复制代码

上传成功后,我们再次进入我们的仓库,就可以看到刚上传的 0.1 版本了。别人也可以通过镜像名称:heimatengyun/test 直接搜索到。



(5)下载使用


此时别人就可以下载使用我们上传的镜像了


为了演示,我们先删除本地的镜像 heimatengyun/test:0.1 和 test:0.1,删掉之前创建的 mywebsite 容器


[root@docker ~]# docker rmi heimatengyun/test:0.1Untagged: heimatengyun/test:0.1Untagged: heimatengyun/test@sha256:0aadd890c2b083fcf52c1ab8b09aef1630ebf612de57429a36f7387bfacba6b3[root@docker ~]# docker rmi test:0.1Untagged: test:0.1Deleted: sha256:6036477c63eef58da0ce7219f67f9d21c389d51d129826e496e49a8161d94cfcDeleted: sha256:cbfff65b403b2ed790072beab328976999c75ad7d2d9ca54a62a64491325ac3f[root@docker ~]# docker rm -f mywebsite mywebsite[root@docker ~]# docker psCONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES[root@docker ~]# 
复制代码

注意观察,删除 heimatengyun/test:0.1 和 test:0.1 镜像时,提示的区别。一个是 Untagged,另外一个是 Deleted,请大家自己分析这个原理。


排除干扰后,直接从远程仓库把镜像拉下来在运行


[root@docker ~]# docker pull heimatengyun/test:0.10.1: Pulling from heimatengyun/test68ced04f60ab: Already exists 35d35f1e0dc9: Already exists 8a918bf0ae55: Already exists d7b9f2dbc195: Already exists d56c468bde81: Already exists 936d6a341573: Pull complete Digest: sha256:0aadd890c2b083fcf52c1ab8b09aef1630ebf612de57429a36f7387bfacba6b3Status: Downloaded newer image for heimatengyun/test:0.1docker.io/heimatengyun/test:0.1[root@docker ~]# docker imagesREPOSITORY          TAG                 IMAGE ID            CREATED             SIZEheimatengyun/test   0.1                 6036477c63ee        40 minutes ago      165MBmysql               latest              c8ad2be69a22        6 days ago          465MBhttpd               2.4                 c5a012f9cf45        6 days ago          165MBcentos              latest              470671670cac        6 weeks ago         237MB[root@docker ~]# 
复制代码

这样就把镜像从远程仓库拉取到本地了,在运行之前,我们来观察一个有趣的现象,这个拉取过程非常快,并且有很多层已经提示 Already exists 了。


我们透过这个现象,仔细分析一下深层次的含义:


首先:部分层提示已经存在 Already exists,原因是我们前面镜像时通过 httpd 镜像创建容器然后打包而来,在本地已经存在了 httpd 镜像,我们在做镜像时仅仅是将容器内部的网站首页名称修改而言,因此他们基础层是一样的,这正是镜像核心理念,通过这种共享机制不仅节约了存储成本,还能加速镜像下载和共享。


其次:如果你细心观察的话,可以看到每一层的下载互不影响,都是并行在执行下载。


这正是前文讲到的 docker 镜像采用分层结构的好处。


接下来我们就把刚从远程仓库下载的镜像运行起来,将容器名称设为 mynewwebsite,宿主机端口映射为 8081。


[root@docker ~]# docker run -d --name mynewwebsite -p 8081:80 heimatengyun/test:0.1 a15f183ec42db5ee531aa8c3135ac3cd39eed0416aedbd955ccadc27c61a7722[root@docker ~]# docker psCONTAINER ID        IMAGE                   COMMAND              CREATED             STATUS              PORTS                  NAMESa15f183ec42d        heimatengyun/test:0.1   "httpd-foreground"   4 seconds ago       Up 3 seconds        0.0.0.0:8081->80/tcp   mynewwebsite[root@docker ~]# 
复制代码

此时我们再通过宿主机 ip:8081 端口去访问,就可以直接看到我们修改过后的网页。


这样就完成了镜像的定制化操作和共享。是不是很方便呢?


四、第三方仓库


前文提到,由于 Docker Hub 是在国外,因此有时候网络可能不太稳定,在这种情况下,可以有两种选择方案:一种是科学上网(至于怎么上,自行查阅);第二种则是采用国内云厂商提供的三房仓库加速器。


原理很简单,之前已提到过。只不过要注意的是,前面的仓库操作都是针对 Docker Hub 仓库,而如果换为第三方的话,相应的账号、镜像存储的位置也是在国内第三方云平台上,而非 Docker Hub 中。只是需要配置 docker 镜像仓库的存储位置而已,操作方式和使用命令都一样。


国内的阿里云、网易云等都提供了镜像容器服务,根据自己的经验,如果要使用镜像加速器建议使用阿里云的即可。


如果采用阿里云 docker 镜像加速,则需要注册阿里云开发者账户,获取私有的加速器地址,然后将其配置到/etc/docker/daemon.json 文件即可。这个过程类似于在 Docker Hub 上创建自己的账户及仓库。


具体操作就不演示了,如果你不会操作,请留言,根据反馈看是否有必要单独写一篇文章进行介绍。


五、Docker 私仓搭建


如果你只想在企业内部大家局域网内部使用的私有仓库,则直接使用 docker 官方提供的 registry 镜像即可。这种场景在一般中小企业中很少见,因此不再简介,有兴趣可以直接查看官网,如果有问题也可以给我留言。


其他更高级的仓库服务以及 Registry 鉴权机制、Restfull Api 监控等知识,以后有机会再在进阶篇中演示。



自学帮


发布于: 2020 年 07 月 21 日阅读数: 127
用户头像

黑马腾云

关注

程序员、终身学习者、创业者。 2020.06.22 加入

“自学帮”公众号主。

评论

发布
暂无评论
Docker基础修炼4--Docker仓库及相关命令