本文共 7752 字,大约阅读时间需要 25 分钟。
Dockerfile要点:
- 每个保留关键字(指令)都必须是大写字母
- 执行从上到下顺序执行
- # 表示注释
- 每一个指令都会创建提交一个新的镜像层,并提交!
- 默认的名字叫Dockerfile
docker build [OPTIONS] PATH | URL | -# OPTIONS说明:# 常用指令-f :指定要使用的Dockerfile路径--tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签-m :设置内存最大值--memory-swap :设置Swap的最大值为内存+swap,"-1"表示不限swap--no-cache :创建镜像的过程不使用缓存# 不常用指令--build-arg=[] :设置镜像创建时的变量;--cpu-shares :设置 cpu 使用权重;--cpu-period :限制 CPU CFS周期;--cpu-quota :限制 CPU CFS配额;--cpuset-cpus :指定使用的CPU id;--cpuset-mems :指定使用的内存 id;--disable-content-trust :忽略校验,默认开启;--force-rm :设置镜像过程中删除中间容器;--isolation :使用容器隔离技术;--label=[] :设置镜像使用的元数据;--pull :尝试去更新镜像的新版本;--quiet, -q :安静模式,成功后只输出镜像 ID;--rm :设置镜像成功后删除中间容器;--shm-size :设置/dev/shm的大小,默认值是64M;--ulimit :Ulimit配置。--squash :将 Dockerfile 中所有的操作压缩为一层。--network: 默认 default。在构建期间设置RUN指令的网络模式
以下部分为了说明一些基础知识,用一个带小bug的案例说明情况,请看:
Dockerfile文件:
FROM centos:7MAINTAINER alien<1246381208@qq.com>ENV MYPATH /usr/localWORKDIR $MYPATHRUN yum -y install vimRUN yum -y install net-toolsEXPOSE 80CMD echo "=========="$MYPATH # 测试用一CMD echo "-----end----" # 测试用二# 如上共计9行
docker build 过程:
由于整个构建的过程代码很多,为了说明构建的过程,构建完镜像我再次构建一次的效果如下:
[root@10-23-51-219 test_Dockerfile]# docker build -f Dockerfile -t centos7-alien:2.0 .Sending build context to Docker daemon 2.048 kBStep 1/9 : FROM centos:7 ---> 8652b9f0cb4c # 第一层 Step 2/9 : MAINTAINER alien<1246381208@qq.com> ---> Using cache ---> e5f09b2c0e76 # 第二层 Step 3/9 : ENV MYPATH /usr/local ---> Using cache ---> 746f48b75dc7 # 第三层 Step 4/9 : WORKDIR $MYPATH ---> Using cache ---> 51ee86a6e9b1 # 第四层 Step 5/9 : RUN yum -y install vim ---> Using cache ---> 3bd41f128dd2 # 第五层 Step 6/9 : RUN yum -y install net-tools ---> Using cache ---> 08267a736ea4 Step 7/9 : EXPOSE 80 ---> Using cache ---> 96719f926d4f Step 8/9 : CMD echo "=========="$MYPATH ---> Using cache ---> b4e0ae22d337 Step 9/9 : CMD echo "-----end----" ---> Using cache ---> 2f1e984f53e7 # 第九层Successfully built 2f1e984f53e7# 2f1e984f53e7 这个就是最终创建的镜像id# Dockerfile中,每一行最终会生成一层镜像
[root@10-23-51-219 test_Dockerfile]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEcentos7-alien 2.0 2f1e984f53e7 3 minutes ago 460 MB
注意事项:
- 如上构建过程发现, 如果本地有缓存的镜像层,就直接使用缓存构建了,就不用再去网上下载了。
- 而镜像的构建的代码从上向下执行的, 所以我们尽可能把不常变动的构建语句放在前面几句。后续构建脚本更新的时候,最初生成的几层镜像也不会跟着变,构建效率就会很高!而如果中途有一个镜像层变动了,下面镜像层也会跟着变动。
启动容器:
docker run -it -d --name centos7-alien-1 centos7-alien:2.0 /bin/bash[root@10-23-51-219 test_Dockerfile]# docker inspect 07c7ff0cbf54 | grep -C 5 Cmd "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "MYPATH=/usr/local" ], "Cmd": [ "/bin/bash" ], "Image": "centos7-alien:2.0", "Volumes": null, "WorkingDir": "/usr/local",
CMD命令的特点:
- 在Dockerfile中,我设置了2条CMD命令,也出现了2个镜像层
- 但是,在运行容器的时候,我使用的是/bin/bash命令,最终查看容器详情的时候发现,只有/bin/bash起作用了!说明docker run 中的容器参数会覆盖cmd中的参数
如下命令之前,先停止并删除了centos7-alien-1容器,然后启动centos7-alien-2容器
# 注意:此处命令最后没有添加/bin/bash[root@10-23-51-219 test_Dockerfile]# docker run -it -d --name centos7-alien-2 centos7-alien:2.060b6d191250cff2e0152a118d310463806894941ed0e5d14b2f65d257ad2de05[root@10-23-51-219 test_Dockerfile]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES60b6d191250c centos7-alien:2.0 "/bin/sh -c 'echo ..." About a minute ago Exited (0) About a minute ago centos7-alien-2[root@10-23-51-219 test_Dockerfile]#[root@10-23-51-219 test_Dockerfile]# docker start 60b6d191250c60b6d191250c[root@10-23-51-219 test_Dockerfile]#[root@10-23-51-219 test_Dockerfile]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES60b6d191250c centos7-alien:2.0 "/bin/sh -c 'echo ..." 2 minutes ago Exited (0) 2 seconds ago centos7-alien-2[root@10-23-51-219 test_Dockerfile]#[root@10-23-51-219 test_Dockerfile]#[root@10-23-51-219 test_Dockerfile]# docker logs 60b6d191250c-----end---------end----[root@10-23-51-219 test_Dockerfile]# docker inspect 60b6d191250c | grep -A 5 Cmd "Cmd": [ "/bin/sh", "-c", "echo \"-----end----\"" ], "ArgsEscaped": true,
CMD命令的特点:
- 在Dockerfile文件中,有2个CMD命令,构建完的镜像发现也没有启动成功,查看日志发现只有最后一个CMD命令生效了
- 说明CMD命令在Dockerfile中,只有最后一个会生效
- 容器启动的时候,最终需要执行/bin/bash才能正常启动,否者启动不了
Dockerfile文件:
FROM centos:7MAINTAINER alien<1246381208@qq.com>ENV MYPATH /usr/localWORKDIR $MYPATHRUN yum -y install vimRUN yum -y install net-toolsEXPOSE 80CMD /bin/bash# 如上共计8行
docker build 过程:
[root@10-23-51-219 test_Dockerfile]# docker build -f Dockerfile -t centos7-alien:latest .Sending build context to Docker daemon 2.048 kBStep 1/8 : FROM centos:7 ---> 8652b9f0cb4c Step 2/8 : MAINTAINER alien<1246381208@qq.com> ---> Using cache ---> e5f09b2c0e76 Step 3/8 : ENV MYPATH /usr/local ---> Using cache ---> 746f48b75dc7 Step 4/8 : WORKDIR $MYPATH ---> Using cache ---> 51ee86a6e9b1 Step 5/8 : RUN yum -y install vim ---> Using cache ---> 3bd41f128dd2 Step 6/8 : RUN yum -y install net-tools ---> Using cache ---> 08267a736ea4 Step 7/8 : EXPOSE 80 ---> Using cache ---> 96719f926d4f Step 8/8 : CMD /bin/bash ---> Running in 5d504cf52964 ---> be219b51af65 Removing intermediate container 5d504cf52964Successfully built be219b51af65
启动容器的过程:
# 注意,此处没有添加/bin/bash# 因为在容器中已经添加了/bin/bashroot@10-23-51-219 test_Dockerfile]# docker run -it -d centos7-alien:latestf4e02fbb79acc632ad6ccd51f583cf4f46a41321bf498a3ebdd1bf8f1510a155[root@10-23-51-219 test_Dockerfile]#[root@10-23-51-219 test_Dockerfile]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESf4e02fbb79ac centos7-alien:latest "/bin/sh -c /bin/bash" 13 seconds ago Up 12 seconds 80/tcp admiring_babbage60b6d191250c centos7-alien:2.0 "/bin/sh -c 'echo ..." 18 minutes ago Exited (0) 16 minutes ago centos7-alien-2[root@10-23-51-219 test_Dockerfile]#[root@10-23-51-219 test_Dockerfile]#[root@10-23-51-219 test_Dockerfile]# docker inspect f4e02fbb79ac | grep -A 5 Cmd "Cmd": [ "/bin/sh", "-c", "/bin/bash" ], "ArgsEscaped": true,
CMD:
- 配置容器默认的启动参数,可以被docker run提供的参数覆盖。
- 每个dockerfile只能有一个,当有多个CMD时,只有最后一个起效,即构建镜像只能执行一条CMD命令。
ENTRYPOINT:
- 配置容器启动后执行的命令,不可被docker run提供的参数覆盖。
- 每个dockerfile中只能有一个,当有多个ENTRYPOINT时,只有最后一个起效,即构建镜像只能执行一条ENTRYPOINT命令。
ENTRYPOINT和CMD可以配合使用,比如:
ENTRYPOINT ["/usr/sbin/sshd"] CMD ["-D"]
在Docker Daemon模式下,无论你是使用ENTRYPOINT还是CMD,但最后一个必须是一直运行的命令,这样可以防止在命令执行完成后容器退出。
个人理解:
- /bin/bash 命令就是那个启动后一直运行的命令,这个仅在非项目的容器中(如centos、nginx、tomcat类似这种镜像)
- 如果是python或java项目,最后需要执行一个启动的项目的命令,就不需要/bin/bash了
ADD命令:
- ADD主要用于将宿主机中目标路径的文件添加到镜像指定路径中。
- 宿主机路径可以是Dockerfile所在目录的一个相对路径。
- 还可以是一个tar文件,ADD命令具备自动解压的功能。
COPY命令:
- 复制宿主机上的文件到镜像中的指定目录下,只是复制功能,无解压功能
参考如下即可:
# 如下方式构建镜像,容器启动后会直接停止ENTRYPOINT service tomcat7 start CMD service tomcat7 start
# 可以使用如下方式:(满足最后一条命令一直运行的)ENTRYPOINT service tomcat7 start && tail -f /var/lib/tomcat7/logs/catalina.outCMD service tomcat7 start && tail -f /var/lib/tomcat7/logs/catalina.outENTRYPOINT ["/usr/sbin/sshd"] CMD ["-D"]
转载地址:http://pxeab.baihongyu.com/