shell form和exec form 

       Dockerfile 中的 RUN、ENTRYPOINT 和 CMD 指令都有两种写法,shell form 和 exec form。exec form 和 shell form 不同,exec form 不调用 shell,这就意味着不会发生正常的 shell 处理,如 RUN ["echo","$HOME"] 不会对 $HOME 执行变量替换。如果想要 shell 处理,要么使用shell form,要么直接执行 shell,exec form 格式命令会被解析成 json 数组,这意味着你必须使用双引号而不是单引号来括住数组中的每一个元素,例如:exec form 运行 ["sh","-c","echo $HOME"] 。

      我们通过例子看一下。

 exec form

Dockerfile内容:
FROM ubuntu
CMD ["watch","-n 1","date"]
###构建镜像。
root@docker:~# docker build -t execform .
Sending build context to Docker daemon     64kB
Step 1/2 : FROM ubuntu
 ---> ba6acccedd29
Step 2/2 : CMD ["watch","-n 1","date"]
 ---> Running in 2dcf4e97d6cf
Removing intermediate container 2dcf4e97d6cf
 ---> b2625b0c9002
Successfully built b2625b0c9002
Successfully tagged execform:latest

###查看镜像。
root@docker:~# docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
execform     latest    b2625b0c9002   25 seconds ago   72.8MB
ubuntu       latest    ba6acccedd29   15 months ago    72.8MB

###运行容器,--rm参数,容器停止后自动删除容器。
root@docker:~# docker run --rm --name execform -it execform

      容器运行效果:

###再另外开启一个新终端。
###查看内容器运行状态信息。
root@docker:~# docker ps
CONTAINER ID   IMAGE      COMMAND               CREATED         STATUS         PORTS     NAMES
0cb43b162629   execform   "watch '-n 1' date"   6 seconds ago   Up 4 seconds             execform

###执行ps命令查看容器进程情况。
root@docker:~# docker exec -it execform ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 13:05 pts/0    00:00:00 watch -n 1 date
root         346       0  0 13:07 pts/1    00:00:00 ps -ef

###执行命令停止容器,发现很快就能停下。
root@docker:~# docker stop execform
execform

 shell form

Dockerfile内容:
FROM ubuntu
CMD watch -n 1 date
###构建镜像。
root@docker:~# docker build -t shellform -f Dockerfile .
Sending build context to Docker daemon  60.42kB
Step 1/2 : FROM ubuntu
 ---> ba6acccedd29
Step 2/2 : CMD watch -n 1 date
 ---> Running in 0dc36e7c4127
Removing intermediate container 0dc36e7c4127
 ---> 74dae56ad62b
Successfully built 74dae56ad62b
Successfully tagged shellform:latest

###查看镜像。
root@docker:~# docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
shellform    latest    74dae56ad62b   53 seconds ago   72.8MB
execform     latest    9a9ad5e91072   12 minutes ago   72.8MB
ubuntu       latest    ba6acccedd29   15 months ago    72.8MB

###运行容器,--rm参数,容器停止后自动删除容器。
root@docker:~# docker run --rm --name shellform -it shellform

      容器运行效果:

###再另外开启一个新终端。
###查看内容器运行状态信息。
root@docker:~# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS     NAMES
e656d89e3d1f   shellform   "/bin/sh -c 'watch -…"   28 minutes ago   Up 28 minutes             shellform

###执行ps命令查看容器进程情况,可以看到比exec多了一个/bin/sh的进程,且它的PID是1。
root@docker:~# docker exec -it shellform ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 10:26 pts/0    00:00:00 /bin/sh -c watch -n 1 date
root           7       1  0 10:26 pts/0    00:00:01 watch -n 1 date
root        4199       0  0 10:49 pts/1    00:00:00 ps -ef

###执行停止容器命令,明显要比exec模式慢。
root@docker:~# docker stop shellform
shellform

     再来看一个例子。

exec form

Dockerfile内容:
FROM centos
ARG app=httpd
RUN ["yum","install","-y","$app"]
###执行创建镜像命令,最后失败了,失败的原因是exec模式没有对变量进行替换。
root@docker:~# docker build -t execform -f Dockerfile .
Sending build context to Docker daemon  66.56kB
Step 1/3 : FROM centos
 ---> dea00f9b3407
