千家信息网

什么是Dockerfile

发表于:2024-11-12 作者:千家信息网编辑
千家信息网最后更新 2024年11月12日,这篇文章主要介绍"什么是Dockerfile",在日常操作中,相信很多人在什么是Dockerfile问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"什么是Dockerfi
千家信息网最后更新 2024年11月12日什么是Dockerfile

这篇文章主要介绍"什么是Dockerfile",在日常操作中,相信很多人在什么是Dockerfile问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"什么是Dockerfile"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

一 DockerFile构建过程解析

1.Dockerfile内容基础知识

  1. 每条保留字指令都必须为大写字母且后面要跟随至少一个参数

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

  3. #表示注释

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

2 Docker执行Dockerfile的大致流程

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

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

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

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

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

3 小总结

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

  • Dockerfile是软件的原材料

  • Docker镜像是软件的交付品

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

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

  2. Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时,会真正开始提供服务;

  3. Docker容器,容器是直接提供服务的。

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

FROM

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

MAINTAINER

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

RUN

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

EXPOSE

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

WORKDIR

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

ENV

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

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

ADD

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

COPY

类似ADD,拷贝文件和目录到镜像中。 将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置

VOLUME

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

CMD

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

三 案例

Base镜像(scratch)

Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的

自定义镜像 mycentos

1 编写

Hub默认CentOS镜像的情况


myCentOS内容Dockerfile

FROM centosMAINTAINER zhl<253316343@qq.com>ENV MYPATH /usr/localWORKDIR $MYPATHRUN yum -y install vimRUN yum -y install net-toolsEXPOSE 80CMD echo $MYPATHCMD echo "success ------  ok"CMD /bin/bash
2 构建

docker build -f DockerFile目录 -t 新镜像名字:TAG . . 表示当前目录

docker build -f /opt/docker/mydocker/Dockerfile -t zhl/centos1.1 .

root@zhanghl:/opt/docker/mydocker# docker build -f /opt/docker/mydocker/Dockerfile -t zhl/centos1.1 .Sending build context to Docker daemon  2.048kBStep 1/10 : FROM centos ---> 300e315adb2fStep 2/10 : MAINTAINER zhl<253316343@qq.com> ---> Running in 9cef0b83aa4dRemoving intermediate container 9cef0b83aa4d ---> e03c70aa84ddStep 3/10 : ENV MYPATH /usr/local ---> Running in a06eb1e589daRemoving intermediate container a06eb1e589da ---> f817774de33bStep 4/10 : WORKDIR $MYPATH ---> Running in 2638200252e1Removing intermediate container 2638200252e1 ---> e0ac249d8189Step 5/10 : RUN yum -y install vim ---> Running in 23a14562d0d6....... ---> 059822073508Step 6/10 : RUN yum -y install net-tools ---> Running in 4a437d96a483..... ---> c49737740d20Step 7/10 : EXPOSE 80 ---> Running in 326caf878a8eRemoving intermediate container 326caf878a8e ---> 6690abcca60fStep 8/10 : CMD echo $MYPATH ---> Running in 47664a0e6e10Removing intermediate container 47664a0e6e10 ---> 8db1cff1fad3Step 9/10 : CMD echo "success ------  ok" ---> Running in 7ad2234cdfbdRemoving intermediate container 7ad2234cdfbd ---> a08723e08f62Step 10/10 : CMD /bin/bash ---> Running in e0ecfa0bf1f3Removing intermediate container e0ecfa0bf1f3 ---> 77c006bf4b15Successfully built 77c006bf4b15Successfully tagged zhl/centos1.1:latestroot@zhanghl:/opt/docker/mydocker#
3 运行

docker run -it 新镜像名字:TAG .

