赞
踩
上一篇Blog我们学习了容器数据卷,了解了容器的数据持久化机制,本篇Blog延续之前的镜像原理【Docker学习笔记 四】深入理解Docker镜像原理,继续进行学习,之前了解过:使用docker commit 命令提交容器成为一个新的版本,本篇Blog我们来继续看看image究竟是怎么构建出来的,依据什么文件构建的。
通俗的说Dockerfile就是绘制镜像image的蓝图。我们可以从dockerhub进去搜索centos我们可以看到centos的镜像,然后跳转到github主页查看镜像构建的文件:
在github主页我们可以看到centos的构建过程,也就是今天的主角:dockerfile。
我们就是依据如下指令来进行dockerfile文件编写的:
Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,’#’ 为 Dockerfile 中的注释。
关于Dockerfile指令的详细语法解释:Dockerfile文件详解,Dockerfile指令介绍的官方文档,接下来我们亲手构建一个dockerfile文件:
现在我们梳理下docker学习以来的各个概念
三个概念是自底向上的,联动前面学到的知识,其实dockerfile就是layer镜像层的编排设计图,通过这个设计图编排出一个个镜像,镜像是一个只读的使用联合文件系统的概念,顶端的容器就是读写的一个文件路径。所以镜像里的layer并不是image,这也就解释了我之前的困惑:难道镜像之间有依赖关系,删除一个镜像会影响另一个?其实镜像是基于layer构建的,而不是别的镜像,而layer可以理解为一行指令,删除镜像理解为只是删除了一个联合文件系统构建出来的一个目录包,并不会真的删除指令构建的文件,所以也不会影响别的镜像的使用。
官方的centos功能不全,例如没有vim指令,这样执行vim指令的时候会报错:
[root@192 ~]# docker run -it centos
[root@7a23a43233d6 /]# ls
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
[root@7a23a43233d6 /]# pwd
/
[root@7a23a43233d6 /]# vim test.java
bash: vim: command not found
[root@7a23a43233d6 /]#
下面通过编写Dockerfile文件来制作Centos镜像,并在官方镜像的基础上添加vim和net-tools工具。首先在/home/dockfile 目录下新建文件mydockerfile-centos。然后使用上述指令编写该文件
首先我们找到一个目录地址存放自己的镜像文件:
[root@192 ~]# cd /home
[root@192 home]# ls
dockerfiles mysql test.java tml-1 tml-not-add.java volume_centos
[root@192 dockerfiles]# vim tml-dockerfile-centos
然后编写镜像文件tml-dockerfile-centos
FROM centos:7
MAINTAINER tml<1233@qq.com>
ENV MYPATH /user/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "---end---"
CMD /bin/bash
逐行解释该Dockerfile文件的指令:
FROM centos
:该image文件继承官方的centos,后面加冒号如centos:7,用于指定镜像的版本ENV MYPATH /usr/local
:设置环境变量MYPATH ,后面有用到WORKDIR $MYPATH
:直接使用上面设置的环境变量,指定/usr/local为工作目录RUN yum -y install vim
和RUN yum -y install net-tools
:在/usr/local目录下,运行yum -y install vim和yum -y install net-tools命令安装工具,注意安装后的所有依赖和工具都会打包到image文件中EXPOSE 80
:将容器80端口暴露出来,允许外部连接这个端口CMD
:指定容器启动的时候运行命令之所以使用7的版本是因为在2022年1月31日,CentOS团队从官方镜像中移除了CentOS 8的所有包。
通过这个dockerfile构建镜像,构建镜像命令:docker build -f dockerfile文件路径 -t 镜像名[:版本号] .(这里有个小点.)
上面命令中,-t
参数用来指定 image 文件的名字,后面还可以用冒号指定标签。如果不指定,默认的标签就是latest。最后的那个点表示 Dockerfile 文件所在的路径,上例是当前路径,所以是一个点。
[root@192 dockerfiles]# docker build -f tml-dockerfile-centos -t my-centos-image:0.1 . Sending build context to Docker daemon 2.048kB Step 1/10 : FROM centos:7 7: Pulling from library/centos 2d473b07cdd5: Pull complete Digest: sha256:9d4bcbbb213dfd745b58be38b13b996ebb5ac315fe75711bd618426a630e0987 Status: Downloaded newer image for centos:7 ---> eeb6ee3f44bd Step 2/10 : MAINTAINER tml<1233@qq.com> ---> Running in 7247002afc76 Removing intermediate container 7247002afc76 ---> c1ea220d6008 Step 3/10 : ENV MYPATH /user/local ---> Running in ce0625db8456 Removing intermediate container ce0625db8456 ---> f8d16a4d561d Step 4/10 : WORKDIR $MYPATH ---> Running in 8d2b2d15d9d7 Removing intermediate container 8d2b2d15d9d7 ---> e3680c03925c Step 5/10 : RUN yum -y install vim ----------------------------------中间过程省略-------------------------------------------------- Step 6/10 : RUN yum -y install net-tools ----------------------------------中间过程省略-------------------------------------------------- Step 7/10 : EXPOSE 80 ---> Running in b9d4d8524126 Removing intermediate container b9d4d8524126 ---> 2bb9def10fb1 Step 8/10 : CMD echo $MYPATH ---> Running in f33f8e49a6d9 Removing intermediate container f33f8e49a6d9 ---> e3e6e352b142 Step 9/10 : CMD echo "---end---" ---> Running in 8ffece1e8795 Removing intermediate container 8ffece1e8795 ---> e11211a46b5e Step 10/10 : CMD /bin/bash ---> Running in 0e880df2dec8 Removing intermediate container 0e880df2dec8 ---> e4e087ce52a3 Successfully built e4e087ce52a3 Successfully tagged my-centos-image:0.1 [root@192 dockerfiles]#
查看自己构造的镜像并依据自己编写的dockerfile启动一个容器:
[root@192 dockerfiles]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE my-centos-image 0.1 e4e087ce52a3 2 minutes ago 580MB <none> <none> 55ac5aa9c06f 15 minutes ago 231MB mytomcat 1.0 251e3ac9aff1 6 days ago 684MB nginx latest 605c77e624dd 8 weeks ago 141MB tomcat latest fb5657adc892 2 months ago 680MB mysql 5.7 c20987f18b13 2 months ago 448MB mysql latest 3218b38490ce 2 months ago 516MB hello-world latest feb5d9fea6a5 5 months ago 13.3kB centos 7 eeb6ee3f44bd 5 months ago 204MB centos latest 5d0da3dc9764 5 months ago 231MB portainer/portainer latest 580c0e4e98b0 11 months ago 79.1MB elasticsearch 7.6.2 f29a1ee41030 23 months ago 791MB elasticsearch latest 5acf0e8da90b 3 years ago 486MB [root@192 dockerfiles]# docker run -it --name my-container my-centos-image:0.1 [root@2c3ef338f21d local]# pwd /user/local [root@2c3ef338f21d local]# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.8 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:ac:11:00:08 txqueuelen 0 (Ethernet) RX packets 7 bytes 586 (586.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 lo: flags=73<UP,LOOPBACK,RUNNING> 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@2c3ef338f21d local]# vim test.java [root@2c3ef338f21d local]#
可以看到现在该centos具备了vim命令能力并应用了我们配置的目录
实际上就是查看构造该镜像的dockerfile文件执行过程,我们可以看看刚刚自己编写的dockerfile:
[root@192 dockerfiles]# docker history my-centos-image:0.1
IMAGE CREATED CREATED BY SIZE COMMENT
e4e087ce52a3 6 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B
e11211a46b5e 6 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
e3e6e352b142 6 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
2bb9def10fb1 6 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B
fae10d8a4ee7 6 minutes ago /bin/sh -c yum -y install net-tools 161MB
b55b15585af4 6 minutes ago /bin/sh -c yum -y install vim 216MB
e3680c03925c 8 minutes ago /bin/sh -c #(nop) WORKDIR /user/local 0B
f8d16a4d561d 8 minutes ago /bin/sh -c #(nop) ENV MYPATH=/user/local 0B
c1ea220d6008 8 minutes ago /bin/sh -c #(nop) MAINTAINER tml<1233@qq.co… 0B
eeb6ee3f44bd 5 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 5 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 5 months ago /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4… 204MB
[root@192 dockerfiles]#
还可以从我们的docker可视化面板看的更详细些,包括镜像的基本信息
以及镜像的镜像文件细节和镜像层信息:
RUN命令与CMD命令的区别在哪里?简单说,RUN命令在 image 文件的构建阶段执行,执行结果都会打包进入 image 文件;CMD命令则是在容器启动后执行。另外,一个 Dockerfile 可以包含多个RUN命令,但是只能有一个CMD命令(或者可以有多个CMD,但是只有最后一个CMD生效)。注意,指定了CMD命令以后,docker container run命令就不能附加命令了(比如前面的/bin/bash),否则它会覆盖CMD命令。CMD和ENTRYPOINT的区别
分别看下两个的示例,注意-l :详细信息显示
,是ls命令的子选项
创建dockerfile文件tml-dockerfile-cmd
[root@192 dockerfiles]# ls
tml-dockerfile-centos
[root@192 dockerfiles]# vim tml-dockerfile-cmd
编辑dockerfile文件tml-dockerfile-cmd
FROM centos:7
ENTRYPOINT ["ls","-a"]
依据tml-dockerfile-cmd
文件构造镜像tml-cmd-test:0.1
[root@192 dockerfiles]# docker build -f tml-dockerfile-cmd -t tml-cmd-test:0.1 .
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM centos:7
---> eeb6ee3f44bd
Step 2/2 : CMD ["ls","-a"]
---> Running in 59b9d2b0bd4e
Removing intermediate container 59b9d2b0bd4e
---> 2b54bee0bae6
Successfully built 2b54bee0bae6
Successfully tagged tml-cmd-test:0.1
依据tml-cmd-test:0.1
镜像运行容器,可以看到CMD的命令已被追加执行
[root@192 dockerfiles]# docker run tml-cmd-test:0.1 . .. .dockerenv anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
run的时候尾部追加执行却抛异常,因为-l
会覆盖ls -a
命令
[root@192 dockerfiles]# docker run tml-cmd-test:0.1 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
[root@192 dockerfiles]#
再测试下末尾加ls
:
[root@192 dockerfiles]# docker run tml-cmd-test:0.1 ls anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var [root@192 dockerfiles]#
创建dockerfile文件tml-dockerfile-entrypoint-test
[root@192 dockerfiles]# ls
tml-dockerfile-centos tml-dockerfile-cmd
[root@192 dockerfiles]# vim tml-dockerfile-entrypoint-test
编辑dockerfile文件tml-dockerfile-entrypoint-test
FROM centos:7
ENTRYPOINT ["ls","-a"]
依据tml-dockerfile-cmd
文件构造镜像tml-cmd-test:0.1
[root@192 dockerfiles]# docker build -f tml-dockerfile-entrypoint-test -t tml-entrypoint-test:0.1 .
Sending build context to Docker daemon 4.096kB
Step 1/2 : FROM centos:7
---> eeb6ee3f44bd
Step 2/2 : ENTRYPOINT ["ls","-a"]
---> Running in 191de7d8b95e
Removing intermediate container 191de7d8b95e
---> 79cf0d9a1240
Successfully built 79cf0d9a1240
Successfully tagged tml-entrypoint-test:0.1
[root@192 dockerfiles]#
依据tml-entrypoint-test:0.1
镜像运行容器,可以看到ENTRYPOINT 的命令已被追加执行
[root@192 dockerfiles]# docker run tml-entrypoint-test:0.1 . .. .dockerenv anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
然后我们在命令后边继续追加-l
,可以看到:
[root@192 dockerfiles]# docker run tml-entrypoint-test:0.1 -l total 12 drwxr-xr-x 1 root root 6 Feb 27 06:47 . drwxr-xr-x 1 root root 6 Feb 27 06:47 .. -rwxr-xr-x 1 root root 0 Feb 27 06:47 .dockerenv -rw-r--r-- 1 root root 12114 Nov 13 2020 anaconda-post.log lrwxrwxrwx 1 root root 7 Nov 13 2020 bin -> usr/bin drwxr-xr-x 5 root root 340 Feb 27 06:47 dev drwxr-xr-x 1 root root 66 Feb 27 06:47 etc drwxr-xr-x 2 root root 6 Apr 11 2018 home lrwxrwxrwx 1 root root 7 Nov 13 2020 lib -> usr/lib lrwxrwxrwx 1 root root 9 Nov 13 2020 lib64 -> usr/lib64 drwxr-xr-x 2 root root 6 Apr 11 2018 media drwxr-xr-x 2 root root 6 Apr 11 2018 mnt drwxr-xr-x 2 root root 6 Apr 11 2018 opt dr-xr-xr-x 223 root root 0 Feb 27 06:47 proc dr-xr-x--- 2 root root 114 Nov 13 2020 root drwxr-xr-x 11 root root 148 Nov 13 2020 run lrwxrwxrwx 1 root root 8 Nov 13 2020 sbin -> usr/sbin drwxr-xr-x 2 root root 6 Apr 11 2018 srv dr-xr-xr-x 13 root root 0 Feb 27 06:47 sys drwxrwxrwt 7 root root 132 Nov 13 2020 tmp drwxr-xr-x 13 root root 155 Nov 13 2020 usr drwxr-xr-x 18 root root 238 Nov 13 2020 var [root@192 dockerfiles]#
我们可以在Dockerfile中使用VOLUME指令来给镜像添加一个或多个数据卷。下面使用Dockerfile构建一个新的镜像,dockerfile01文件的内容,匿名挂载了volume01和volume02两个目录:
FROM centos:7
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
执行构建镜像:
[root@192 dockerfiles]# docker build -f tml-volume-dockerfile -t docker-image-volume:1.0 . Sending build context to Docker daemon 5.12kB Step 1/4 : FROM centos:7 ---> eeb6ee3f44bd Step 2/4 : VOLUME ["volume01","volume02"] ---> Running in bd03f08b91ab Removing intermediate container bd03f08b91ab ---> d8fd913ad145 Step 3/4 : CMD echo "----end----" ---> Running in 62a9988664de Removing intermediate container 62a9988664de ---> 0ecb45090e52 Step 4/4 : CMD /bin/bash ---> Running in 7b8ac923feff Removing intermediate container 7b8ac923feff ---> 3d736800dd60 Successfully built 3d736800dd60 Successfully tagged docker-image-volume:1.0
完成镜像的生成后,启动自己生成的容器
[root@192 dockerfiles]# docker run -it docker-image-volume:1.0 /bin/bash [root@f9323fd4567f /]# ls anaconda-post.log dev home lib64 mnt proc run srv tmp var volume02 bin etc lib media opt root sbin sys usr volume01 [root@f9323fd4567f /]# ls -l total 12 -rw-r--r-- 1 root root 12114 Nov 13 2020 anaconda-post.log lrwxrwxrwx 1 root root 7 Nov 13 2020 bin -> usr/bin drwxr-xr-x 5 root root 360 Feb 27 09:29 dev drwxr-xr-x 1 root root 66 Feb 27 09:29 etc drwxr-xr-x 2 root root 6 Apr 11 2018 home lrwxrwxrwx 1 root root 7 Nov 13 2020 lib -> usr/lib lrwxrwxrwx 1 root root 9 Nov 13 2020 lib64 -> usr/lib64 drwxr-xr-x 2 root root 6 Apr 11 2018 media drwxr-xr-x 2 root root 6 Apr 11 2018 mnt drwxr-xr-x 2 root root 6 Apr 11 2018 opt dr-xr-xr-x 232 root root 0 Feb 27 09:29 proc dr-xr-x--- 2 root root 114 Nov 13 2020 root drwxr-xr-x 11 root root 148 Nov 13 2020 run lrwxrwxrwx 1 root root 8 Nov 13 2020 sbin -> usr/sbin drwxr-xr-x 2 root root 6 Apr 11 2018 srv dr-xr-xr-x 13 root root 0 Feb 27 06:47 sys drwxrwxrwt 7 root root 132 Nov 13 2020 tmp drwxr-xr-x 13 root root 155 Nov 13 2020 usr drwxr-xr-x 18 root root 238 Nov 13 2020 var drwxr-xr-x 2 root root 6 Feb 27 09:29 volume01 drwxr-xr-x 2 root root 6 Feb 27 09:29 volume02 [root@f9323fd4567f /]#
可以看到自动挂载的数据卷目录。下面查看对应宿主机的数据卷目录:
"Mounts": [ { "Type": "volume", "Name": "84bf0cdcdf0f1d000a11391ca56a9e9ca70839e99e2187d16893d133cd094065", "Source": "/var/lib/docker/volumes/84bf0cdcdf0f1d000a11391ca56a9e9ca70839e99e2187d16893d133cd094065/_data", "Destination": "volume01", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }, { "Type": "volume", "Name": "6299205be5706a8604821514ee304a1007b314d03c9350cc4715e1217862c709", "Source": "/var/lib/docker/volumes/6299205be5706a8604821514ee304a1007b314d03c9350cc4715e1217862c709/_data", "Destination": "volume02", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ],
可以看到Mounts下有宿主机的挂载目录。因为dockerfile中没有指定宿主机目录,所以属于匿名挂载,在/var/lib/docker/volumes/目录下生成了随机命名的路径。
这个问题困惑了我一段时间,不多说,直接试试:
基于centos镜像运行一个容器,并指定路径挂载数据卷
[root@192 /]# docker run -it -v /home/centos/test:/usr/var centos
[root@03a5686af4fa /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@03a5686af4fa /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@03a5686af4fa /]# cd usr
[root@03a5686af4fa usr]# ls
bin games include lib lib64 libexec local sbin share src tmp var
[root@03a5686af4fa usr]# cd var
[root@03a5686af4fa var]# ls
a.java
宿主机增加文件
[root@192 ~]# cd /home
[root@192 home]# ls
centos dockerfiles mysql test.java tml-1 tml-not-add.java tomcat volume_centos
[root@192 home]# cd centos/
[root@192 centos]# ls
test
[root@192 centos]# cd test
[root@192 test]# touch a.java
[root@192 test]#
依据当前镜像和容器提交一个新镜像
[root@03a5686af4fa var]# docker commit -m "volume是否会被带着提交" 03a5686af4fa volume-centos:1.0 bash: docker: command not found [root@03a5686af4fa var]# exit exit [root@192 /]# docker commit -m "volume是否会被带着提交" 03a5686af4fa volume-centos:1.0 sha256:caf2866a962e5a332c93e28fec00dd5b67e578267af70d909c8002ee10f17b9f [root@192 /]# ls backup bin boot dev etc home jdk-8u171-linux-x64.tar.gz kafka lib lib64 media mnt opt proc root run sbin soft srv sys tmp usr var [root@192 /]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE volume-centos 1.0 caf2866a962e 15 seconds ago 231MB docker-image-volume 1.0 3d736800dd60 3 hours ago 204MB tianmaolin/tml-mydockerfile-tomcat 1.0 94dbe2d0cb91 4 hours ago 799MB tml-mydockerfile-tomcat 1.0 94dbe2d0cb91 4 hours ago 799MB tml-dockerfile-tomcat 1.0 2a1bbcae34bf 5 hours ago 799MB tml-entrypoint-test 0.1 79cf0d9a1240 6 hours ago 204MB tml-cmd-test 0.1 2b54bee0bae6 6 hours ago 204MB my-centos-image 0.1 e4e087ce52a3 10 hours ago 580MB <none> <none> 55ac5aa9c06f 10 hours ago 231MB mytomcat 1.0 251e3ac9aff1 7 days ago 684MB nginx latest 605c77e624dd 8 weeks ago 141MB tomcat latest fb5657adc892 2 months ago 680MB mysql 5.7 c20987f18b13 2 months ago 448MB mysql latest 3218b38490ce 2 months ago 516MB hello-world latest feb5d9fea6a5 5 months ago 13.3kB centos 7 eeb6ee3f44bd 5 months ago 204MB centos latest 5d0da3dc9764 5 months ago 231MB portainer/portainer latest 580c0e4e98b0 11 months ago 79.1MB elasticsearch 7.6.2 f29a1ee41030 23 months ago 791MB elasticsearch latest 5acf0e8da90b 3 years ago 486MB [root@192 /]# docker history volume-centos Error response from daemon: No such image: volume-centos:latest [root@192 /]# docker history volume-centos:1.0 IMAGE CREATED CREATED BY SIZE COMMENT caf2866a962e 44 seconds ago /bin/bash 112B volume是否会被带着提交 5d0da3dc9764 5 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B <missing> 5 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B <missing> 5 months ago /bin/sh -c #(nop) ADD file:805cb5e15fb6e0bb0… 231MB
依据新镜像运行容器并查看容器数据卷目录
[root@192 /]# docker run -it volume-centos:1.0 /bin/bash
[root@06b20f3507cc /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@06b20f3507cc /]# cd usr
[root@06b20f3507cc usr]# ls
bin games include lib lib64 libexec local sbin share src tmp var
[root@06b20f3507cc usr]# cd var
[root@06b20f3507cc var]# ls
可以看到并没有a.java
文件,但是var文件夹创建上了,同时查看下该容器元数据
"Mounts": [],
由此可见volume数据卷是独立于联合文件系统的。
按照如下步骤进行tomcat镜像制作及发布:
使用appNode将两个tomcat镜像构建用到的压缩包上传到/home/tomcat
目录下
目录如下:
[root@192 ~]# cd /home
[root@192 home]# ls
dockerfiles mysql test.java tml-1 tml-not-add.java tomcat volume_centos
[root@192 home]# cd tomcat
[root@192 tomcat]# ls
apache-tomcat-8.5.55.tar.gz jdk-8u321-linux-x64.tar.gz
[root@192 tomcat]# touch readme.txt
[root@192 tomcat]# ls
apache-tomcat-8.5.55.tar.gz jdk-8u321-linux-x64.tar.gz readme.txt
[root@192 tomcat]#
[root@192 tomcat]# vim Dockerfile
[root@192 tomcat]#
编写dockerfile文件,文件名使用官方命名:Dockerfile ,build的时候会默认寻找当前目录下的文件,不需要使用-f参数指定
FROM centos:7 MAINTAINER tml<22222222@qq.com> COPY readme.txt /usr/local/readme.txt ADD jdk-8u321-linux-x64.tar.gz /usr/local/ ADD apache-tomcat-8.5.55.tar.gz /usr/local/ RUN yum -y install vim ENV MYPATH /usr/local WORKDIR $MYPATH ENV JAVA_HOME /usr/local/jdk1.8.0_321 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.55 ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.55 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin EXPOSE 8080 CMD /usr/local/apache-tomcat-8.5.55/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.55/bin/logs/catalina.out
执行命令构建镜像:docker build -t tml-mydockerfile-tomcat:1.0 .
,执行过程如下:
[root@192 tomcat]# docker build -t tml-mydockerfile-tomcat:1.0 . Sending build context to Docker daemon 157.2MB Step 1/15 : FROM centos:7 ---> eeb6ee3f44bd Step 2/15 : MAINTAINER tml<22222222@qq.com> ---> Running in c0cf98ad1656 Removing intermediate container c0cf98ad1656 ---> 37e75c1c3fbf Step 3/15 : COPY readme.txt /usr/local/readme.txt COPY failed: file not found in build context or excluded by .dockerignore: stat readme.txt: file does not exist [root@192 tomcat]# cd /home [root@192 home]# ls dockerfiles mysql test.java tml-1 tml-not-add.java tomcat volume_centos [root@192 home]# cd tomcat [root@192 tomcat]# touch readme.txt [root@192 tomcat]# docker build -t tml-mydockerfile-tomcat:1.0 . Sending build context to Docker daemon 157.2MB Step 1/15 : FROM centos:7 ---> eeb6ee3f44bd Step 2/15 : MAINTAINER tml<22222222@qq.com> ---> Using cache ---> 37e75c1c3fbf Step 3/15 : COPY readme.txt /usr/local/readme.txt ---> c00a06e0b624 Step 4/15 : ADD jdk-8u321-linux-x64.tar.gz /usr/local/ ---> 7843775f3843 Step 5/15 : ADD apache-tomcat-8.5.55.tar.gz /usr/local/ ---> ca57ff38958c Step 6/15 : RUN yum -y install vim ----------------------------------中间过程省略-------------------------------------------------- Step 7/15 : ENV MYPATH /usr/local ---> Running in 15432f278bd4 Removing intermediate container 15432f278bd4 ---> 90ce935c42b5 Step 8/15 : WORKDIR $MYPATH ---> Running in c218f55f9975 Removing intermediate container c218f55f9975 ---> 0248a9e1fccd Step 9/15 : ENV JAVA_HOME /usr/local/jdk1.8.0_321 ---> Running in 38c4fb4b8ec0 Removing intermediate container 38c4fb4b8ec0 ---> aa704765f66f Step 10/15 : ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ---> Running in 047dc22054b3 Removing intermediate container 047dc22054b3 ---> 45de2f0792a6 Step 11/15 : ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.55 ---> Running in 4be3a29dae94 Removing intermediate container 4be3a29dae94 ---> cb0a033be5cf Step 12/15 : ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.55 ---> Running in a16bb8c663e7 Removing intermediate container a16bb8c663e7 ---> 66bb078fc3e1 Step 13/15 : ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin ---> Running in e86d6426d09f Removing intermediate container e86d6426d09f ---> 69cf63889a88 Step 14/15 : EXPOSE 8080 ---> Running in 0ccebe86d126 Removing intermediate container 0ccebe86d126 ---> d211c04efccb Step 15/15 : CMD /usr/local/apache-tomcat-8.5.55/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.55/bin/logs/catalina.out ---> Running in 2e305079d51f Removing intermediate container 2e305079d51f ---> 94dbe2d0cb91 Successfully built 94dbe2d0cb91 Successfully tagged tml-mydockerfile-tomcat:1.0 [root@192 tomcat]#
这里设置了数据卷,宿主机的/home/tomcat/test
对应该容器的/usr/local/apache-tomcat-8.5.55/webapps/test
。这样关于test项目的修复只需要在宿主机上修改就可以了,不需要进入到容器中修改。
[root@192 test]# docker run -d -p 6680:8080 --name tml-mydockerfile-tomcat-contanier -v /home/tomcat/test:/usr/local/apache-tomcat-8.5.55/webapps/test tml-mydockerfile-tomcat:1.0
08e1e1d3388ed9b9932f727868ffe6d8c027d4b4bbc92042667474e7e6f94ff4
[root@192 test]#
在/home/tomcat/test
的目录下,新建index.html
测试Tomcat是否能正常使用。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>tml,hello</title>
</head>
<body>
<h1>tml 这是你自制的tomcat镜像,访问一下</h1>
<p>恭喜你访问成功</p>
</body>
</html>
可以看到容器内部地址:
[root@192 test]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 08e1e1d3388e tml-mydockerfile-tomcat:1.0 "/bin/sh -c '/usr/lo…" 33 seconds ago Up 31 seconds 0.0.0.0:6680->8080/tcp, :::6680->8080/tcp tml-mydockerfile-tomcat-contanier b4c122ea9c7e nginx "/docker-entrypoint.…" 19 hours ago Up 19 hours 0.0.0.0:49155->80/tcp, :::49155->80/tcp nginx-ro 0b24ae53e7fc nginx "/docker-entrypoint.…" 19 hours ago Up 19 hours 0.0.0.0:49154->80/tcp, :::49154->80/tcp nginx-tml-juming a872a0802014 nginx "/docker-entrypoint.…" 19 hours ago Up 19 hours 0.0.0.0:49153->80/tcp, :::49153->80/tcp nginx-tml-volume 33fe5e65f769 mysql:5.7 "docker-entrypoint.s…" 24 hours ago Up 24 hours 33060/tcp, 0.0.0.0:6603->3306/tcp, :::6603->3306/tcp mysql-5.7-tml 78664208a245 portainer/portainer "/portainer" 8 days ago Up 7 days 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp thirsty_gauss 2f59536a92da tomcat "catalina.sh run" 8 days ago Up 7 days 0.0.0.0:3335->8080/tcp, :::3335->8080/tcp tomcat-tml [root@192 ~]# docker exec -it 08e1e1d3388e /bin/bash [root@f2dd05532e5f local]# ls readme.txt [root@f2dd05532e5f local]# cd .. [root@f2dd05532e5f user]# ls local [root@f2dd05532e5f user]# cd .. [root@f2dd05532e5f /]# ls anaconda-post.log dev home lib64 mnt proc run srv tmp usr bin etc lib media opt root sbin sys user var [root@f2dd05532e5f /]# cd /usr [root@f2dd05532e5f usr]# ls bin etc games include lib lib64 libexec local sbin share src tmp [root@f2dd05532e5f usr]# cd local [root@f2dd05532e5f local]# ls apache-tomcat-8.5.55 etc include lib libexec share bin games jdk1.8.0_321 lib64 sbin src [root@f2dd05532e5f local]# cd apache-tomcat-8.5.55/ [root@f2dd05532e5f apache-tomcat-8.5.55]# ls BUILDING.txt LICENSE README.md RUNNING.txt conf logs webapps CONTRIBUTING.md NOTICE RELEASE-NOTES bin lib temp work [root@f2dd05532e5f apache-tomcat-8.5.55]# cd webapps/ [root@f2dd05532e5f webapps]# ls ROOT docs examples host-manager manager test [root@f2dd05532e5f webapps]# cd test/ [root@f2dd05532e5f test]# ls index.html [root@f2dd05532e5f test]#
访问下容器看看效果,页面请求:
登录DockerHub官网进行注册,因为之前我已经注册过了,所以这里直接登录:
[root@192 ~]# docker login -u tianmaolin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
[root@192 ~]#
登录后直接进行推送即可,使用docker push命令推送镜像到DockerHub上的仓库
[root@192 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE tml-mydockerfile-tomcat 1.0 94dbe2d0cb91 15 minutes ago 799MB tml-dockerfile-tomcat 1.0 2a1bbcae34bf About an hour ago 799MB tml-entrypoint-test 0.1 79cf0d9a1240 2 hours ago 204MB tml-cmd-test 0.1 2b54bee0bae6 2 hours ago 204MB my-centos-image 0.1 e4e087ce52a3 6 hours ago 580MB <none> <none> 55ac5aa9c06f 6 hours ago 231MB mytomcat 1.0 251e3ac9aff1 7 days ago 684MB nginx latest 605c77e624dd 8 weeks ago 141MB tomcat latest fb5657adc892 2 months ago 680MB mysql 5.7 c20987f18b13 2 months ago 448MB mysql latest 3218b38490ce 2 months ago 516MB hello-world latest feb5d9fea6a5 5 months ago 13.3kB centos 7 eeb6ee3f44bd 5 months ago 204MB centos latest 5d0da3dc9764 5 months ago 231MB portainer/portainer latest 580c0e4e98b0 11 months ago 79.1MB elasticsearch 7.6.2 f29a1ee41030 23 months ago 791MB elasticsearch latest 5acf0e8da90b 3 years ago 486MB [root@192 ~]# docker tag 94dbe2d0cb91 tianmaolin/tml-mydockerfile-tomcat:1.0 [root@192 ~]# docker push tianmaolin/tml-mydockerfile-tomcat:1.0 The push refers to repository [docker.io/tianmaolin/tml-mydockerfile-tomcat] ac01855d7d2a: Pushed c7e4d1ddfc26: Pushed 38ed04c6f8af: Pushed 6b9f15b17790: Pushed 174f56854903: Mounted from library/centos 1.0: digest: sha256:d829761d327aea380c934da8c58873843cfe0e1872d5cdb958afc2557b268db0 size: 1373 [root@192 ~]#
因为push的时候,镜像名前面需要加上用户名(tianmaolin,如果用户名不是当前登录用户则会拒绝push请求),所以需要使用命令docker tag 镜像名 新的镜像名复制出一份镜像重新打个Tag,访问dockerhub可以看到镜像已经推送完成了:
可以看到该镜像的layer:
FROM的基础镜像其实是引用了三层layer,所以镜像从另一种意义上看是一组指令集合。
梳理下各个概念,其实Dockerfile就是一个镜像编排蓝图,把一个镜像Dockerimage的整体结构编排出来,编排出来后可以基于该镜像进行容器运行,容器里的数据目录可以映射挂载到宿主机的磁盘地址。镜像为一个只读文件系统,容器为基于镜像的读写层,通过commit命令可以将镜像和基于该镜像的容器二次制作一个新镜像,自己编写制作的镜像也可以推送到DockerHub供别人下载使用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。