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.4
2.4: Pulling from library/httpd
Digest: sha256:946c54069130dbf136903fe658fe7d113bd8db8004de31282e20b262a3e106fb
Status: Image is up to date for httpd:2.4
docker.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 ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dfdc1c5909cb 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.1
sha256:6036477c63eef58da0ce7219f67f9d21c389d51d129826e496e49a8161d94cfc
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test 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 images
REPOSITORY TAG IMAGE ID CREATED SIZE
heimatengyun/test 0.1 6036477c63ee 14 minutes ago 165MB
test 0.1 6036477c63ee 14 minutes ago 165MB



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



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



[root@docker ~]# docker push heimatengyun/test:0.1
The 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.1
The 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.1
Untagged: heimatengyun/test:0.1
Untagged: heimatengyun/test@sha256:0aadd890c2b083fcf52c1ab8b09aef1630ebf612de57429a36f7387bfacba6b3
[root@docker ~]# docker rmi test:0.1
Untagged: test:0.1
Deleted: sha256:6036477c63eef58da0ce7219f67f9d21c389d51d129826e496e49a8161d94cfc
Deleted: sha256:cbfff65b403b2ed790072beab328976999c75ad7d2d9ca54a62a64491325ac3f
[root@docker ~]# docker rm -f mywebsite
mywebsite
[root@docker ~]# docker ps
CONTAINER 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.1
0.1: Pulling from heimatengyun/test
68ced04f60ab: Already exists
35d35f1e0dc9: Already exists
8a918bf0ae55: Already exists
d7b9f2dbc195: Already exists
d56c468bde81: Already exists
936d6a341573: Pull complete
Digest: sha256:0aadd890c2b083fcf52c1ab8b09aef1630ebf612de57429a36f7387bfacba6b3
Status: Downloaded newer image for heimatengyun/test:0.1
docker.io/heimatengyun/test:0.1
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
heimatengyun/test 0.1 6036477c63ee 40 minutes ago 165MB
mysql latest c8ad2be69a22 6 days ago 465MB
httpd 2.4 c5a012f9cf45 6 days ago 165MB
centos 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 ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a15f183ec42d 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 日 阅读数: 11
用户头像

黑马腾云

关注

自学帮号主,致力于帮助初学者提升IT技能。 2020.06.22 加入

程序猿,持续创业者。

评论

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