陶刚的博客
与你分享我的点滴

Docker的镜像和容器(二)

说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!

一、Dockerfile语法

1.前言

这里只是简单的描述Dockerfile关键字,具体的详解可以查阅官方文档
在这里插入图片描述
在github有一个group,里面有很多官方提供的docker image并提供了Dockerfile构建文件,可以查看这些Dockerfile,从中学习,也可以通过download Dockerfile文件,通过这个Dockerfile文件就可以build一个跟官方一样的image,如下查看mysql5.7版本的Dockerfile
在这里插入图片描述

2.FROM关键字

定义:基础镜像,当前新镜像是基于哪个镜像的

尽量使用官方的image作为base image,这样安全
在这里插入图片描述

3.LABEL关键字

定义:为镜像指定标签

Metadata不可少
在这里插入图片描述

4.RUN关键字

定义:在镜像中要执行的命令

为了美观,复杂的RUN请用反斜线换行!避免无用分层,合并多条命令成一行!
在这里插入图片描述

5.WORKDIR关键字

定义:指定当前工作目录,相当于 cd

用WORKDIR,不要用RUN cd!尽量使用绝对目录!
在这里插入图片描述

6.ADD和COPY关键字

COPY定义:功能类似ADD,但是是不会自动解压文件,也不能访问网络资源

ADD定义:将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget

大部分情况,COPY优于ADD!ADD除了COPY还有额外功能(解压)!添加远程文件/目录请使用curl或者wget
在这里插入图片描述

7.ENV关键字

定义:用来在构建镜像过程中设置环境变量,指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持,如ENV MY_PATH /usr/local/bin,这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;也可以在其它指令中直接使用这些环境变量,比如:WORKDIR $MY_PATH

尽量使用ENV增加可维护性
在这里插入图片描述

8.VOLUME(存储)和EXPOSE(网络)关键字

VOLUME定义:容器数据卷,用于数据存储和持久化工作,创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等

EXPOSE定义:告诉 Docker 服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过 -P,Docker 主机会自动分配一个端口转发到指定的端口

关于VOLUME和EXPOSE会在之后的文章中进行使用介绍

9.RUN 和 CMD 和 ENTRYPOINT

RUN:执行命令并创建新的Image Layer
CMD:设置容器启动后默认执行的命令和参数
ENTRYPOINT:设置容器启动时运行的命令

9.1 Shell和Exec格式

Shell格式 把要运行的命令当成shell命令去执行
在这里插入图片描述
Exec格式 通过特定的格式去指明要运行的命令以及命令参数
在这里插入图片描述

9.2 ENTRYPOINT关键字

  • 让容器以应用程序或者服务的形式运行
  • 不会被忽略,一定会执行
  • 最佳实践:写一个shell脚本作为entrypoint
    在这里插入图片描述
    Dockerfile(Shell格式)
    在这里插入图片描述
    Dockerfile(Exec格式)
    在这里插入图片描述
  • 查看以上两个Dockerfile build出来的image,通过docker run运行容器,查看区别,首先创建Shell格式的Dockerfile使用ENTRYPOINT关键字,运行容器成功打印出hello Docker
    在这里插入图片描述
  • 修改Dockerfile文件,使用Exec格式,运行结果并没有替换定义的name常量的值,原因很简单,因为数据格式是shell,容器是基于centos(linux)系统,所以直接是在bash里面,就能通过shell去执行这个命令,而使用Exec格式只会单纯的执行echo命令并不会将其看做成shell命令,所以后面的$name不会识别替换
    在这里插入图片描述
  • 解决方法就是,指明要运行的命令是通过shell去运行的,也就是在/bin/bash里面执行命令,通过-c 指明后面的为命令字符串
    在这里插入图片描述

