写点什么

Dockerfile 中的保留字指令讲解

作者:宁在春
  • 2022 年 7 月 17 日
  • 本文字数:3171 字

    阅读完需:约 10 分钟

Dockerfile中的保留字指令讲解

之前简单学过 Docker,当时是为了快速部署一个项目,过的很快,对于 Dockerfile 文件的编写,有些显的陌生。

所以就写了这篇文章。希望能够帮助到大家哦!!!

一、Dockerfile 是什么?

概念:

Dockerfile 是用来构建 Docker 镜像的构建文件,由一系列命令和参数构成的脚本

构建三步骤:

  1. 编写 Dockerfile 文件

  2. docker build

  3. docker run

Centos 案例:

centos案例


FROM scratch  #真正的基础镜像,ADD centos-7-x86_64-docker.tar.xz /
# label 说明的意思LABEL \ org.label-schema.schema-version="1.0" \ org.label-schema.name="CentOS Base Image" \ org.label-schema.vendor="CentOS" \ org.label-schema.license="GPLv2" \ org.label-schema.build-date="20201113" \ org.opencontainers.image.title="CentOS Base Image" \ org.opencontainers.image.vendor="CentOS" \ org.opencontainers.image.licenses="GPL-2.0-only" \ org.opencontainers.image.created="2020-11-13 00:00:00+00:00"
CMD ["/bin/bash"] #最后一行执行的命令
复制代码


在哪找到的勒,在 hub.docker.com 上找到滴:centos


我们不会,但是可以先去看看人家怎么写的,抄作业这事,我想大家都熟悉吧。俗称 CV 大法😂。

二、Dockerfile 构建过程分析

入门知识:

  1. 每条保留字指令(今天的重点)都必须为大写字母并且后面要跟随至少一个参数

  2. 如:


   FROM scratch  #真正的基础镜像,   ADD centos-7-x86_64-docker.tar.xz /
复制代码


  1. 指令按照从上到下,顺序执行

  2. #表示注释。


   #这就是注释
复制代码


  1. 每条指令都会创建一个新的镜像层,并对镜像进行提交。

  2. 就如下面这样,可以套娃一样。


Dockerfile 执行流程分析:

  1. docker从基础镜像运行一个容器

  2. 执行一条指令并对容器作出修改

  3. 执行类似docker commit的操作提交一个新的镜像层。

  4. docker再基于刚提交的镜像运行一个新容器

  5. 执行dockerfile中的下一条指令直到所有指令都执行完成


后文有案例,结合案例回过来看更容易理解。




小小番外


在现阶段,我们将DockerfileDocker镜像和Docker容器看待为软件的三个不同阶段。


Dockerfile面向开发--->Docker 镜像成为交付标准--->Docker 容器则涉及部署与运维


  • Dockerfile中定义了进程所需要的一切东西,以前需要依赖的环境变量、依赖包、运行时环境等都被写入到Dockerfile文件中啦。比起之前你在 Liunx 服务器中,下载那么那么多软件,配置那么那么多,真的是简单蛮多,起码对于我这个菜鸡来说用 Docker 部署真的简单了蛮多的。

  • Docker镜像是在用Dockerfile定义了一个文件后,docker build 时产生的一个 Docker 镜像,当运行时Docker镜像时,才会真正开始提供服务。

  • Docker 容器就是运行起来即可提供服务的。

三、Dockerfile 保留字指令

Dockerfiel 保留字指令大致有以下:


  1. FROM

  2. MAINTANINER

  3. RUN

  4. EXPOSE

  5. WORKDIR

  6. ENV

  7. ADD

  8. COPY

  9. VOLUME

  10. CMD

  11. ENTRYPOINT

  12. ONBUILD

3.1、FROM

基础镜像,即当前新镜像是基于哪个镜像创建的。


#基于openjdk:8 创建镜像FROM openjdk:8
复制代码

3.2、MAINTAINER

镜像维护者的姓名和邮箱地址


MAINTAINER 宁在春<crush@163.com>
复制代码

3.3、RUN

容器构建时需要运行的指令


RUN mkdir -p /conf/my.cn
复制代码

3.4、EXPOSE

当前容器对外暴露的端口


#暴露出MyCat的所需端口EXPOSE 8066 9066
复制代码

3.5、WORKDIR

指定在创建容器后,终端默认登录的进来工作目录


#容器数据卷,用于数据保存和持久化工作WORKDIR /usr/local/mycat
复制代码

3.6、ENV

用来在构建镜像过程中设置环境变量


#用来在构建镜像过程中设置环境变量ENV MYCAT_HOME=/usr/local/mycat
复制代码


这个环境变量可以在后续的任何 RUN 指令中使用,这就如同在命令前面指定了环境变量前缀一样;也可以在其它指令中直接使用这些环境变量。


如:


RUN $MYCAT_HOME/mycat
复制代码

3.7、ADD 和 COPY

ADD


将宿主机目录下的文件拷贝进镜像,并且 ADD 命令会自动处理 URL 和解压 tar 压缩包