root@zhanghl:/opt/docker/mydocker# docker imagesREPOSITORY      TAG       IMAGE ID       CREATED         SIZEzhl/centos1.1   latest    77c006bf4b15   3 minutes ago   291MBzhl/centos      latest    e4998e64dece   38 hours ago    209MBzhl/mytomcat    1.1       a636ea3caaed   4 days ago      672MBmongo           latest    995ccc33e58f   8 days ago      449MBtomcat          latest    c0e850d7b9bb   9 days ago      667MBhello-world     latest    d1165f221234   8 weeks ago     13.3kBcentos          latest    300e315adb2f   4 months ago    209MBroot@zhanghl:/opt/docker/mydocker# docker run -it 77c006bf4b15[root@01ba3472d1c3 local]# pwd/usr/local[root@01ba3472d1c3 local]# ifconfigeth0: flags=4163  mtu 1500        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)        RX packets 21  bytes 2716 (2.6 KiB)        RX errors 0  dropped 0  overruns 0  frame 0        TX packets 0  bytes 0 (0.0 B)        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0lo: flags=73  mtu 65536        inet 127.0.0.1  netmask 255.0.0.0        loop  txqueuelen 1000  (Local Loopback)        RX packets 0  bytes 0 (0.0 B)        RX errors 0  dropped 0  overruns 0  frame 0        TX packets 0  bytes 0 (0.0 B)        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0[root@01ba3472d1c3 local]# vim a.txt[root@01ba3472d1c3 local]# cat a.txthello
4 列出镜像的变更历史

docker history [镜像名]

[root@01ba3472d1c3 local]# docker history 77c006bf4b15bash: docker: command not found[root@01ba3472d1c3 local]# exitexitroot@zhanghl:/opt/docker/mydocker# docker history  77c006bf4b15IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT77c006bf4b15   7 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh">

CMD / ENTRYPOINT 镜像案例

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

CMD

Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换
案例 tomcat 的讲解演示

追加 ls -l 命令后 替代了原理运行tomcat的命令,导致docker没有启动

ENTRYPOINT

docker run 之后的参数会被当做参数传递给 ENTRYPOINT,之后形成新的命令组合
案例

制作CMD版可以查询IP信息的容器

DockerFile: Dockerfile -myid

FROM centosRUN yum install -y curlCMD ["curl","www.trackip.net/ip?json"]
root@zhanghl:/opt/docker/mydocker# docker build -f Dockerfile-myid -t myid:1.1 .Sending build context to Docker daemon  3.072kBStep 1/3 : FROM centos ---> 300e315adb2fStep 2/3 : RUN yum install -y curl ---> Using cache ---> 82abeb79293fStep 3/3 : CMD ["curl","www.trackip.net/ip?json"] ---> Running in bafa2c73ec55Removing intermediate container bafa2c73ec55 ---> a566bc415a96Successfully built a566bc415a96Successfully tagged myid:1.1root@zhanghl:/opt/docker/mydocker# docker imagesREPOSITORY      TAG       IMAGE ID       CREATED          SIZEmyid            1.1       a566bc415a96   5 seconds ago    243MBmyip            latest    251ed5335c1a   30 minutes ago   243MBzhl/centos1.1   latest    77c006bf4b15   3 hours ago      291MBzhl/centos      latest    e4998e64dece   40 hours ago     209MBzhl/mytomcat    1.1       a636ea3caaed   4 days ago       672MBmongo           latest    995ccc33e58f   8 days ago       449MBtomcat          latest    c0e850d7b9bb   9 days ago       667MBhello-world     latest    d1165f221234   8 weeks ago      13.3kBcentos          latest    300e315adb2f   4 months ago     209MBroot@zhanghl:/opt/docker/mydocker# docker run -it myid:1.1{"IP":"175.161.93.164","Country":"CN","UA":"curl\/7.61.1","Time":1619934102}

问题 ,运行时 加参数 -i 报错

root@zhanghl:/opt/docker/mydocker# docker run -it myid:1.1 -idocker: Error response from daemon: OCI runtime create failed: container_linux.go:367: starting container process caused: exec: "-i": executable file not found in $PATH: unknown.

WHY