9.3 CMD关键字

  • 容器启动时默认执行的命令
  • 如果docker run指定了其它命令,CMD命令被忽略
  • 如果定义了多个CMD,只有最后一个会被执行
    在这里插入图片描述
  • 现在将Dockerfile文件中ENTRYPOINT关键字换成CMD关键字,并创建image,创建并运行容器,成功打印出hello Docker
    在这里插入图片描述
  • 现在使用docker run指定了其它命令,验证CMD命令被忽略,并没有打印hello Docker
    在这里插入图片描述
  • 而使用docker run 指定其他命令,运行Dockerfile文件使用ENTRYPOINT关键字构建出来的image,验证ENTRYPOINT不会被忽略,一定会执行成功打印出
    在这里插入图片描述

二、Docker Image发布

说明: 之前文章有详细实操演示从Docker Hub(类似GitHub)上去pull拉取个人或官方build好的image,对于个人来讲,自己build的image也可以分享出来,将自己的image贡献出来,让他人可以使用,就跟在github一样提倡OpenSource精神

1.第一种方式(推送到Docker Hub)

1.1 Push Image to Docker Hub

  • 首先注册账户登录Docker hub,点击Repositories就可以到目前账户下的仓库,博主这里没有

在这里插入图片描述

  • 现在就将之前创建的cdtaogang/hello-world镜像,push到Docker hub上,需要说明的是push的镜像名的格式应该是你docker hub的用户名/镜像名,不然push的时候会提示权限问题,在执行docker push命令之前,需要执行docker login输入用户名密码进行登录
    在这里插入图片描述
  • 刷新仓库页面,就能看到刚刚push到仓库的image了
    在这里插入图片描述

1.2 Pull Image from Docker Hub

  • 点击镜像进入概括,可以看到镜像的描述、标签、自述以及push新版本,因为构建image时并没有添加描述,所以肯定是空的
    在这里插入图片描述
  • 切换到Tags标签,可以看到拉取该镜像的命令
    在这里插入图片描述
  • 现在博主将本地的cdtaogang/hello-world镜像进行删除,执行docker rmi删除镜像命令提示,该镜像创建的容器正在使用,所以博主将所有的容器进行删除后,再删除该镜像
    在这里插入图片描述
  • 删除后,pull拉取我们push的image
    在这里插入图片描述

2.第二种方式(关联Github自动构建)

说明: 将Docker Hub链接到Github上(请注意:一个Github / Bitbucket帐户一次只能连接到一个Docker Hub帐户),在GIthub上创建一个代码仓库,将本地build image的Dockerfile文件push到代码仓库上,并让Docker Hub仓库与Github代码仓库进行关联,只要这个代码仓库中存在Dockerfile文件,Docker Hub就会自动去克隆这个代码仓库获取到Dockerfile,然后Docker Hub服务器就会自动帮我们去build image,这样的话,我们既提供了image的Dockerfile,又使Docker Hub 服务器自动帮我们build image,安全性就比较高了

2.1 链接到Github

  • 首先将Docker Hub链接到Github上,点击如下账户设置
    在这里插入图片描述
  • 点击关联账号,就可以看到可以关联Github和Bitbucket账户
    在这里插入图片描述
  • 点击Connect进行授权
    在这里插入图片描述
  • 链接成功,显示github账户
    在这里插入图片描述

2.2 将Dockerfile文件git到GitHub仓库

  • 通过git工具将本地Dockerfile文件上传到github test仓库
    在这里插入图片描述
  • 刷新github上的test仓库,成功上传Dockerfile
    在这里插入图片描述
  • 为了给大家演示支持多分支多版本,所以博主又在github test仓库创建一个font分支
    在这里插入图片描述– 查看Dockerfile文件内容
    在这里插入图片描述

2.3 Docker Hub Repositories关联Github Repositories并进行自动构建

  • 紧接着回到Docker Hub上,页面定位到Repositories存储库,点击Create Repositories创建一个存储库,点击已之前已链接的Github,选择用户及对应的仓库,点击BUILD RULES添加构建规则,选择Github上的分支,以及设置Tag和Dockerfile路径,最后点击创建仓库并进行构建
    在这里插入图片描述
  • 点击创建并构建后,会跳转到仓库常规界面,可以看到正在加载两个build构建
    在这里插入图片描述
  • 切换到Builds页签,现在构建的状态为正在进行和挂起等待
    在这里插入图片描述
  • 构建成功如下
    在这里插入图片描述
  • 点击Recent Builds最近构建,可以查看构建时的日志
    在这里插入图片描述
  • 回到仓库基本页面,可以对这两个自动构建的image,选择Tag进行pull拉取
    在这里插入图片描述

