当前位置:   article > 正文

【Docker学习笔记 六】Dockerfile文件详解与镜像发布_docker容器里的文件是根据什么进行生成的

docker容器里的文件是根据什么进行生成的

上一篇Blog我们学习了容器数据卷,了解了容器的数据持久化机制,本篇Blog延续之前的镜像原理【Docker学习笔记 四】深入理解Docker镜像原理,继续进行学习,之前了解过:使用docker commit 命令提交容器成为一个新的版本,本篇Blog我们来继续看看image究竟是怎么构建出来的,依据什么文件构建的。

Dockerfile基本概念

通俗的说Dockerfile就是绘制镜像image的蓝图。我们可以从dockerhub进去搜索centos我们可以看到centos的镜像,然后跳转到github主页查看镜像构建的文件:
在这里插入图片描述
在github主页我们可以看到centos的构建过程,也就是今天的主角:dockerfile。
在这里插入图片描述

dockerfile常用指令

我们就是依据如下指令来进行dockerfile文件编写的:
在这里插入图片描述
Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令容器启动时执行指令,’#’ 为 Dockerfile 中的注释。

  • 每个保留关键字(指令)都必须是大写字母
  • 文件中的指令从上到下顺序执行,第一个指令必须是FROM
  • 每一个指令都会创建提交一个新的镜像层,并提交!

关于Dockerfile指令的详细语法解释:Dockerfile文件详解Dockerfile指令介绍的官方文档,接下来我们亲手构建一个dockerfile文件:

概念结构辨析

现在我们梳理下docker学习以来的各个概念

  1. dockerfile文件:镜像文件,制作镜像的蓝图,通过一行行指令标识镜像的实现过程
  2. dockerimage镜像:依据镜像文件build出来的镜像
  3. 容器:依据镜像运行的容器实例,镜像只读顶端的读写层

三个概念是自底向上的,联动前面学到的知识,其实dockerfile就是layer镜像层的编排设计图,通过这个设计图编排出一个个镜像,镜像是一个只读的使用联合文件系统的概念,顶端的容器就是读写的一个文件路径。所以镜像里的layer并不是image,这也就解释了我之前的困惑:难道镜像之间有依赖关系,删除一个镜像会影响另一个?其实镜像是基于layer构建的,而不是别的镜像,而layer可以理解为一行指令,删除镜像理解为只是删除了一个联合文件系统构建出来的一个目录包,并不会真的删除指令构建的文件,所以也不会影响别的镜像的使用

依据dockerfile制作centos镜像

官方的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 /]# 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

下面通过编写Dockerfile文件来制作Centos镜像,并在官方镜像的基础上添加vim和net-tools工具。首先在/home/dockfile 目录下新建文件mydockerfile-centos。然后使用上述指令编写该文件

1 编写dockerfile文件

首先我们找到一个目录地址存放自己的镜像文件:

[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
  • 1
  • 2
  • 3
  • 4

然后编写镜像文件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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

逐行解释该Dockerfile文件的指令:

  • FROM centos:该image文件继承官方的centos,后面加冒号如centos:7,用于指定镜像的版本
  • ENV MYPATH /usr/local:设置环境变量MYPATH ,后面有用到
  • WORKDIR $MYPATH:直接使用上面设置的环境变量,指定/usr/local为工作目录
  • RUN yum -y install vimRUN 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的所有包。

2 依据dockerfile构建dockerimage镜像

通过这个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]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

3 依据dockerimage镜像启动容器

查看自己构造的镜像并依据自己编写的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]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

可以看到现在该centos具备了vim命令能力并应用了我们配置的目录

4 查看镜像构建过程

实际上就是查看构造该镜像的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.co0B        
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]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

还可以从我们的docker可视化面板看的更详细些,包括镜像的基本信息
在这里插入图片描述
以及镜像的镜像文件细节和镜像层信息:
在这里插入图片描述

RUN,CMD和ENTRYPOINT的区别

RUN命令与CMD命令的区别在哪里?简单说,RUN命令在 image 文件的构建阶段执行,执行结果都会打包进入 image 文件;CMD命令则是在容器启动后执行。另外,一个 Dockerfile 可以包含多个RUN命令,但是只能有一个CMD命令(或者可以有多个CMD,但是只有最后一个CMD生效)。注意,指定了CMD命令以后,docker container run命令就不能附加命令了(比如前面的/bin/bash),否则它会覆盖CMD命令。CMD和ENTRYPOINT的区别

  • CMD :指定容器启动的时候要运行的命令,只有最后一个会生效,如果启动时run附加了命令,则CMD的自动无效
  • ENTRYPOINT :指定容器启动的时候要运行的命令,命令可以追加,如果启动时run附加了命令,则会追加到ENTRYPOINT 后执行