我们可以看到可执行文件找不到的报错,executable file not found。之前我们说过,跟在镜像名后面的是 command,运行时会替换 CMD 的默认值。因此这里的 -i 替换了原来的 CMD,而不是添加在原来的 curl -s http://ip.cn 后面。而 -i 根本不是命令,所以自然找不到。 那么如果我们希望加入 -i 这参数,我们就必须重新完整的输入这个命令: $ docker run myip curl -s http://ip.cn -i

制作ENTRYPOINT版查询IP信息的容器

DockerFile:

FROM centosRUN yum install -y curlENTRYPOINT  ["curl","www.trackip.net/ip?json"]

build

root@zhanghl:/opt/docker/mydocker# docker build -f Dockerfile-Entrypoint-myip -t myip:1.2 .Sending build context to Docker daemon  4.096kBStep 1/3 : FROM centos ---> 300e315adb2fStep 2/3 : RUN yum install -y curl ---> Using cache ---> 82abeb79293fStep 3/3 : ENTRYPOINT  ["curl","www.trackip.net/ip?json"] ---> Running in 70070b1d358cRemoving intermediate container 70070b1d358c ---> f1f60b285381Successfully built f1f60b285381Successfully tagged myip:1.2root@zhanghl:/opt/docker/mydocker#

运行

root@zhanghl:/opt/docker/mydocker# docker run -it myip:1.2{"IP":"175.161.93.164","Country":"CN","UA":"curl\/7.61.1","Time":1619934632}root@zhanghl:/opt/docker/mydocker# root@zhanghl:/opt/docker/mydocker# docker run -it myip:1.2 -iHTTP/1.1 200 OKDate: Sun, 02 May 2021 05:50:38 GMTContent-Type: text/plainContent-Length: 76Connection: keep-aliveSet-Cookie: __cfduid=d6e71854852b8ade1b5e9d1ba03386d6a1619934638; expires=Tue, 01-Jun-21 05:50:38 GMT; path=/; domain=.trackip.net; HttpOnly; SameSite=LaxCF-Cache-Status: DYNAMICcf-request-id: 09cd3a08d100000530688e1000000001Report-To: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report?s=aZpOakyvJEJIy5RKJSanPc6kAxlXG390nfy3ADvHSEbFkG7pzavegW8Xwt7RiF%2F6ExbnXvvp9ZiGHKJ0gD%2F%2F6fm5IyWGJPv%2FeKG1mY%2FGnWQ%3D"}]}NEL: {"report_to":"cf-nel","max_age":604800}Server: cloudflareCF-RAY: 648ef9214d210530-LAXalt-svc: h4-27=":443"; ma=86400, h4-28=":443"; ma=86400, h4-29=":443"; ma=86400{"IP":"175.161.93.164","Country":"CN","UA":"curl\/7.61.1","Time":1619934639}root@zhanghl:/opt/docker/mydocker# root@zhanghl:/opt/docker/mydocker#

ONBUILD 命令案例

修改上一步的DockerFile

FROM centosRUN yum install -y curlENTRYPOINT  ["curl","www.trackip.net/ip?json"]ONBUILD RUN echo "father images onbuild------886"

build镜像

docker build -f Dockerfile-Entrypoint-myip -t myip_father .

root@zhanghl:/opt/docker/mydocker# docker build -f Dockerfile-Entrypoint-myip  -t myip_father .Sending build context to Docker daemon   5.12kBStep 1/4 : FROM centos ---> 300e315adb2fStep 2/4 : RUN yum install -y curl ---> Using cache ---> 82abeb79293fStep 3/4 : ENTRYPOINT  ["curl","www.trackip.net/ip?json"] ---> Using cache ---> f1f60b285381Step 4/4 : ONBUILD RUN echo "father images onbuild------886" ---> Using cache ---> 1d20c7ac1ee1Successfully built 1d20c7ac1ee1Successfully tagged myip_father:latest

显示信息:

Step 4/4 : ONBUILD RUN echo "father images onbuild------886"

以myip:1.3 为父镜像 编写子镜像DockerFile。Dockerfile-Entrypoint-myip-sub

FROM myip_fatherRUN yum install -y curlENTRYPOINT  ["curl","www.trackip.net/ip?json"]ONBUILD RUN echo "father images onbuild------886"~
docker build -f Dockerfile-Entrypoint-myip-sub  -t myip_son .Sending build context to Docker daemon   5.12kBStep 1/4 : FROM myip_father# Executing 1 build trigger ---> Running in 9b6bfe884ccdfather images onbuild------886Removing intermediate container 9b6bfe884ccd ---> d45eda2663bcStep 2/4 : RUN yum install -y curl ---> Running in 3f4e383eec45Last metadata expiration check: 1:08:58 ago on Sun May  2 05:10:51 2021.Package curl-7.61.1-14.el8_3.1.x86_64 is already installed.Dependencies resolved.Nothing to do.Complete!Removing intermediate container 3f4e383eec45 ---> 4cdefe20ba39Step 3/4 : ENTRYPOINT  ["curl","www.trackip.net/ip?json"] ---> Running in 395df3226201Removing intermediate container 395df3226201 ---> fc869c497482Step 4/4 : ONBUILD RUN echo "father images onbuild------886" ---> Running in 36d3ac20d0feRemoving intermediate container 36d3ac20d0fe ---> c3615df75130Successfully built c3615df75130Successfully tagged myip_son:latest

build时父类onbuild事件被触发

 ONBUILD RUN echo "father images onbuild------886"

自定义镜像TOMCAT

1 创建实验目录 /opt/docker/mydocker/tomcat9
2 创建c.txt

touch c.txt

3 将jdk和tomcat安装的压缩包拷贝进目录
root@zhanghl:/opt/docker/mydocker/tomcat9# ll总用量 152772drwxr-xr-x 2 root root      4096 5月   2 16:33 ./drwxr-xr-x 3 root root      4096 5月   2 14:25 ../-rw-r--r-- 1 root root  11486964 5月   2 14:30 apache-tomcat-9.0.45.tar.gz-rw-r--r-- 1 root root         0 5月   2 14:28 c.txt-rw-r--r-- 1 root root 144935989 5月   2 16:31 jdk-8u291-linux-x64.tar.gzroot@zhanghl:/opt/docker/mydocker/tomcat9# pwd/opt/docker/mydocker/tomcat9
4 在目录下新建Dockerfile文件
FROM   centosMAINTAINER    ZHL<253316343@qq.com>#把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下COPY c.txt /usr/local/cincontainer.txt#把java与tomcat添加到容器中ADD jdk-8u291-linux-x64.tar.gz /usr/local/ADD apache-tomcat-9.0.45.tar.gz /usr/local/#安装vim编辑器RUN yum -y install vim#设置工作访问时候的WORKDIR路径,登录落脚点ENV MYPATH /usr/localWORKDIR $MYPATH#配置java与tomcat环境变量ENV JAVA_HOME /usr/local/jdk1.8.0_291ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarENV CATALINA_HOME /usr/local/apache-tomcat-9.0.45ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.45ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin#容器运行时监听的端口EXPOSE  8080#启动时运行tomcat# ENTRYPOINT ["/usr/local/apache-tomcat-9.0.45/bin/startup.sh" ]# CMD ["/usr/local/apache-tomcat-9.0.45/bin/catalina.sh","run"]CMD /usr/local/apache-tomcat-9.0.45/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.45/bin/logs/catalina.out

5 构建
docker build -f /opt/docker/mydocker/tomcat9/DockerFile -t mytomcat9 .
root@zhanghl:/opt/docker/mydocker/tomcat9# docker imagesREPOSITORY      TAG       IMAGE ID       CREATED         SIZEmytomcat9       latest    2b12a6a03ea0   2 minutes ago   643MB
6 RUN
docker run -d -p 9080:8080 --name myt9 -v /opt/docker/mydocker/tomcat9/test:/usr/local/apache-tomcat-9.0.45/webapps/test -v /opt/docker/mydocker/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0.45/logs  mytomcat9

