Docker---dockerfile文件详解1(续前)

文章目录

    • 利用dockerfile创建镜像
    • 缓存特性
    • dockerfile常用指令
      • shell 和 exec两种书写格式

利用dockerfile创建镜像

1.创建一个Dockerfile
注意:一定要创建一个新的目录 因为在构建镜像的时候,会默认把dockerfile所在的目录中的所有目录发送给docker引擎,举个例子 如果你把dockerfile放在/目录下 那么这个过程会变得非常的缓慢

[root@server3 mnt]# mkdir /mnt/docker
[root@server3 mnt]# cd docker/
[root@server3 docker]# ls
[root@server3 docker]# vim dockerfile
FROM busybox 	 #以哪个基础镜像为模板
RUN echo testfile > file1 #在新镜像中你要执行的哪些动作
RUN echo testfile > file2

创建镜像

[root@server3 docker]# docker build -t test:v2 #镜像名称 . 代表当前目录

Sending build context to Docker daemon 2.048 kB #把dockerfile所在的目录中的所有目录发送给docker引擎
Step 1/3 : FROM busybox
 ---> db8ee88ad75f
Step 2/3 : RUN echo testfile > file1
 ---> Running in 4c00ef6f0753
 ---> e8a1fbac8837
Removing intermediate container 4c00ef6f0753 #临时镜像层删掉
Step 3/3 : RUN echo testfile > file2
 ---> Running in cd7a46bb3269
 ---> 5fc404485b27
Removing intermediate container cd7a46bb3269
Successfully built 5fc404485b27
  • 查看刚刚镜像有没有创建成功
[root@server3 docker]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
test                v2                  5fc404485b27        About a minute ago   1.22 MB
test                v1                  c1a9c80bccb0        19 minutes ago       1.22 MB
ubuntu              latest              3556258649b2        2 weeks ago          64.2 MB
busybox             latest              db8ee88ad75f        3 weeks ago          1.22 MB
game2048            latest              19299002fdbe        2 years ago          55.5 MB
  • 查看镜像
[root@server3 docker]# docker history test:v2
IMAGE               CREATED              CREATED BY                                      SIZE                COMMENT
5fc404485b27        About a minute ago   /bin/sh -c echo testfile > file2                9 B                 
e8a1fbac8837        About a minute ago   /bin/sh -c echo testfile > file1                9 B                 
db8ee88ad75f        3 weeks ago          /bin/sh -c #(nop)  CMD ["sh"]                   0 B                 
           3 weeks ago          /bin/sh -c #(nop) ADD file:9ceca008111a4dd...   1.22 MB
[root@server3 docker]# docker history busybox:latest
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
db8ee88ad75f        3 weeks ago         /bin/sh -c #(nop)  CMD ["sh"]                   0 B                 
           3 weeks ago         /bin/sh -c #(nop) ADD file:9ceca008111a4dd...   1.22 MB 

缓存特性

再次更改dockerfile 注意:不要随便加空格(要使用缓存 之前内容不能随便更改)

[root@server3 docker]# cat dockerfile 
FROM busybox
RUN echo testfile > file1
RUN echo testfile > file2
RUN echo testfile > file3
  • 再次build一个镜像,会出现Using cache ,已经缓存过的不会再缓存了
[root@server3 docker]# docker build -t test:v3 .
Sending build context to Docker daemon 2.048 kB
Step 1/4 : FROM busybox
 ---> db8ee88ad75f
Step 2/4 : RUN echo testfile > file1
 ---> Using cache  					#已经运行过的不再运行
 ---> e8a1fbac8837
Step 3/4 : RUN echo testfile > file2
 ---> Using cache
 ---> 5fc404485b27
Step 4/4 : RUN echo testfile > file3
 ---> Running in e2e4d6f4c565  #运行新的指令
 ---> edd40df71d11
Removing intermediate container e2e4d6f4c565
Successfully built edd40df71d11