Step 2/3 : ARG app=httpd
 ---> Using cache
 ---> 0c50017f9ea3
Step 3/3 : RUN ["yum","install","-y","$app"]
 ---> Running in 4e6693c278af
Last metadata expiration check: 0:04:34 ago on Fri Jan 20 16:18:48 2023.
No match for argument: $app
Error: Unable to find a match: $app
The command 'yum install -y $app' returned a non-zero code: 1

shell form

Dockerfile内容:
FROM centos
ARG app=httpd
RUN yum install -y $app
###构建镜像,可以成功构建。
root@docker:~# docker build -t shellform -f Dockerfile .
Sending build context to Docker daemon  66.56kB
Step 1/3 : FROM centos
 ---> dea00f9b3407
Step 2/3 : ARG app=httpd
 ---> Running in 58e9499fe5ea
Removing intermediate container 58e9499fe5ea
 ---> 0c50017f9ea3
Step 3/3 : RUN   yum install -y $app
 ---> Running in 2e184a123c2c
Last metadata expiration check: 0:02:57 ago on Fri Jan 20 16:18:48 2023.
Dependencies resolved.
================================================================================
 Package          Arch   Version                                Repo       Size
================================================================================
Installing:
 httpd            x86_64 2.4.37-43.module_el8.5.0+1022+b541f3b1 AppStream 1.4 M
Installing dependencies:
 apr              x86_64 1.6.3-12.el8                           AppStream 129 k
 apr-util         x86_64 1.6.1-6.el8                            AppStream 105 k
 brotli           x86_64 1.0.6-3.el8                            base      323 k
 centos-logos-httpd
                  noarch 85.8-2.el8                             base       75 k
 httpd-filesystem noarch 2.4.37-43.module_el8.5.0+1022+b541f3b1 AppStream  39 k
 httpd-tools      x86_64 2.4.37-43.module_el8.5.0+1022+b541f3b1 AppStream 107 k
 mailcap          noarch 2.1.48-3.el8                           base       39 k
 mod_http2        x86_64 1.15.7-3.module_el8.4.0+778+c970deab   AppStream 154 k
Installing weak dependencies:
 apr-util-bdb     x86_64 1.6.1-6.el8                            AppStream  25 k
 apr-util-openssl x86_64 1.6.1-6.el8                            AppStream  27 k
Enabling module streams:
 httpd                   2.4                                                   

Transaction Summary
================================================================================
Install  11 Packages

