DockerFile使用与自定义镜像详解

本文深入解析DockerFile的概念、构建过程与保留字指令,通过案例演示自定义CentOS与Tomcat镜像,探讨CMD与ENTRYPOINT的区别,以及解决build时文件过大的策略。

【1】DockerFile是什么

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

构建的三个步骤:

  • 编写Dockerfile文件
  • docker build 生成镜像
  • docker run 创建容器运行

这里以我们熟悉的Centos为例 ,查看DockerFile大致文件结构

FROM scratch
ADD CentOS-8-Container-8.1.1911-20200113.3-layer.x86_64.tar.xz  /

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="20200114" \
    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-01-14 00:00:00-08:00"

CMD ["/bin/bash"]

从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,

  • Dockerfile是软件的原材料
  • Docker镜像是软件的交付品
  • Docker容器则可以认为是软件的运行态

Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。

在这里插入图片描述

定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;

Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像。当运行 Docker镜像时,会创建Docker容器,容器是直接提供服务的。


【2】DockerFile构建过程解析

① Dockerfile内容基础知识

  • 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
  • 指令按照从上到下,顺序执行
  • #表示注释
  • 每条指令都会创建一个新的镜像层,并对镜像进行提交

② Docker执行Dockerfile的大致流程

  • docker从基础镜像运行一个容器
  • 执行一条指令并对容器作出修改
  • 执行类似docker commit的操作提交一个新的镜像层
  • docker再基于刚提交的镜像运行一个新容器
  • 执行dockerfile中的下一条指令直到所有指令都执行完成

③ DockerFile体系结构(保留字指令)

  • FROM:基础镜像,当前新镜像是基于哪个镜像的

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

  • RUN:容器构建时需要运行的命令

  • EXPOSE:当前容器对外暴露出的端口

  • WORKDIR:指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点

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

    ENV MY_PATH /usr/mytest
    这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;也可以在其它指令中直接使用这些环境变量,比如:WORKDIR $MY_PATH

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

  • COPY:类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置。实例如COPY src dest 或者 COPY ["src", "dest"]

    //src dest均为目录,表示把src下的文件拷贝到dest目录下
    COPY server /usr/local/server/
    //src为文件,dest为目录,表示把src这个文件拷贝到dest目录下
    COPY run.sh /usr/local/sbin/

  • VOLUME:容器数据卷,用于数据保存和持久化工作

  • CMD:指定一个容器启动时要运行的命令。Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换。

    CMD ["/usr/local/apache-tomcat-8.5.42/bin/catalina.sh",“run”]
    CMD /usr/local/apache-tomcat-8.5.42/bin/startup.sh && tail -f /usr/local/apache-tomcat-8.5.42/logs/catalina.out

cmc命令的三种格式

CMD ["executable","param1","param2"] (exec格式)
CMD ["param1","param2"] (参数列表格式,作为ENTRYPOINT的默认参数)
CMD command param1 param2 (shell格式)

#实例
CMD echo "hello cmd!"
CMD ["/bin/bash", "-c", "echo 'hello cmd!'"]
  • ENTRYPOINT :指定一个容器启动时要运行的命令。ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数。
ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred)
ENTRYPOINT command param1 param2 (shell form)
  • ONBUILD:子镜像继承父镜像,子镜像运行时,父镜像ONBUILD被触发。
BUILD BOTH RUN
FROM WORKDIR CMD
MAINTAINER USER ENV
COPY EXPOSE
ADD VOLUME
RUN ENTRYPOINT
ONBUILD

④ ONBUILD测试

两个DockerFile文件:DockerFile3与DockerFile4。

DockerFile3内容如下:

FROM centos
RUN yum install -y curl
ENTRYPOINT [ "curl", "-s", "https://ip.cn" ]
ONBUILD RUN echo "now ,dockerfile3 is execute..."

生成镜像myip:

docker build -f DockerFile3 -t myip .

DockerFile4内容如下:

FROM myip
RUN yum install -y curl
ENTRYPOINT [ "curl", "-s", "https://ip.cn" ]

生成镜像myip4:

在这里插入图片描述


【3】案例之自定义镜像mycentos

首先需要了解一个Base(scratch)镜像。Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的。

① 编写DockerFile文件

目标: 默认centos镜像是不支持登陆后的默认路径、 vim编辑器、查看网络配置ifconfig的,这里自定义DockerFile使其支持。

在自定义目录下创建DockerFile文件,如/mydocker/下,内容如下:

##使用的时候注意去掉注释  可以在vim窗口模式下使用dd命令快速删除一行
#继承自centos镜像
FROM centos

#作者与邮箱
MAINTAINER jane<jane@qq.com>

#设置环境 
ENV MYPATH /usr/local

#容器启动后的落脚路径
WORKDIR $MYPATH
 
#运行安装命令 
RUN yum -y install vim
RUN yum -y install net-tools

#暴露80端口 
EXPOSE 80
 
CMD echo $MYPATH
CMD echo "success--------------ok"
CMD /bin/bash

② 构建生成镜像

在当前路径下/mydocker/执行如下格式命令:

docker build -f DockFile路径 -t 新镜像名字:TAG .

会看到 docker build 命令最后有一个 . ,其表示当前目录。

实例如下:

docker build -f DockerFile  -t mycentos:2.0 .

在这里插入图片描述
检测镜像:

[root@localhost mydocker]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              VIRTUAL SIZE
mycentos            2.0                 df8160eb077f        About a minute ago   314.3 MB
jane/centos         latest              b3a32e0a2930        14 hours ago         237.1 MB
badtomcat           1.0                 4c900ee6d6e3        19 hours ago         528.7 MB
tomcat              latest              dd7dc39599b6        37 hours ago         528.6 MB
centos              latest              495a24dc98e8        3 weeks ago          237.1 MB
hello-world         latest              9f5834b25059        13 months ago        1.84 kB

③ 创建容器并运行

命令格式如下:

docker run -it 新镜像名字:TAG  [/bin/bash]

实例如下:

docker run -it df8160eb077f /bin/bash

结果如下:
在这里插入图片描述


④ 列出镜像的变更历史

命令格式如下:

docker history 镜像ID

在这里插入图片描述


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流烟默

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值