说明

  • 如果我们希望在构建镜像时不使用缓存,可以在docker build命令中加上 --no-cache参数
  • dockerfile中每一个指令都会创建一个镜像层,上层是依赖于下层的,无论什么时候,只要某一层发生变化,其上面所有层的缓存都会失败
  • 对比来看 v2和v3 有几层是一样的 每一个RUN就会构建一层镜像
  • 而且我们可以看到 每一层的操作,再次说明 共同的镜像层之间的共享的
[root@server3 docker]# docker history test:v3
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
edd40df71d11        52 seconds ago      /bin/sh -c echo testfile > file3                9 B                 
5fc404485b27        6 minutes ago       /bin/sh -c echo testfile > file2                9 B                 
e8a1fbac8837        6 minutes ago       /bin/sh -c echo testfile > file1                9 B                 
db8ee88ad75f        3 weeks ago         /bin/sh -c #(nop)  CMD ["sh"]                   0 B                 
           3 weeks ago         /bin/sh -c #(nop) ADD file:9ceca008111a4dd...   1.22 MB             
[root@server3 docker]# docker history test:v2
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
5fc404485b27        6 minutes ago       /bin/sh -c echo testfile > file2                9 B                 
e8a1fbac8837        6 minutes ago       /bin/sh -c echo testfile > file1                9 B                 
db8ee88ad75f        3 weeks ago         /bin/sh -c #(nop)  CMD ["sh"]                   0 B                 
           3 weeks ago         /bin/sh -c #(nop) ADD file:9ceca008111a4dd...   1.22 MB  

本质:dockerfile中的每一层其实就是执行了一个docker commit

dockerfile常用指令

以下详细介绍dockerfile的一些常用指令 ,便于我们书写更成熟的dockerfile文件

  • FROM:指定base镜像,如果本地不存在会从远程仓库下载(虚拟机要配置上网)
  • MAINTAINER:设置镜像的作者,比如用户邮箱等 (不是必须的)
  • COPY:把文件从build context复制到镜像
    支持两种形式:COPY src dest 和 COPY [“src”,“dest”]
    src必须指定build context中的文件或目录
  • 书写dockerfile
[root@server3 docker]# vim dockerfile
	FROM busybox
	COPY testfile /tmp
  • 编辑所要复制的文档
[root@server3 docker]# vim testfile
	hello~
  • bulid镜像并进行查看
 [root@server3 docker]# docker build -t test:v4 .
	Sending build context to Docker daemon 3.072 kB
	Step 1/2 : FROM busybox
	 ---> db8ee88ad75f
	Step 2/2 : COPY testfile /tmp
	 ---> ff437a8d3732
	Removing intermediate container e79887133199
	Successfully built ff437a8d3732
[root@server3 docker]# docker history test:v4
	IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
	ff437a8d3732        9 seconds ago       /bin/sh -c #(nop) COPY file:d93a5a916d7ae8...   7 B                 
	db8ee88ad75f        3 weeks ago         /bin/sh -c #(nop)  CMD ["sh"]                   0 B                 
	           3 weeks ago         /bin/sh -c #(nop) ADD file:9ceca008111a4dd...   1.22
  • 查看是否COPY成功
[root@server3 docker]# docker run -it --name vm1 test:v4
	/ # ls
	bin   dev   etc   home  proc  root  sys   tmp   usr   var
	/ # cd /tmp/
	/tmp # ls
	testfile
	/tmp # cat testfile 
	hello~

建议:不用的容器和镜像,要即使删除

  • ADD:用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以下载URL并拷贝到镜像
eg:ADD html.tar /var/www
	   ADD http://ip/html.tar /var/www
scp [email protected]:/mnt/nginx/nginx-1.17.4.tar.gz .
  • 演示,编辑dockerfile
[root@server3 docker]# vim dockerfile
FROM busybox
COPY testfile /tmp
ADD nginx-1.15.9.tar.gz /tmp
  • bulid新镜像
[root@server3 docker]# docker build -t test:v5 .
Sending build context to Docker daemon 1.036 MB
Step 1/3 : FROM busybox
 ---> db8ee88ad75f