Total download size: 2.4 M
Installed size: 7.1 M
Downloading Packages:
(1/11): mailcap-2.1.48-3.el8.noarch.rpm          90 kB/s |  39 kB     00:00    
(2/11): centos-logos-httpd-85.8-2.el8.noarch.rp 151 kB/s |  75 kB     00:00    
(3/11): apr-util-1.6.1-6.el8.x86_64.rpm         208 kB/s | 105 kB     00:00    
(4/11): apr-1.6.3-12.el8.x86_64.rpm             192 kB/s | 129 kB     00:00    
(5/11): apr-util-bdb-1.6.1-6.el8.x86_64.rpm     133 kB/s |  25 kB     00:00    
(6/11): apr-util-openssl-1.6.1-6.el8.x86_64.rpm 182 kB/s |  27 kB     00:00    
(7/11): httpd-filesystem-2.4.37-43.module_el8.5 148 kB/s |  39 kB     00:00    
(8/11): brotli-1.0.6-3.el8.x86_64.rpm           200 kB/s | 323 kB     00:01    
(9/11): httpd-tools-2.4.37-43.module_el8.5.0+10 201 kB/s | 107 kB     00:00    
(10/11): mod_http2-1.15.7-3.module_el8.4.0+778+ 196 kB/s | 154 kB     00:00    
(11/11): httpd-2.4.37-43.module_el8.5.0+1022+b5 222 kB/s | 1.4 MB     00:06    
--------------------------------------------------------------------------------
Total                                           321 kB/s | 2.4 MB     00:07     
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                        1/1 
  Installing       : apr-1.6.3-12.el8.x86_64                               1/11 
  Running scriptlet: apr-1.6.3-12.el8.x86_64                               1/11 
  Installing       : apr-util-bdb-1.6.1-6.el8.x86_64                       2/11 
  Installing       : apr-util-openssl-1.6.1-6.el8.x86_64                   3/11 
  Installing       : apr-util-1.6.1-6.el8.x86_64                           4/11 
  Running scriptlet: apr-util-1.6.1-6.el8.x86_64                           4/11 
  Installing       : httpd-tools-2.4.37-43.module_el8.5.0+1022+b541f3b1    5/11 
  Running scriptlet: httpd-filesystem-2.4.37-43.module_el8.5.0+1022+b54    6/11 
  Installing       : httpd-filesystem-2.4.37-43.module_el8.5.0+1022+b54    6/11 
  Installing       : mailcap-2.1.48-3.el8.noarch                           7/11 
  Installing       : centos-logos-httpd-85.8-2.el8.noarch                  8/11 
  Installing       : brotli-1.0.6-3.el8.x86_64                             9/11 
  Installing       : mod_http2-1.15.7-3.module_el8.4.0+778+c970deab.x86   10/11 
  Installing       : httpd-2.4.37-43.module_el8.5.0+1022+b541f3b1.x86_6   11/11 
  Running scriptlet: httpd-2.4.37-43.module_el8.5.0+1022+b541f3b1.x86_6   11/11 
  Verifying        : brotli-1.0.6-3.el8.x86_64                             1/11 
  Verifying        : centos-logos-httpd-85.8-2.el8.noarch                  2/11 
  Verifying        : mailcap-2.1.48-3.el8.noarch                           3/11 
  Verifying        : apr-1.6.3-12.el8.x86_64                               4/11 
  Verifying        : apr-util-1.6.1-6.el8.x86_64                           5/11 
  Verifying        : apr-util-bdb-1.6.1-6.el8.x86_64                       6/11 
  Verifying        : apr-util-openssl-1.6.1-6.el8.x86_64                   7/11 
  Verifying        : httpd-2.4.37-43.module_el8.5.0+1022+b541f3b1.x86_6    8/11 
  Verifying        : httpd-filesystem-2.4.37-43.module_el8.5.0+1022+b54    9/11 
  Verifying        : httpd-tools-2.4.37-43.module_el8.5.0+1022+b541f3b1   10/11 
  Verifying        : mod_http2-1.15.7-3.module_el8.4.0+778+c970deab.x86   11/11 

Installed:
  apr-1.6.3-12.el8.x86_64                                                       
  apr-util-1.6.1-6.el8.x86_64                                                   
  apr-util-bdb-1.6.1-6.el8.x86_64                                               
  apr-util-openssl-1.6.1-6.el8.x86_64                                           
  brotli-1.0.6-3.el8.x86_64                                                     
  centos-logos-httpd-85.8-2.el8.noarch                                          
  httpd-2.4.37-43.module_el8.5.0+1022+b541f3b1.x86_64                           
  httpd-filesystem-2.4.37-43.module_el8.5.0+1022+b541f3b1.noarch                
  httpd-tools-2.4.37-43.module_el8.5.0+1022+b541f3b1.x86_64                     
  mailcap-2.1.48-3.el8.noarch                                                   
  mod_http2-1.15.7-3.module_el8.4.0+778+c970deab.x86_64                         

Complete!
Removing intermediate container 2e184a123c2c
 ---> edaed2fc23b0
Successfully built edaed2fc23b0
Successfully tagged shellform:latest

       RUN 指令是在 docker build 构建 docker 镜像时执行的命令,推荐使用 shell 模式,shell 模式书写简洁,而且可以使用变量,多个命令可以使用 && 进行连接,可以减少镜像的层数。

       ENTRYPOINT 和 CMD 指令用于指定容器启动时需要运行的命令,推荐使用 exec 模式。如果使用shell 模式,程序会以 /bin/sh -c 的子命令启动,shell 进程默认不会处理 SIGTERM 信号,自己不会退出,也不会将信号传递给子进程,导致业务程序不会触发停止逻辑,只能等待超时关闭。

      

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AtobeKegio

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值