分别看下两个的示例,注意-l :详细信息显示,是ls命令的子选项

1 CMD命令测试实践

创建dockerfile文件tml-dockerfile-cmd

[root@192 dockerfiles]# ls
tml-dockerfile-centos
[root@192 dockerfiles]# vim tml-dockerfile-cmd
  • 1
  • 2
  • 3

编辑dockerfile文件tml-dockerfile-cmd

FROM centos:7
ENTRYPOINT ["ls","-a"]
  • 1
  • 2

依据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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

依据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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

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]# 
  • 1
  • 2
  • 3

再测试下末尾加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]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

2 ENTRYPOINT 命令测试实践

创建dockerfile文件tml-dockerfile-entrypoint-test

[root@192 dockerfiles]# ls
tml-dockerfile-centos  tml-dockerfile-cmd
[root@192 dockerfiles]# vim tml-dockerfile-entrypoint-test
  • 1
  • 2
  • 3

编辑dockerfile文件tml-dockerfile-entrypoint-test

FROM centos:7
ENTRYPOINT ["ls","-a"]
  • 1
  • 2

依据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]#
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

依据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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

然后我们在命令后边继续追加-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]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

Dockerfile中设置数据卷

我们可以在Dockerfile中使用VOLUME指令来给镜像添加一个或多个数据卷。下面使用Dockerfile构建一个新的镜像,dockerfile01文件的内容,匿名挂载了volume01和volume02两个目录:

FROM centos:7
VOLUME ["volume01","volume02"]

CMD echo "----end----"
CMD /bin/bash
  • 1
  • 2
  • 3
  • 4
  • 5

执行构建镜像:

[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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

完成镜像的生成后,启动自己生成的容器

[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 /]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

可以看到自动挂载的数据卷目录。下面查看对应宿主机的数据卷目录:

    "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": ""
            }
        ],
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

可以看到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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

宿主机增加文件

[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]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

依据当前镜像和容器提交一个新镜像

[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 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

依据新镜像运行容器并查看容器数据卷目录

[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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

可以看到并没有a.java文件,但是var文件夹创建上了,同时查看下该容器元数据

 "Mounts": [],
  • 1

由此可见volume数据卷是独立于联合文件系统的。

依据dockerfile制作tomcat镜像并发布

按照如下步骤进行tomcat镜像制作及发布:

1 准备本地的压缩包文件

使用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]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2 创建一个dockerfile文件

[root@192 tomcat]# vim Dockerfile
[root@192 tomcat]#
  • 1
  • 2

3 编写dockerfile文件

编写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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

4 使用该Dockerfile构建镜像

执行命令构建镜像: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]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

5 启动生成的镜像,构建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]# 
  • 1
  • 2
  • 3

/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>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

可以看到容器内部地址:

[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]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

6 容器访问测试

访问下容器看看效果,页面请求:

在这里插入图片描述

7 发布镜像到DockerHub

登录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 ~]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

登录后直接进行推送即可,使用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 ~]# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

因为push的时候,镜像名前面需要加上用户名(tianmaolin,如果用户名不是当前登录用户则会拒绝push请求),所以需要使用命令docker tag 镜像名 新的镜像名复制出一份镜像重新打个Tag,访问dockerhub可以看到镜像已经推送完成了:
在这里插入图片描述
可以看到该镜像的layer:
在这里插入图片描述
FROM的基础镜像其实是引用了三层layer,所以镜像从另一种意义上看是一组指令集合。
在这里插入图片描述

总结一下

梳理下各个概念,其实Dockerfile就是一个镜像编排蓝图,把一个镜像Dockerimage的整体结构编排出来,编排出来后可以基于该镜像进行容器运行,容器里的数据目录可以映射挂载到宿主机的磁盘地址。镜像为一个只读文件系统,容器为基于镜像的读写层,通过commit命令可以将镜像和基于该镜像的容器二次制作一个新镜像,自己编写制作的镜像也可以推送到DockerHub供别人下载使用。
在这里插入图片描述

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/73922
推荐阅读
相关标签
  

闽ICP备14008679号