Step 2/3 : COPY testfile /tmp
 ---> Using cache
 ---> ff437a8d3732
Step 3/3 : ADD nginx-1.15.9.tar.gz /tmp
 ---> 9db2ad29e44f
Removing intermediate container f84d556d43dc
Successfully built 9db2ad29e44f
  • 验证是否ADD成功
[root@server3 docker]# docker run -it --name vm2 test:v5 

/ # cd /tmp/
/tmp # ls
nginx-1.15.9  testfile
/tmp # cd nginx-1.15.9/
/tmp/nginx-1.15.9 # ls
CHANGES     README      configure   man
CHANGES.ru  auto        contrib     src
LICENSE     conf        htm
  • ENV:设置环境变量,变量可以被后续的指令使用(不是必须的)
    ENV HOSTNAME server1.example.com
  • EXPOSE:如果容器运行应用服务,可以把服务的端口暴露出去
[root@server3 docker]# docker history game2048
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
19299002fdbe        2 years ago         /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "se...   0 B                 
           2 years ago         /bin/sh -c #(nop)  EXPOSE 80/ tcp                0 B                   # 服务的端口暴露出去 方便我们去做端口映射和用户在容器启动后去访问的
           2 years ago         /bin/sh -c #(nop) COPY dir:cb74e9c037a3d50...   600 kB              
           2 years ago         /bin/sh -c #(nop)  MAINTAINER Golfen Guo <...   0 B                 
           2 years ago         /bin/sh -c #(nop)  CMD ["nginx" "-g" "daem...   0 B                 
           2 years ago         /bin/sh -c #(nop)  EXPOSE 443/tcp 80/tcp        0 B                 
           2 years ago         /bin/sh -c #(nop) COPY file:d15ceb73c6ea77...   1.1 kB              
           2 years ago         /bin/sh -c #(nop) COPY file:af94db45bb7e4b...   643 B               
           2 years ago         /bin/sh -c GPG_KEYS=B0F4253373F8F6F510D421...   50.1 MB             
           2 years ago         /bin/sh -c #(nop)  ENV NGINX_VERSION=1.11.7     0 B                 
           2 years ago         /bin/sh -c #(nop)  MAINTAINER NGINX Docker...   0 B                 
           2 years ago         /bin/sh -c #(nop) ADD file:7afbc23fda8b0b3...   4.8 MB    
  • VOLUME:申明数据卷,通常指定的是应用的数据挂载点
    目的:容器数据持久化的

  • 在dockerfile中加VOLUME ["/data"]

[root@server3 docker]# vim dockerfile 
FROM busybox
COPY testfile /tmp
ADD nginx-1.15.9.tar.gz /tmp
VOLUME ["/data"] #在启动容器的时候会帮我们自动的新建
  • 新建一个镜像
[root@server3 docker]# docker build -t test:v6 .
Sending build context to Docker daemon 1.036 MB
Step 1/4 : FROM busybox
 ---> db8ee88ad75f
Step 2/4 : COPY testfile /tmp
 ---> Using cache
 ---> ff437a8d3732
Step 3/4 : ADD nginx-1.15.9.tar.gz /tmp
 ---> Using cache
 ---> 9db2ad29e44f
Step 4/4 : VOLUME /data
 ---> Running in 5f03d4efc260
 ---> 680a9d07e8e9
Removing intermediate container 5f03d4efc260
Successfully built 680a9d07e8e9
  • 运行容器
[root@server3 docker]# docker run -it --name vm2 test:v6
/ # ls
bin   dev   home  root  tmp   var
data  etc   proc  sys   usr
/ # cd data/
  • 我们可以通过docker inspect 6a8af9225428 (镜像ID)这个命令看到
    容器中的/data目录与宿主机上的一个新建的本地目录发生了联系
docker inspect 6a8af9225428