准备两个目录

root@zhanghl:/opt/docker/mydocker/tomcat9# mkdir testroot@zhanghl:/opt/docker/mydocker/tomcat9# mkdir tomcat9logsroot@zhanghl:/opt/docker/mydocker/tomcat9# ll总用量 152784drwxr-xr-x 4 root root      4096 5月   2 17:23 ./drwxr-xr-x 3 root root      4096 5月   2 14:25 ../-rw-r--r-- 1 root root  11486964 5月   2 14:30 apache-tomcat-9.0.45.tar.gz-rw-r--r-- 1 root root         0 5月   2 14:28 c.txt-rw-r--r-- 1 root root      1039 5月   2 16:40 DockerFile-rw-r--r-- 1 root root 144935989 5月   2 16:31 jdk-8u291-linux-x64.tar.gzdrwxr-xr-x 2 root root      4096 5月   2 17:23 test/drwxr-xr-x 2 root root      4096 5月   2 17:23 tomcat9logs/
7 验证

进入容器查看目录内容

root@zhanghl:/opt/docker/mydocker/tomcat9# docker exec 882930ee0ac0 ls -ltotal 52drwxr-xr-x 1 root  root  4096 May  2 09:16 apache-tomcat-9.0.45drwxr-xr-x 2 root  root  4096 Nov  3 15:22 bin-rw-r--r-- 1 root  root     0 May  2 06:28 cincontainer.txtdrwxr-xr-x 2 root  root  4096 Nov  3 15:22 etcdrwxr-xr-x 2 root  root  4096 Nov  3 15:22 gamesdrwxr-xr-x 2 root  root  4096 Nov  3 15:22 includedrwxr-xr-x 8 10143 10143 4096 Apr  7 19:26 jdk1.8.0_291drwxr-xr-x 2 root  root  4096 Nov  3 15:22 libdrwxr-xr-x 3 root  root  4096 Dec  4 17:37 lib64drwxr-xr-x 2 root  root  4096 Nov  3 15:22 libexecdrwxr-xr-x 2 root  root  4096 Nov  3 15:22 sbindrwxr-xr-x 5 root  root  4096 Dec  4 17:37 sharedrwxr-xr-x 2 root  root  4096 Nov  3 15:22 src
8 结合前述的容器卷将测试的web服务test发布

在宿主机中共享文件夹中创建Web服务

root@zhanghl:/opt/docker/mydocker/tomcat9/test# mkdir WEB-INFroot@zhanghl:/opt/docker/mydocker/tomcat9/test# cd WEB-INF/root@zhanghl:/opt/docker/mydocker/tomcat9/test/WEB-INF# vim web.xmlroot@zhanghl:/opt/docker/mydocker/tomcat9/test/WEB-INF# vim a.jsp

创建 WEB-INFO目录,并在其下创建 web.xml

web.xml:

    test 

在 test目录中创建 a.jsp:

          Insert title here        -----------welcome------------    <%="i am in docker tomcat self "%>    

<% System.out.println("=============docker tomcat self");%>

重启 容器

docker restart [container id]

root@zhanghl:/opt/docker/mydocker/tomcat9/test/WEB-INF# docker psCONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                                       NAMES882930ee0ac0   mytomcat9   "/bin/sh -c '/usr/lo…"   17 minutes ago   Up 17 minutes   0.0.0.0:9080->8080/tcp, :::9080->8080/tcp   myt9root@zhanghl:/opt/docker/mydocker/tomcat9/test/WEB-INF# docker restart 882930ee0ac0

查看网页

查看日志

root@zhanghl:/opt/docker/mydocker/tomcat9/tomcat9logs# cat catalina.out

小总结

到此,关于"什么是Dockerfile"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0