容器技术之Dockerfile(二)
前文我们聊到了什么是dockerfile,它的主要作用以及dockerfile的一些基本指令的使用方法,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13019411.html;今天我们在来聊一聊dockerfile余下指令的用法和作用;
1、RUN:该指令用于docker build 过程中运行的程序,可以是任何命令;语法格式RUN <command> 或RUN ["<executable>", "<param1>", "<param2>"];第一种格式中,<command>通常是一个shell命令,且以“/bin/sh -c”来运行它,这意味着此进程在容器中的PID不为1,不能接收Unix信号,因此,当使用docker stop <container>命令停止容器时,此进程接收不到SIGTERM信号; 第二种语法格式中的参数是一个JSON格式的数组,其中<executable>为要运行的命令,后面的<paramN>为传递给命令的选项或参数;然而,此种格式指定的命令不会以“/bin/sh -c”来发起,因此常见的shell操作如变量替换以及通配符(?,*等)替换将不会进行;不过,如果要运行的命令依赖于此shell特性的话,可以将其替换为 RUN ["/bin/sh", "-c", "<executable>", "<param1>"]这样的格式;注意:json数组中,要使用双引号;
示例:
[root@node1 test]# cat Dockerfile
FROM centos:7 MAINTAINER "qiuhom <qiuhom@linux-1874.com>" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." ARG web_home COPY html ${web_home:-"/data/htdoc/"} VOLUME ${web_home:-"/data/htdoc/"} EXPOSE 80/tcp 443/tcp RUN mkdir -p /aaa/bbb/t{1..4} [root@node1 test]#
提示:以上Dockerfile中,用RUN指令运行了mkdir命令,这种运行命令的方式在就可以利用shell的特性,如上大括号展开功能;
验证:build 该dockerfile后,运行该镜像为容器,看看容器内部是否创建了/aaa/bbb/t1 t2 t3 t4?
[root@node1 test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 1c35c4412082 16 hours ago 1.22MB
centos 7 b5b4d78bc90c 4 weeks ago 203MB
[root@node1 test]# docker build . -t myimg:v1
Sending build context to Docker daemon 1.05MB
Step 1/9 : FROM centos:7
---> b5b4d78bc90c
Step 2/9 : MAINTAINER "qiuhom <qiuhom@linux-1874.com>"
---> Running in 64c792ce6750
Removing intermediate container 64c792ce6750
---> 604899ef29f9
Step 3/9 : LABEL version="1.0"
---> Running in 6a3f9b4a9058
Removing intermediate container 6a3f9b4a9058
---> d9edea71fa22
Step 4/9 : LABEL description="this is test file \ that label-values can span multiple lines."
---> Running in b191ab5e19f9
Removing intermediate container b191ab5e19f9
---> ee027bbdc04b
Step 5/9 : ARG web_home
---> Running in a4c86febf616
Removing intermediate container a4c86febf616
---> 5b25bb7421dd
Step 6/9 : COPY html ${web_home:-"/data/htdoc/"}
---> 7c7a667149fa
Step 7/9 : VOLUME ${web_home:-"/data/htdoc/"}
---> Running in f9ec02d8f736
Removing intermediate container f9ec02d8f736
---> 86c7226f6b21
Step 8/9 : EXPOSE 80/tcp 443/tcp
---> Running in ad82d389ac25
Removing intermediate container ad82d389ac25
---> 28dadea40aff
Step 9/9 : RUN mkdir -p /aaa/bbb/t{1..4}
---> Running in 1013a212d3f2
Removing intermediate container 1013a212d3f2
---> 7f109a34a4a5
Successfully built 7f109a34a4a5
Successfully tagged myimg:v1
[root@node1 test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myimg v1 7f109a34a4a5 4 seconds ago 203MB
busybox latest 1c35c4412082 16 hours ago 1.22MB
centos 7 b5b4d78bc90c 4 weeks ago 203MB
[root@node1 test]# docker run --name test --rm -it myimg:v1 /bin/bash
[root@fc89ca934ed5 /]# ls /
aaa bin dev home lib64 mnt proc run srv tmp var
anaconda-post.log data etc lib media opt root sbin sys usr
[root@fc89ca934ed5 /]# ls /aaa/
bbb
[root@fc89ca934ed5 /]# ls /aaa/bbb/
t1 t2 t3 t4
[root@fc89ca934ed5 /]# exit
exit
[root@node1 test]#
提示:底层基础镜像的shell如果不支持大括号展开,那么我们基于这种镜像做出来的镜像运行以上命令也就不支持shell的大括号展开功能;
示例:
[root@node1 test]# cat Dockerfile
FROM centos:7 MAINTAINER "qiuhom <qiuhom@linux-1874.com>" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." ARG web_home COPY html ${web_home:-"/data/htdoc/"} VOLUME ${web_home:-"/data/htdoc/"} EXPOSE 80/tcp 443/tcp RUN mkdir -p /aaa/bbb/t{1..4} RUN ["mkdir","-p","/ccc/ddd/f{1..4}"] [root@node1 test]#
提示:以json数组格式的方式去运行命令,它默认是不支持shell的任何特性,这意味着运行该命令时,不是基于shell子进程的方式在执行命令,通常是内核直接执行了;所以上面的命令它会把大括号处理成字符,而不会展开;
验证:build成镜像运行成容器,看看是否把大括号处理成字符了?
[root@node1 test]# docker build . -t myimg:v1.1
Sending build context to Docker daemon 1.05MB
Step 1/10 : FROM centos:7
---> b5b4d78bc90c
Step 2/10 : MAINTAINER "qiuhom <qiuhom@linux-1874.com>"
---> Using cache
---> 604899ef29f9
Step 3/10 : LABEL version="1.0"
---> Using cache
---> d9edea71fa22
Step 4/10 : LABEL description="this is test file \ that label-values can span multiple lines."
---> Using cache
---> ee027bbdc04b
Step 5/10 : ARG web_home
---> Using cache
---> 5b25bb7421dd
Step 6/10 : COPY html ${web_home:-"/data/htdoc/"}
---> Using cache
---> 7c7a667149fa
Step 7/10 : VOLUME ${web_home:-"/data/htdoc/"}
---> Using cache
---> 86c7226f6b21
Step 8/10 : EXPOSE 80/tcp 443/tcp
---> Using cache
---> 28dadea40aff
Step 9/10 : RUN mkdir -p /aaa/bbb/t{1..4}
---> Using cache
---> 7f109a34a4a5
Step 10/10 : RUN ["mkdir","-p","/ccc/ddd/f{1..4}"]
---> Running in 9da1e6bab59f
Removing intermediate container 9da1e6bab59f
---> ae463ec8cbd9
Successfully built ae463ec8cbd9
Successfully tagged myimg:v1.1
[root@node1 test]# docker run --name test --rm -it myimg:v1.1 /bin/bash
[root@02ec6e404100 /]# ls /
aaa bin data etc lib media opt root sbin sys usr
anaconda-post.log ccc dev home lib64 mnt proc run srv tmp var
[root@02ec6e404100 /]# ls /ccc/ddd/
f{1..4}
[root@02ec6e404100 /]#
提示:可以看到在/ccc/ddd/目录下并没有把大括号展开,而是直接把它当成了字符处理了;如果我们想要用json数组这种方式运行命令,又想让使用shell特性,我们可以使用"/bin/sh -c"来明确声明后面的命令用shell子进程的方式运行;如下所示
[root@node1 test]# cat Dockerfile
FROM centos:7 MAINTAINER "qiuhom <qiuhom@linux-1874.com>" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." ARG web_home COPY html ${web_home:-"/data/htdoc/"} VOLUME ${web_home:-"/data/htdoc/"} EXPOSE 80/tcp 443/tcp RUN mkdir -p /aaa/bbb/t{1..4} RUN ["/bin/bash","-c","mkdir -p /ccc/ddd/f{1..4}"] [root@node1 test]#
提示:以上运行命令的方式就明确声明使用shell子进程的方式运行命令;这里需要注意一点的是,如果使用json数组的方式运行命令,后面真正执行的命令要一个整体当作参数传给"/bin/bash"
验证:看看是否会把大括号展开?
[root@node1 test]# docker build . -t myimg:v1.2
Sending build context to Docker daemon 1.05MB
Step 1/10 : FROM centos:7
---> b5b4d78bc90c
Step 2/10 : MAINTAINER "qiuhom <qiuhom@linux-1874.com>"
---> Using cache
---> 604899ef29f9
Step 3/10 : LABEL version="1.0"
---> Using cache
---> d9edea71fa22
Step 4/10 : LABEL description="this is test file \ that label-values can span multiple lines."
---> Using cache
---> ee027bbdc04b
Step 5/10 : ARG web_home
---> Using cache
---> 5b25bb7421dd
Step 6/10 : COPY html ${web_home:-"/data/htdoc/"}
---> Using cache
---> 7c7a667149fa
Step 7/10 : VOLUME ${web_home:-"/data/htdoc/"}
---> Using cache
---> 86c7226f6b21
Step 8/10 : EXPOSE 80/tcp 443/tcp
---> Using cache
---> 28dadea40aff
Step 9/10 : RUN mkdir -p /aaa/bbb/t{1..4}
---> Using cache
---> 7f109a34a4a5
Step 10/10 : RUN ["/bin/bash","-c","mkdir -p /ccc/ddd/f{1..4}"]
---> Running in a5785a139e1f
Removing intermediate container a5785a139e1f
---> 30a5f5594104
Successfully built 30a5f5594104
Successfully tagged myimg:v1.2
[root@node1 test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myimg v1.2 30a5f5594104 5 seconds ago 203MB
myimg v1.1 ae463ec8cbd9 9 minutes ago 203MB
myimg v1 7f109a34a4a5 21 minutes ago 203MB
busybox latest 1c35c4412082 16 hours ago 1.22MB
centos 7 b5b4d78bc90c 4 weeks ago 203MB
[root@node1 test]# docker run --name test --rm -it myimg:v1.2 /bin/bash
[root@549f875aa4de /]# ls /
aaa bin data etc lib media opt root sbin sys usr
anaconda-post.log ccc dev home lib64 mnt proc run srv tmp var
[root@549f875aa4de /]# ls /ccc/ddd/
f1 f2 f3 f4
[root@549f875aa4de /]#
提示:可以看到用"/bin/bash -c" 是可以明确声明后面的命令用shell子进程的方式运行,这样一来就可以在后面的命令使用shell特性的语法;
2、CMD:该指令类似于RUN指令,CMD指令也可用于运行任何命令或应用程序,不过,二者的运行时间点不同; RUN指令运行于映像文件构建过程中,而CMD指令运行于基于Dockerfile构建出的新映像文件启动一个容器时; CMD指令的首要目的在于为启动的容器指定默认要运行的程序,且其运行结束后,容器也将终止;不过,CMD指定的命令其可以被docker run的命令行选项所覆盖;在Dockerfile中可以存在多个CMD指令,但仅最后一个会生效;语法格式 CMD <command> 或 CMD [“<executable>”, “<param1>”, “<param2>”] 或 CMD ["<param1>","<param2>"];前两种语法格式的意义同RUN,第三种则用于为ENTRYPOINT指令提供默认参数;
示例:
[root@node1 test]# cat Dockerfile
FROM busybox:latest MAINTAINER "qiuhom <qiuhom@linux-1874.com>" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." ARG web_home COPY html ${web_home:-"/data/htdoc/"} VOLUME ${web_home:-"/data/htdoc/"} EXPOSE 80/tcp 443/tcp CMD httpd -f -h /data/htdoc/
[root@node1 test]#
提示:docker容器内部运行的程序必须运行为前台;CMD是指定容器运行时要运行的命令;通常该命令或程序是以前台方式运行;如果不是前台运行,我们的容器就会存在一启动就退出的情况;以上命令就表示前台运行httpd程序 并指定httpd 的工作目录为${web_home}变量所指定的目录;
验证:build后看看启动为容器是否提供80访问服务?
[root@node1 test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myimg v1.2 30a5f5594104 23 minutes ago 203MB
myimg v1.1 ae463ec8cbd9 32 minutes ago 203MB
myimg v1 7f109a34a4a5 44 minutes ago 203MB
busybox latest 1c35c4412082 16 hours ago 1.22MB
centos 7 b5b4d78bc90c 4 weeks ago 203MB
[root@node1 test]# docker build . -t myimg:v1.3
Sending build context to Docker daemon 1.05MB
Step 1/9 : FROM busybox:latest
---> 1c35c4412082
Step 2/9 : MAINTAINER "qiuhom <qiuhom@linux-1874.com>"
---> Running in deb5e54eef87
Removing intermediate container deb5e54eef87
---> baf170e0c586
Step 3/9 : LABEL version="1.0"
---> Running in 433669185e0d
Removing intermediate container 433669185e0d
---> d96fb4ae3d58
Step 4/9 : LABEL description="this is test file \ that label-values can span multiple lines."
---> Running in b5da74e27c69
Removing intermediate container b5da74e27c69
---> 62372d19daf3
Step 5/9 : ARG web_home
---> Running in 3f65a67bb15a
Removing intermediate container 3f65a67bb15a
---> 1ce797c7cde0
Step 6/9 : COPY html ${web_home:-"/data/htdoc/"}
---> 15848dea21b9
Step 7/9 : VOLUME ${web_home:-"/data/htdoc/"}
---> Running in 868f4c10e00f
Removing intermediate container 868f4c10e00f
---> f3ec40d1cb5e
Step 8/9 : EXPOSE 80/tcp 443/tcp
---> Running in 7f72c2612e92
Removing intermediate container 7f72c2612e92
---> 5ccfc6d604cc
Step 9/9 : CMD httpd -f -h /data/htdoc/
---> Running in 95a4fd578821
Removing intermediate container 95a4fd578821
---> 2e296b4f4500
Successfully built 2e296b4f4500
Successfully tagged myimg:v1.3
[root@node1 test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myimg v1.3 2e296b4f4500 3 seconds ago 1.22MB
myimg v1.2 30a5f5594104 23 minutes ago 203MB
myimg v1.1 ae463ec8cbd9 33 minutes ago 203MB
myimg v1 7f109a34a4a5 44 minutes ago 203MB
busybox latest 1c35c4412082 16 hours ago 1.22MB
centos 7 b5b4d78bc90c 4 weeks ago 203MB
[root@node1 test]# docker run --name b1 -d myimg:v1.3
c3514f782cffd8140aa7c612293029f4d0302e8d697887dfc2696eea44a31700
[root@node1 test]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c3514f782cff myimg:v1.3 "/bin/sh -c 'httpd -…" 4 seconds ago Up 3 seconds 80/tcp, 443/tcp b1
[root@node1 test]# curl http://172.17.0.2/test1.html
this is test1 html
[root@node1 test]#
提示:可以看到httpd是可以正常提供服务的;从上面的信息我们也可以了解到运行容器后,它默认是把我们写的命令当作shell子命令的方式在运行;
示例:以json数组方式运行命令
[root@node1 test]# cat Dockerfile
FROM busybox:latest MAINTAINER "qiuhom <qiuhom@linux-1874.com>" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." ARG web_home COPY html ${web_home:-"/data/htdoc/"} VOLUME ${web_home:-"/data/htdoc/"} EXPOSE 80/tcp 443/tcp CMD ["httpd","-f","-h","/data/htdoc/"] [root@node1 test]#
提示:用json数组格式运行命令,需要把后面的每个选项当作参数传给httpd;
验证:运行容器看看容器是否退出,是否能够正常提供httpd服务?
[root@node1 test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myimg v1.3 2e296b4f4500 24 minutes ago 1.22MB
myimg v1.2 30a5f5594104 47 minutes ago 203MB
myimg v1.1 ae463ec8cbd9 57 minutes ago 203MB
myimg v1 7f109a34a4a5 About an hour ago 203MB
busybox latest 1c35c4412082 17 hours ago 1.22MB
centos 7 b5b4d78bc90c 4 weeks ago 203MB
[root@node1 test]# docker build . -t myimg:v1.4
Sending build context to Docker daemon 1.05MB
Step 1/9 : FROM busybox:latest
---> 1c35c4412082
Step 2/9 : MAINTAINER "qiuhom <qiuhom@linux-1874.com>"
---> Using cache
---> baf170e0c586
Step 3/9 : LABEL version="1.0"
---> Using cache
---> d96fb4ae3d58
Step 4/9 : LABEL description="this is test file \ that label-values can span multiple lines."
---> Using cache
---> 62372d19daf3
Step 5/9 : ARG web_home
---> Using cache
---> 1ce797c7cde0
Step 6/9 : COPY html ${web_home:-"/data/htdoc/"}
---> Using cache
---> 15848dea21b9
Step 7/9 : VOLUME ${web_home:-"/data/htdoc/"}
---> Using cache
---> f3ec40d1cb5e
Step 8/9 : EXPOSE 80/tcp 443/tcp
---> Using cache
---> 5ccfc6d604cc
Step 9/9 : CMD ["httpd","-f","-h","/data/htdoc/"]
---> Running in 5bebdabfe2b7
Removing intermediate container 5bebdabfe2b7
---> 58e3b4c40ae7
Successfully built 58e3b4c40ae7
Successfully tagged myimg:v1.4
[root@node1 test]# docker run --name b1 -d myimg:v1.4
a32a05033a6dcb735363906bfcd2b84cfb290ca1b60c17d3ac2f81cdeceee705
[root@node1 test]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a32a05033a6d myimg:v1.4 "httpd -f -h /data/h…" 6 seconds ago Up 5 seconds 80/tcp, 443/tcp b1
[root@node1 test]# curl http://172.17.0.2/test1.html
this is test1 html
[root@node1 test]#
提示:可以看到httpd服务可以正常提供访问,说明我们用json数组方式运行命令是正确的;总结一点,用CMD或RUN指令运行命令时,如果直接在CMD或RUN指令后面接命令,这种方式通常会被解释为启动一个shell子进程运行命令,RUN指令表现形式就是后面的命令可以使用shell特性的语法格式的命令,比如大括号展开等等;而CMD指令表现形式就是启动为容器后,它默认会把我们指定运行的命令当作参数传给“/bin/sh”来运行;CMD或RUN指令加中括号的形式就表示使用json数组格式方式运行命令;这种方式运行命令在CMD中表现形式是我们运行的命令的选项都要当作参数传给该命令;RUN指令表现形式是不能使用shell特性的命令;如果非要使用shell特性的命令格式,我们需要把我们的命令当作参数传给“/bin/sh”,当然前提是我们的基础镜像shell支持shell特性的语法;
3、ENTRYPOINT:该指令类似CMD指令的功能,用于为容器指定默认运行程序,从而使得容器像是一个单独的可执行程序;与CMD不同的是,由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT指定的程序(不过,docker run命令的--entrypoint选项的参数可覆盖ENTRYPOINT指令指定的程序);语法格式 ENTRYPOINT <command>或 ENTRYPOINT ["<executable>", "<param1>", "<param2>"];docker run命令传入的命令参数会覆盖CMD指令的内容并且附加到ENTRYPOINT命令最后做为其参数使用;Dockerfile文件中也可以存在多个ENTRYPOINT指令,但仅有最后一个会生效;
示例:
[root@node1 test]# cat Dockerfile
FROM busybox:latest MAINTAINER "qiuhom <qiuhom@linux-1874.com>" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." ARG web_home COPY html ${web_home:-"/data/htdoc/"} VOLUME ${web_home:-"/data/htdoc/"} EXPOSE 80/tcp 443/tcp ENTRYPOINT httpd -f -h /data/htdoc/
[root@node1 test]#
提示:以上dockerfile中用ENTRYPOINT 来指定容器默认运行程序,它和CMD不同的是,CMD指定运行的命令,我们可以使用docker run 命令加要运行的的命令替代容器里默认运行的命令,而ENTRYPOINT指定的命令我们是不可随便替换的,如果要替换必须要使用--entrypoint选项来指定;
验证:build成镜像,我们启动为容器直接运行/bin/sh 看看是否可行?
[root@node1 test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myimg v1.4 58e3b4c40ae7 23 minutes ago 1.22MB
myimg v1.3 2e296b4f4500 47 minutes ago 1.22MB
myimg v1.2 30a5f5594104 About an hour ago 203MB
myimg v1.1 ae463ec8cbd9 About an hour ago 203MB
myimg v1 7f109a34a4a5 2 hours ago 203MB
busybox latest 1c35c4412082 17 hours ago 1.22MB
centos 7 b5b4d78bc90c 4 weeks ago 203MB
[root@node1 test]# docker build . -t myimg:v1.5
Sending build context to Docker daemon 1.05MB
Step 1/9 : FROM busybox:latest
---> 1c35c4412082
Step 2/9 : MAINTAINER "qiuhom <qiuhom@linux-1874.com>"
---> Using cache
---> baf170e0c586
Step 3/9 : LABEL version="1.0"
---> Using cache
---> d96fb4ae3d58
Step 4/9 : LABEL description="this is test file \ that label-values can span multiple lines."
---> Using cache
---> 62372d19daf3
Step 5/9 : ARG web_home
---> Using cache
---> 1ce797c7cde0
Step 6/9 : COPY html ${web_home:-"/data/htdoc/"}
---> Using cache
---> 15848dea21b9
Step 7/9 : VOLUME ${web_home:-"/data/htdoc/"}
---> Using cache
---> f3ec40d1cb5e
Step 8/9 : EXPOSE 80/tcp 443/tcp
---> Using cache
---> 5ccfc6d604cc
Step 9/9 : ENTRYPOINT httpd -f -h /data/htdoc/
---> Running in de274d68686c
Removing intermediate container de274d68686c
---> 5825c2ec655f
Successfully built 5825c2ec655f
Successfully tagged myimg:v1.5
[root@node1 test]# docker run --name b1 --rm -it myimg:v1.5 /bin/sh
提示:运行以上命令后,不会给我们一个shell终端,也不报错;但是我们直接访问httpd服务是可以正常访问的;这意味我们用docker run 命令是不能替换我们用entrypoint指定指定的命令的;
测试:用--entrypoint 选项来看看是否能够覆盖ENTRYPOINT指定所指定的命令程序?
[root@node1 test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myimg v1.5 5825c2ec655f 12 minutes ago 1.22MB
myimg v1.4 58e3b4c40ae7 35 minutes ago 1.22MB
myimg v1.3 2e296b4f4500 About an hour ago 1.22MB
myimg v1.2 30a5f5594104 About an hour ago 203MB
myimg v1.1 ae463ec8cbd9 2 hours ago 203MB
myimg v1 7f109a34a4a5 2 hours ago 203MB
busybox latest 1c35c4412082 17 hours ago 1.22MB
centos 7 b5b4d78bc90c 4 weeks ago 203MB
[root@node1 test]# docker run --name b1 --rm -it --entrypoint "/bin/sh" myimg:v1.5
/ # ls
bin data dev etc home proc root sys tmp usr var
/ # ps
PID USER TIME COMMAND
1 root 0:00 /bin/sh
7 root 0:00 ps
/ #
提示:可以看到使用docker run 必须要加--entrypoint 选项才可以覆盖ENTRYPOINT指令指定的命令;
示例:使用json数组格式来指定命令
[root@node1 test]# cat Dockerfile
FROM busybox:latest MAINTAINER "qiuhom <qiuhom@linux-1874.com>" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." ARG web_home COPY html ${web_home:-"/data/htdoc/"} VOLUME ${web_home:-"/data/htdoc/"} EXPOSE 80/tcp 443/tcp ENTRYPOINT ["httpd","-f","-h","/data/htdoc/"] [root@node1 test]#
提示:使用json数组格式来指定命令时,都需要将后面的选项和参数当作该命令的参数传进去;
测试:使用docker run 直接加命令 看看是否能够覆盖ENTRYPOINT指令指定的命令?
提示:可以看到我们直接使用命令是无法覆盖ENTRYPOINT指令说指定的命令;
示例:
[root@node1 test]# cat Dockerfile
FROM centos:7 MAINTAINER "qiuhom <qiuhom@linux-1874.com>" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." RUN yum install -y httpd EXPOSE 80/tcp ENTRYPOINT ["/usr/sbin/httpd","-DFOREGROUND"] [root@node1 test]#
测试:用docker run 命令覆盖ENTRYPOINT指定的默认命令,看看是否可行?
[root@node1 test]# docker build . -t myimg:v1.7
Sending build context to Docker daemon 1.051MB
Step 1/7 : FROM centos:7
---> b5b4d78bc90c
Step 2/7 : MAINTAINER "qiuhom <qiuhom@linux-1874.com>"
---> Using cache
---> 604899ef29f9
Step 3/7 : LABEL version="1.0"
---> Using cache
---> d9edea71fa22
Step 4/7 : LABEL description="this is test file \ that label-values can span multiple lines."
---> Using cache
---> ee027bbdc04b
Step 5/7 : RUN yum install -y httpd
---> Running in 164240645e39
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
* base: mirrors.aliyun.com
* extras: mirrors.aliyun.com
* updates: mirrors.aliyun.com
Resolving Dependencies
--> Running transaction check
---> Package httpd.x86_64 0:2.4.6-93.el7.centos will be installed
--> Processing Dependency: httpd-tools = 2.4.6-93.el7.centos for package: httpd-2.4.6-93.el7.centos.x86_64
--> Processing Dependency: system-logos >= 7.92.1-1 for package: httpd-2.4.6-93.el7.centos.x86_64
--> Processing Dependency: /etc/mime.types for package: httpd-2.4.6-93.el7.centos.x86_64
--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.4.6-93.el7.centos.x86_64
--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.4.6-93.el7.centos.x86_64
--> Running transaction check
---> Package apr.x86_64 0:1.4.8-5.el7 will be installed
---> Package apr-util.x86_64 0:1.5.2-6.el7 will be installed
---> Package centos-logos.noarch 0:70.0.6-3.el7.centos will be installed
---> Package httpd-tools.x86_64 0:2.4.6-93.el7.centos will be installed
---> Package mailcap.noarch 0:2.1.41-2.el7 will be installed
--> Finished Dependency Resolution Dependencies Resolved ================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
httpd x86_64 2.4.6-93.el7.centos base 2.7 M
Installing for dependencies:
apr x86_64 1.4.8-5.el7 base 103 k
apr-util x86_64 1.5.2-6.el7 base 92 k
centos-logos noarch 70.0.6-3.el7.centos base 21 M
httpd-tools x86_64 2.4.6-93.el7.centos base 92 k
mailcap noarch 2.1.41-2.el7 base 31 k Transaction Summary
================================================================================
Install 1 Package (+5 Dependent packages) Total download size: 24 M
Installed size: 32 M
Downloading packages:
warning: /var/cache/yum/x86_64/7/base/packages/apr-util-1.5.2-6.el7.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
Public key for apr-util-1.5.2-6.el7.x86_64.rpm is not installed
--------------------------------------------------------------------------------
Total 7.8 MB/s | 24 MB 00:03
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
Importing GPG key 0xF4A80EB5:
Userid : "CentOS-7 Key (CentOS 7 Official Signing Key) <security@centos.org>"
Fingerprint: 6341 ab27 53d7 8a78 a7c2 7bb1 24c6 a8a7 f4a8 0eb5
Package : centos-release-7-8.2003.0.el7.centos.x86_64 (@CentOS)
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : apr-1.4.8-5.el7.x86_64 1/6
Installing : apr-util-1.5.2-6.el7.x86_64 2/6
Installing : httpd-tools-2.4.6-93.el7.centos.x86_64 3/6
Installing : centos-logos-70.0.6-3.el7.centos.noarch 4/6
Installing : mailcap-2.1.41-2.el7.noarch 5/6
Installing : httpd-2.4.6-93.el7.centos.x86_64 6/6
Verifying : mailcap-2.1.41-2.el7.noarch 1/6
Verifying : apr-util-1.5.2-6.el7.x86_64 2/6
Verifying : httpd-2.4.6-93.el7.centos.x86_64 3/6
Verifying : apr-1.4.8-5.el7.x86_64 4/6
Verifying : httpd-tools-2.4.6-93.el7.centos.x86_64 5/6
Verifying : centos-logos-70.0.6-3.el7.centos.noarch 6/6 Installed:
httpd.x86_64 0:2.4.6-93.el7.centos Dependency Installed:
apr.x86_64 0:1.4.8-5.el7
apr-util.x86_64 0:1.5.2-6.el7
centos-logos.noarch 0:70.0.6-3.el7.centos
httpd-tools.x86_64 0:2.4.6-93.el7.centos
mailcap.noarch 0:2.1.41-2.el7 Complete!
Removing intermediate container 164240645e39
---> 63db91f4fe6a
Step 6/7 : EXPOSE 80/tcp
---> Running in 6585da71fc3b
Removing intermediate container 6585da71fc3b
---> eb671cf67f52
Step 7/7 : ENTRYPOINT ["/usr/sbin/httpd","-DFOREGROUND"]
---> Running in f6e7297025af
Removing intermediate container f6e7297025af
---> bac03b20761a
Successfully built bac03b20761a
Successfully tagged myimg:v1.7
[root@node1 test]# docker run --name m1 --rm -it myimg:v1.7 /bin/sh
Usage: /usr/sbin/httpd [-D name] [-d directory] [-f file]
[-C "directive"] [-c "directive"]
[-k start|restart|graceful|graceful-stop|stop]
[-v] [-V] [-h] [-l] [-L] [-t] [-T] [-S] [-X]
Options:
-D name : define a name for use in <IfDefine name> directives
-d directory : specify an alternate initial ServerRoot
-f file : specify an alternate ServerConfigFile
-C "directive" : process directive before reading config files
-c "directive" : process directive after reading config files
-e level : show startup errors of level (see LogLevel)
-E file : log startup errors to file
-v : show version number
-V : show compile settings
-h : list available command line options (this page)
-l : list compiled in modules
-L : list available configuration directives
-t -D DUMP_VHOSTS : show parsed vhost settings
-t -D DUMP_RUN_CFG : show parsed run settings
-S : a synonym for -t -D DUMP_VHOSTS -D DUMP_RUN_CFG
-t -D DUMP_MODULES : show all loaded modules
-M : a synonym for -t -D DUMP_MODULES
-t : run syntax check for config files
-T : start without DocumentRoot(s) check
-X : debug mode (only one worker, do not detach)
[root@node1 test]#
提示:可以看到我们用docker run指定命令去覆盖ENTRYPOINT指令指定的命令,它给我们打印了httpd命令的用法,这说明我们后面传递的/bin/sh 当作参数传递给ENTRYPOINT说指定的命令;这里还需要说一下,上面的示例用docker run 去覆盖ENTRYPOINT指令指定的命令,没有报错的原因应该是busybox里的httpd程序支持传递/bin/sh当作参数;
示例:CMD指令同ENTRYPOINT一起使用
[root@node1 test]# cat Dockerfile
FROM centos:7 MAINTAINER "qiuhom <qiuhom@linux-1874.com>" LABEL version="1.0" LABEL description="this is test file \ that label-values can span multiple lines." RUN yum install -y httpd ADD entrypoint.sh /bin/ EXPOSE 80/tcp CMD ["/usr/sbin/httpd","-DFOREGROUND"] ENTRYPOINT ["/bin/entrypoint.sh"] [root@node1 test]#
提示:以上dockerfile使用了CMD和ENTRYPOINT指令来指定容器默认运行程序;此时CMD所指定的命令默认会以参数的形式传给ENTRYPOINT指令所指定的命令;而上面ENTRYPOINT指定指定的是一个脚本,也就说上面dockerfile最终运行的命令是/bin/entrypoint.sh /usr/sbin/httpd -DFOREGROUND;这里的脚本就相当于中间层,通过脚本设定一些参数,然后把CMD指定的命令当作参数传给脚本,最终脚本运行起来;
entrypoint脚本
[root@node1 test]# ll
total 1032
-rw-r--r-- 1 root root 307 Jun 3 11:28 Dockerfile
-rwxr-xr-x 1 root root 300 Jun 3 11:22 entrypoint.sh
drwxr-xr-x 2 root root 42 May 31 01:51 html
-rw-r--r-- 1 root root 1043748 May 26 11:07 nginx-1.19.0.tar.gz
-rw-r--r-- 1 root root 22 May 31 01:52 test.html
[root@node1 test]# cat entrypoint.sh
#!/bin/bash doc_root=${DOC_ROOT:-/var/www/html}
cat > /etc/httpd/conf.d/myweb.conf <<EOF
<virtualhost *:80>
servername "localhost"
documentroot "${doc_root}"
<directory "${doc_root}">
options none
allowoverride none
require all granted
</directory>
</virtualhost>
EOF exec "$@"
[root@node1 test]#
提示:这个脚本很简单就是在/etc/httpd/conf.d/生成一个myweb.conf的配置文件,然后最后引用脚本的参数运行;exec "$@" 表示把脚本的所有参数独立运行成一个守护进程;默认不使用exec就表示以shell子进程的方式运行,exec就表示运行为单独的守护进程,不再是shell子进程的方式;
测试:
[root@node1 test]# docker build . -t httpd:v1
Sending build context to Docker daemon 1.051MB
Step 1/9 : FROM centos:7
---> b5b4d78bc90c
Step 2/9 : MAINTAINER "qiuhom <qiuhom@linux-1874.com>"
---> Using cache
---> 604899ef29f9
Step 3/9 : LABEL version="1.0"
---> Using cache
---> d9edea71fa22
Step 4/9 : LABEL description="this is test file \ that label-values can span multiple lines."
---> Using cache
---> ee027bbdc04b
Step 5/9 : RUN yum install -y httpd
---> Using cache
---> 63db91f4fe6a
Step 6/9 : ADD entrypoint.sh /bin/
---> 49d1270c3aa3
Step 7/9 : EXPOSE 80/tcp
---> Running in 3dacf6acf23b
Removing intermediate container 3dacf6acf23b
---> edced77af5b5
Step 8/9 : CMD ["/usr/sbin/httpd","-DFOREGROUND"]
---> Running in 23bb32def296
Removing intermediate container 23bb32def296
---> 169a5e164ba5
Step 9/9 : ENTRYPOINT ["/bin/entrypoint.sh"]
---> Running in f3bf0c267c7b
Removing intermediate container f3bf0c267c7b
---> 0801db092665
Successfully built 0801db092665
Successfully tagged httpd:v1
[root@node1 test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd v1 0801db092665 35 seconds ago 307MB
myimg v1.7 bac03b20761a 12 minutes ago 307MB
myimg v1.6 5370df4238eb 2 hours ago 1.22MB
myimg v1.5 5825c2ec655f 2 hours ago 1.22MB
myimg v1.4 58e3b4c40ae7 2 hours ago 1.22MB
myimg v1.3 2e296b4f4500 3 hours ago 1.22MB
myimg v1.2 30a5f5594104 3 hours ago 203MB
myimg v1.1 ae463ec8cbd9 3 hours ago 203MB
myimg v1 7f109a34a4a5 3 hours ago 203MB
busybox latest 1c35c4412082 19 hours ago 1.22MB
centos 7 b5b4d78bc90c 4 weeks ago 203MB
[root@node1 test]# docker run --name h1 -d httpd:v1
cee14b04912822c33e7deeee361e1ce0c20d7daf6c0666bff319bf3f1bc69bdc
[root@node1 test]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cee14b049128 httpd:v1 "/bin/entrypoint.sh …" 9 seconds ago Up 9 seconds 80/tcp h1
[root@node1 test]#
提示:可以看到我们build成镜像后,直接运行为容器,容器正常;我们进入容器内部看看它到底运行的说明命令
[root@node1 test]# docker exec -it h1 /bin/bash
[root@cee14b049128 /]# ls /etc/httpd/conf.d/myweb.conf
/etc/httpd/conf.d/myweb.conf
[root@cee14b049128 /]# cat /etc/httpd/conf.d/myweb.conf
<virtualhost *:80>
servername "localhost"
documentroot "/var/www/html"
<directory "/var/www/html">
options none
allowoverride none
require all granted
</directory>
</virtualhost>
[root@cee14b049128 /]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 224080 5016 ? Ss 16:26 0:00 /usr/sbin/httpd -D
apache 7 0.0 0.0 224212 2960 ? S 16:26 0:00 /usr/sbin/httpd -D
apache 8 0.0 0.0 224212 2960 ? S 16:26 0:00 /usr/sbin/httpd -D
apache 9 0.0 0.0 224212 2960 ? S 16:26 0:00 /usr/sbin/httpd -D
apache 10 0.0 0.0 224212 2960 ? S 16:26 0:00 /usr/sbin/httpd -D
apache 11 0.0 0.0 224212 2960 ? S 16:26 0:00 /usr/sbin/httpd -D
root 12 0.0 0.0 11828 1932 pts/0 Ss 16:35 0:00 /bin/bash
root 27 0.0 0.0 51756 1720 pts/0 R+ 16:36 0:00 ps aux
[root@cee14b049128 /]# httpd -t -D DUMP_VHOSTS
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
VirtualHost configuration:
*:80 localhost (/etc/httpd/conf.d/myweb.conf:1)
[root@cee14b049128 /]#
提示:可以看到容器内部运行的就是/usr/sbin/httpd -DFOREGROUND这个命令;其实这个命令不是CMD直接运行的命令,而是通过脚本获取参数而来的;我们通过脚本添加的配置文件都在对应的位置,并且也都生效了;总结一点,通常CMD和ENTRYPOINT应用在通过entrypoint脚本做中间层向容器内运行的程序提供配置文件的场景,通常这些应用程序不是云原生的;
容器技术之Dockerfile(二)的更多相关文章
- 容器技术之Dockerfile (一)
在前边的随笔中我们聊到了docker的基本命令,镜像,网络,存储卷以及基于现有容器制做docker镜像,相关随笔可参考https://www.cnblogs.com/qiuhom-1874/categ ...
- 容器技术之Dockerfile(三)
前面我们聊到了dockerfile的 FROM.COPY .ADD.LABAL.MAINTAINER.ENV.ARG.WORKDIR.VOLUME.EXPOSE.RUN.CMD.ENTRYPOINT指 ...
- Linux 运维工作中的经典应用ansible(批量管理)Docker容器技术(环境的快速搭建)
一 Ansible自动化运维工具 Python 在运维工作中的经典应用 ansible(批量管理操作) .安装ansible(需要bese epel 2种源) wget -O /etc/yum.rep ...
- Docker 容器技术
前言: 之前感觉Docker是一种小虚拟机,docker和KVM虚拟机之间有什么区别.联系.可以应用在什么样的生产环境? 一.Docker是什么以及和KVM的区别 1.docker概念? Docker ...
- docker-每天5分钟玩转Docker容器技术
安装 https://www.cnblogs.com/qinxu/p/10032176.html 安装教程,目前只能安装到18版本的,安装完后执行下面命令更新到版本19 yum install doc ...
- 一文了解Docker容器技术的操作
一文了解Docker容器技术的操作 前言一.Docker是什么二.Docker的安装及测试Docker的安装Docker的Hello world测试三.Docker的常见操作镜像的基本操作容器的基本操 ...
- 【Docker】(9)---每天5分钟玩转 Docker 容器技术之镜像
镜像是 Docker 容器的基石,容器是镜像的运行实例,有了镜像才能启动容器.为什么我们要讨论镜像的内部结构? 如果只是使用镜像,当然不需要了解,直接通过 docker 命令下载和运行就可以了. 但如 ...
- WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇]
原文:WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇] 元数据的导出就是实现从ServiceEndpoint对象向MetadataSet对象转换的过程,在WCF元数据框 ...
- WCF技术剖析之二十: 服务在WCF体系中是如何被描述的?
原文:WCF技术剖析之二十: 服务在WCF体系中是如何被描述的? 任何一个程序都需要运行于一个确定的进程中,进程是一个容器,其中包含程序实例运行所需的资源.同理,一个WCF服务的监听与执行同样需要通过 ...
随机推荐
- Spring学习笔记(八)Spring Data JPA学习
jpa简单的命名规则如下,这个不多做介绍,放在这里也是给自己以后查找起来方便,这篇文章主要介绍之前一直忽略了的几个点,像@NoRepositoryBean这个注解,以及怎么自定义Repositor ...
- SQL语言概况(4.1)
SQL语言概况(4.1) 目录 SQL语言概况(4.1) 4.1 SQL语言概况 4.1.1 历史及标准简介 4.1.2 SQL语言定义及特点 4.1.3 使用说明 参考资料: 数据库原理及设计(第3 ...
- Exception in thread "main" java.lang.NoSuchMethodError: scala.Predef$.wrapRefArray([Ljava/lang/Object;)Lscala/collection/mutable/WrappedArray
我是在用akka框架做简单的一个聊天,然而出师不利,刚开始学就遇到这个问题 遇事不决问百度,百度给出的结果是spark中scala版本和你使用的scala的版本不一致,所导致的错误 我用的是akka, ...
- P2220 [HAOI2012]容易题(快速幂)
Describe 为了使得大家高兴,小Q特意出个自认为的简单题(easy)来满足大家,这道简单题是描述如下: 有一个数列A已知对于所有的A[i]都是1~n的自然数,并且知道对于一些A[i]不能取哪些值 ...
- layui编辑商品时,怎么使用下拉菜单显示商品默认分类的问题
//加载商品默认的分类$.get('/admin/category/selec/' + {$simple.0.first_pid},function(msg){ $("#two_cate&q ...
- 将mat文件中的数据按要求保存到txt文档中(批处理)
之前有个老朋友,让帮忙将一个mat中的数据重新保存到txt中,由于数据比较多需要用到批处理,之前弄过很多次,但每次一到要用的时候总是忘记怎么写了,现在记录一下,免得后面老是需要上网搜.这里先说一个比较 ...
- vue实例中created、mounted以及其他类型说明
生命周期图示(图片来自coderwhy老师): 每个 Vue 实例在被创建之前都要经过一系列的初始化过程.例如,实例需要配置数据观测(data observer).编译模版.挂载实例到 DOM ,然后 ...
- Vue中import用法
1. 引入第三方插件 第三方常用插件参考https://blog.csdn.net/vbirdbest/article/details/86527886 2. 导入 css 文件 import 'iv ...
- C# 数据操作系列 - 10 NHibernate初试
0. 前言 在上一篇基本讲完了EF Core的入门级教程.从这一篇开始,我们试着去探索一下 .net core平台上更多的ORM框架.那么,这一篇开始我们就来试试NHibernate. 1. NHib ...
- 「雕爷学编程」Arduino动手做(35)——模拟量声音传感器
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里 ...