2.4 更新提交Dockerfile测试Docker Hub自动构建

  • 首先修改本地的Dockerfile,这里博主就只提交到master分支进行演示,将端口号修改为6380,重新提交到Github上
    在这里插入图片描述
  • 回到Docker Hub上刷新页面,自动检测关联的Github test仓库中的Dockerfile文件,实现自动构建,因为博主只更新了master分支,所以font分支则不会被检测到形成自动构建,顺便说一下更新font分支,则只需要指定分支进行push即可git push origin master:font
    在这里插入图片描述

3.第三种方式(搭建个人的Docker Hub)

说明: 对于公司或者说个人比较重要的image不想放在官方Docker Hub上,公开的都能访问,私有的需要花钱并且有些公司级的image即使放在私有仓库也有可能被泄露,所以这里搭建一个私有的Docker Hub自己可以去进行维护,这个私有的Docker Hub没有web界面只供我们个人或者公司使用,Docker Hub官网为我们提供了一个名叫registry的image,通过这个image就可以在本地或者其他服务器机器上搭建一个私人的Docker Hub

3.1 在服务器上搭建Docker Hub(Docker Registry)

  • 首先在Dokcer Hub官网上,搜索registry这个image,点击进入该image,可以看到官方提供的使用文档
    在这里插入图片描述
  • 需要准备一台linux机器,并且安装了docker,博主这里再搭建一个centos7的机器命名为centos7_2(当作一个服务器)并已安装了docker
    在这里插入图片描述
  • 回到centos7中,需要ping通centos7_2服务器
    在这里插入图片描述
  • 在centos7_2中,需要执行官方提供的在本地快速运行registry镜像
docker run -d -p 5000:5000 --restart always --name registry registry:2
  • 安装并运行registry镜像成功
    在这里插入图片描述

3.2 Push Image to My Docker Hub

  • 首先需要保证在centos7中,telnet 服务器5000端口成功,出现以下提示表示成功
    在这里插入图片描述
  • 然后需要将要push的image的tag需要命名为服务器(centos7_2)IP加上端口号,首先将之前的cdtaogang/hello-world镜像删除,重新构建
    在这里插入图片描述
  • 重新构建一个tag为服务器IP加端口的image
    在这里插入图片描述
  • 此时在进行push image之前需要配置,在/etc/docker目录下创建一个名为daemon.json文件(有就不需要创建了),进行如下配置添加信任,不然会任务我们创建的Docker Hub(192.168.88.211:5000)是不可信任的
    在这里插入图片描述
  • 以上配置了daemon.json文件,需要到/lib/systemd/system/docker.service配置文件中添加EnvironmentFile=-/etc/docker/daemon.json,让启动dockerd进程时读取daemon.json环境的文件,配置就会被加载
    在这里插入图片描述
  • 重启docker服务
    在这里插入图片描述
  • 然后就可以push到个人的docker hub上了
    在这里插入图片描述

3.3 验证Push Image to My Docker Hub成功

  • 因为私有的Docker Registry没有web界面,需要在官方提供的API接口来查询验证是否push成功,查看Listing Repositories列表库接口文档
    在这里插入图片描述
  • 输入服务器IP加上端口号/v2/_catalog请求地址,根据返回的json数据来验证是否push image到私人docker registry成功,如果返回的json数据显示我们push的image名称,则表示成功将image push到私人Docker Hub(Docker Registry)上
    在这里插入图片描述
赞(0) 打赏
版权声明:本文为CSDN博主「cdtaogang」的原创文章,遵循CC 4.0 BY-NC-SA版权协议,转载请附上原文出处链接及本声明:记录学习生活 » Docker的镜像和容器(二)

评论 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