ADD centos-6-docker.tar.xz / 
复制代码


COPY


类似 ADD,拷贝文件和目录到镜像中。


将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置


COPY src destCOPY ["src" "dest"]
复制代码

3.8、VOLUME

容器数据卷,用于数据持久化和数据保存。


#将mycat的配置文件的地址暴露出映射地址,启动时直接映射宿主机的文件夹VOLUME /usr/local/mycat
复制代码

3.9、CMD 和 ENTRYPOINT

CMD


CMD 的指令和 RUN 相似,也是两种格式:


  • shell格式:CMD<命令>

  • exec 格式:CMD ["可执行文件“,”参数 1“,”参数 2“.....]


Dockerfile中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被docker run 之后的参数替换。


ENTRYPOINT


指定一个容器启动时要运行的命令。


ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数。


区别


在这里先简单说明一下区别,你可以将 CMD 理解为覆盖


CMD cat /conf/my.cnfCMD /bin/bash
复制代码


这两条指令都写在Dockerfile文件中,只会执行 CMD /bin/bash ,而不会执行CMD cat /conf/my.cnf,因为CMD /bin/bash把上一条直接覆盖掉了。


ENTRYPOINT则不同,你可以将ENTRYPOINT简单理解为追加。


主要体现在docker run 上,如果使用dockerfile文件中最后是CMD结尾,则在运行时不能够额外追加命令,否则会覆盖掉Dockerfile中的CMD命令。


Dockerfile文件中最后一行为ENTRYPOINT结尾时,你可以在docker run 命令后追加一些命令.

3.10、ONBUILD

当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后,父镜像的onbuild被触发。

四、实战案例

4.1、制作一个自己的 Centos 镜像

4.1.1、引入:

我们先从阿里云上拉取一个 centos 看看,看看有哪些问题,然后我们再进行自定义。


docker pull centos # 拉取镜像docker run -it centos #运行镜像# ===== 测试====vim ceshi.txtifconfig pwd
复制代码



为什么会这样?因为 docker 仓库中的 Centos 是精简版,其只有内核,没有其它的东西。


要求自定义的 Centos 能够解决上述问题。

4.1.2、编写 Dockerfile 文件

为我们自定义的 Centos 编写 Dockerfile 文件


FROM centosMAINTAINER 宁在春<crush@163.com>ENV MYPATH /usr/localWORKDIR $MYPATHRUN yum -y install vimRUN yum -y install net-toolsEXPOSE 80 CMD echo $MYPATHCMD echo "success"CMD /bin/bash  #只会运行最后一个
复制代码



然后把这个复制进去即可。


mkdir -p /usr/local/docker/mycentos # 自己创建存放的位置vim Dockerfile
复制代码


4.1.3、构建 centos 镜像

docker build -f /usr/local/docker/mycentos/Dockerfile  -t mycentos:1.1 .
复制代码


解释:


  • -f:后面跟随的是 Dockerfile 文件

  • -t :后面跟随的镜像名和版本号。

  • 最后的小数点:就表明是当前目录。



- 当dockerfile文件命名为dockerfile时并且在当前目录下时可简写为:
- ```bash docker build -t 镜像名:tag .docker build -t mycentos:1.1 .
复制代码


执行



看到最后的这个就是代表成功了。



docker images 查看全部镜像:


4.1.4、运行 Centos 镜像

docker run -it mycentos:1.3pwdifconfig
复制代码



之所以我们进去容器的目录会从/切换到/usr/local是因为在 dockerfile 文件中已经写明。


ENV MYPATH /usr/localWORKDIR $MYPATH
复制代码

4.1.5、查看镜像的变更历史

docker history mycentos:1.1
复制代码



在这里也可以看出来,镜像它是由 Dockerfile 文件中的指令,一层一层构建出来的。

4.2、ONBUILD 示例

率先构建一个夫镜像

编写dockerfile文件,命名为dockerfile2


FROM centosRUN yum -y install  curlONBUILD RUN echo "我被子镜像继承了,输出此条语句"CMD ["crul", "-s","http://ip.cn"]
复制代码


docker build -f /usr/local/docker/mycentos/Dockerfile2 -t my_father_centos .
复制代码


构建一个镜像继承夫镜像

编写dockerfile文件,命名为dockerfile3


FROM my_father_centosRUN yum -y install  curlCMD ["crul", "-s","http://ip.cn"]
复制代码


docker build -f /usr/local/docker/mycentos/Dockerfile3 -t my_son_centos .
复制代码



可以看到父镜像中的语句被输出了。

五、自言自语

纸上得来终觉浅,绝知此事要躬行。

一名喜欢文艺却踏上编程这条道路的小青年。

希望:我们,待别日相见时,都已有所成


换个小猫表情,我们一起击个掌吧。



发布于: 刚刚阅读数: 3
用户头像

宁在春

关注

还未添加个人签名 2022.07.01 加入

还未添加个人简介

评论

发布
暂无评论
Dockerfile中的保留字指令讲解_Docker_宁在春_InfoQ写作社区