"Mounts": [
            {
                "Type": "volume",
                "Name": "54322e71d6257057e0b785efdfa5853a53422a287048780753fba37df3a2470b",
                "Source": "/var/lib/docker/volume/54322e71d6257057e0b785efdfa5853a53422a287048780753fba37df3a2470b/_data",
  • 在宿主机中,进入到这个目录中去cd var/lib/docker/volume/54322e71d6257057e0b785efdfa5853a53422a287048780753fba37df3a2470b/_data
    注意:此目录是docker引擎自动帮我们创建出来的 目录名是随机生成的
[root@server3 /]# cd /var/lib/docker/volumes/54322e71d6257057e0b785efdfa5853a53422a287048780753fba37df3a2470b/_data
[root@server3 _data]# ls
[root@server3 _data]# touch file1
[root@server3 _data]# touch file2
[root@server3 _data]# docker attach vm2
/ # cd /data/
/data # ls
file1  file2
/data # rm -rf file1
/data # exit
[root@server3 _data]# ls
file2
  • WOEKDIR:为RUN CMD ENTRYPOINT ADD COPY 指令设置镜像中的当前工作目录(类似于cd ),如果目录不存在会自动创建
  • RUN:在容器中运行命令并创建新的镜像层,常用于安装包
    每一个RUN指令都会构建一层镜像层 尽可能将 多个命令放在一个RUN指令下RUN yum install -y vim
  • CMDENTRYPOINT:这两个指令都是用于设置容器启动后执行的命令
    CMD会被docker run后面的命令覆盖,而ENTRYPOINT不会被忽略,一定会被执行
    docker run后面的参数可以传递给ENTRYPOINT指令当作参数 dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效
    CMD与ENTRYPOINT(容器启动后要运行的!!)
    RUN :在创建容器的时候!!!(在容器中)

shell 和 exec两种书写格式

  • shell方式
[root@server3 docker]# cat dockerfile  
FROM busybox
ENV name world #ENV:定义变量
ENTRYPOINT echo "hello,$name"
[root@server3 docker]# docker build -t test:v8 .
Sending build context to Docker daemon 1.036 MB
Step 1/3 : FROM busybox
 ---> db8ee88ad75f
Step 2/3 : ENV name world
 ---> Using cache
 ---> 9771be0e3225
Step 3/3 : ENTRYPOINT /bin/echo hello,$name
 ---> Running in 6bc8e3d7e2d8
 ---> 77cecb1b6c1c
Removing intermediate container 6bc8e3d7e2d8
Successfully built 77cecb1b6c1c
  • 发现问题 变量无法被解析
[root@server3 docker]# docker run --rm test:v8
hello,$name
  • exec的方式
 [root@server3 docker]# cat dockerfile #
FROM busybox
ENV name world
ENTRYPOINT ["/bin/echo","hello,$name"]

shell格式底层会掉用/bin/sh -c 来执行命令,可以解析变量,而exec格式不会

[root@server3 docker]# docker build -t test:v9 .
Sending build context to Docker daemon 1.036 MB
Step 1/3 : FROM busybox
 ---> db8ee88ad75f
Step 2/3 : ENV name world
 ---> Using cache
 ---> 9771be0e3225
Step 3/3 : ENTRYPOINT /bin/sh -c echo hello,$name
 ---> Running in 5ab8da5fc8ca
 ---> 6f26d3c56e7e
Removing intermediate container 5ab8da5fc8ca
Successfully built 6f26d3c56e7e

exec格式时,ENTRYPOINT可以通过CMD提供的额外参数,CMD的额外参数可以在容器启动时动态替换,在shell格式时ENTRYPOINT会忽略任何CMD或docker run提供的参数

[root@server3 docker]# docker run --rm test:v10
hello world
  • 比较CMDENTRYPOINT
[root@server3 docker]# cat dockerfile 
FROM busybox
ENTRYPOINT ["/bin/echo","hello"]
CMD ["world"]

验证

[root@server3 docker]# docker run --rm test:v10 westos
hello westos
# westos 覆盖了dockerfile CMD后面的值

你可能感兴趣的:(Docker---dockerfile文件详解1(续前))