ENTRYPOINT
EXTRYPOING指令指定容器启动后运行的可执行文件
语法
有2种书写格式:
ENTRYPOINT ["executable", "param1", "param2"](exec形式,推荐)ENTRYPOINT command param1 param2(shell形式)
可以在使用docker run命令启动容器时添加executable参数,
- 对于
exec形式的ENTRYPOINT指令- 命令行参数将添加到
exec表达式的参数之后,同时重写CMD指令指定的参数。比如执行docker run <image> -d,则-d将会作为入口点的参数 - 可以使用标识符
--entrypoint重写ENTRYPOINT指令
- 命令行参数将添加到
- 对于
shell形式的ENTRYPOINT指令,不会使用CMD或docker run添加的参数
Dockerfile文件中只有最后一条ENTRYPOINT指令其作用
Exec形式示例
FROM zjykzj/ubuntu:18.04
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
完整的入口点命令为top -b -c。启动该容器后,仅有该应用运行
启动容器如下:
# 镜像名为top:v4
$ docker run -it --rm --name test top:v4
top - 06:01:45 up 4:26, 0 users, load average: 0.20, 0.38, 0.37
Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.7 us, 0.5 sy, 0.0 ni, 97.6 id, 0.1 wa, 0.0 hi, 0.1 si, 0.0 st
KiB Mem : 16164188 total, 8438760 free, 3265344 used, 4460084 buff/cache
KiB Swap: 15999996 total, 15999996 free, 0 used. 11943604 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 36484 3036 2688 R 0.0 0.0 0:00.21 top
也可通过docker exec验证
$ docker exec fde5 ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.4 0.0 36484 3020 pts/0 Ss+ 06:05 0:00 top -b
root 11 0.0 0.0 34400 2860 ? Rs 06:06 0:00 ps aux
注意 1:exec形式作为JSON数组,使用双引号而不是单引号
注意 2:exec形式不会调用命令行shell,所以如果要进行shell处理必须显式调用/bin/sh -c,比如ENTRYPOING ["sh", "-c", "echo $HOME"]
Shell形式示例
shell形式的缺点在于其作为/bin/sh -c的子命令,不会输入信号。这意味着可执行文件不是容器的PID 1,不会接收到Unix信号,所以可执行文件无法接受来自docker stop <container>的SIGTERM信号。此时运行docker stop,容器不会干净地退出,stop命令将在超时后强制发送SIGKILL指令
可以指定exec启动命令,这样就能得到PID 1的入口程序
FROM zjykzj/ubuntu:18.04
ENTRYPOINT exec top -b
创建镜像top并启动
$ docker run -t top .
$ docker run -it --rm --name test top
top - 06:17:18 up 4:41, 0 users, load average: 0.43, 0.65, 0.54
Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.8 us, 0.5 sy, 0.0 ni, 97.5 id, 0.1 wa, 0.0 hi, 0.1 si, 0.0 st
KiB Mem : 16164188 total, 8468692 free, 3225808 used, 4469688 buff/cache
KiB Swap: 15999996 total, 15999996 free, 0 used. 11979700 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 36484 2956 2604 R 0.0 0.0 0:00.21 top
可使用/usr/bin/time测试docker top停止镜像的运行时间
对于镜像top,测试如下
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dc47139817b3 top "/bin/sh -c 'exec to…" 2 minutes ago Up 2 minutes test
(base) zj@zj-ThinkPad-T470p:~$ /usr/bin/time docker stop dc47
dc47
0.01user 0.02system 0:00.52elapsed 7%CPU (0avgtext+0avgdata 63500maxresident)k
0inputs+0outputs (0major+7827minor)pagefaults 0swaps
对于不使用exec命令的Shell形式,测试如下:
$ /usr/bin/time docker stop f5fe
f5fe
0.01user 0.02system 0:10.68elapsed 0%CPU (0avgtext+0avgdata 62684maxresident)k
0inputs+0outputs (0major+7923minor)pagefaults 0swaps
前者花费了0.52秒,后者花费了10.68秒
CMD和ENTRYPOINT的交互
CMD和ENTRYPOINT指令都定义了运行容器时执行的命令,其合作如下:
Dockerfile文件应该至少定义一条CMD或ENTRYPOINT指令ENTRYPOING适用于将容器作为可执行文件的场景CMD适用于定义ENTRYPOINT命令在容器中执行特殊命令的默认参数- 使用可选参数运行容器时,将重写
CMD
注意:如果CMD指令定义在基础镜像,那么ENTRYPOINT将会重置CMD为空。如果需要CMD指令操作,必须在当前镜像上重写
