首页 > 学院 > 系统知识 > 正文

怎样优雅的关闭容器,看本文就够了

2022-07-09 12:57:43
字体:
来源:转载
供稿:网友
1 信号
信号是事件发生时对进程的通知机制,有时也称之为软件中断。
 
信号有不同的类型,Linux 对标准信号的编号为 1~31,可以通过 kill -l 获取信号名称:
 
# kill -l  
 1) SIGHUP       2) SIGINT       3) SIGQUIT     
 4) SIGILL       5) SIGTRAP      6) SIGABRT    
 7) SIGBUS       8) SIGFPE       9) SIGKILL
 10) SIGUSR1    11) SIGSEGV     12) SIGUSR2
 13) SIGPIPE    14) SIGALRM     15) SIGTERM
... ...
实际列出的信号超过了 31 个,有些是其它名称的同义词,有些则是定义但未使用的。以下介绍几个常用的信号:
 
 1) SIGHUP 当终端断开(挂机)时,将发送该信号给终端控制进程。SIGHUP 信号还可用于守护进程(比如,init 等)。许多守护进程会在收到 SIGHUP 信号时重新进行初始化并重读配置文件。
 2) SIGINT 当用户键入终端中断字符(通常为 Control-C ) 时,终端驱动程序将发送该信号给前台进程组。该信号的默认行为是终止进程。
 3) SIGQUIT 当用户在键盘上键入退出字符(通常为 Control-/ )时,该信号将发往前台进程组。默认情况下,该信号终止进程,并生成用于调试的核心转储文件。进程如果陷入无限循环,或者不再响应时,使用 SIGQUIT 信号就很合适。
 9) SIGKILL 此信号为 “必杀(sure kill)” 信号,处理器程序无法将其阻塞、忽略或者捕获,故而 “一击必杀”,总能终止程序。
 15) SIGTERM 这是用来终止进程的标准信号,也是 kill 、 killall 、 pkill 命令所发送的默认信号。精心设计的应用程序应当为 SIGTERM 信号设置处理器程序,以便其能够预先清除临时文件和释放其它资源,从而全身而退。因此,总是应该先尝试使用 SIGTERM 信号来终止进程,而把 SIGKILL 作为最后手段,去对付那些不响应 SIGTERM 信号的失控进程。
 20) SIGTSTP 这是作业控制的停止信号,当用户在键盘上输入挂起字符(通常为 Control-Z )时,将该信号给前台进程组,使其停止运行。
值得注意的是, Control-D 不会发起信号,它表示 EOF(End-Of-File),关闭标准输入(stdin)管道(比如可以通过 Control-D 退出当前 shell)。如果程序不读取当前输入的话,是不受 Control-D 影响的。
2 ENTRYPOINT 、 CMD
可能有人会问,说了半天,那信号和优雅的关闭容器有半毛钱的关系啊?话说,这和钱确实没关系,但是和如何优雅关闭容器却关系密切。
 
接着说 Dockerfile 中的 ENTRYPOINT 和 CMD 指令,它们的主要功能是指定容器启动时执行的程序。
 
CMD 有三种格式:
 
 CMD ["executable","param1","param2"] (exec 格式, 推荐使用这种格式)
 CMD ["param1","param2"] (作为 ENTRYPOINT 指令参数)
 CMD command param1 param2 (shell 格式,默认 /bin/sh -c )
ENTRYPOINT 有两种格式:
 
 ENTRYPOINT ["executable", "param1", "param2"] (exec 格式,推荐优先使用这种格式)
 ENTRYPOINT command param1 param2 (shell 格式)
其中,不管你 Dockerfile 用其中哪个指令,两个指令都推荐使用 exec 格式,而不是 shell 格式。原因就是因为使用 shell 格式之后,程序会以 /bin/sh -c 的子命令启动,并且 shell 格式下不会传递任何信号给程序。这也就导致,在 docker stop 容器的时候,以这种格式运行的程序捕捉不到发送的信号,也就谈不上优雅的关闭了。
 
➜  ~ docker stop --help  
Usage:  docker stop [OPTIONS] CONTAINER [CONTAINER...]  
Stop one or more running containers  
Options:  
      --help       Print usage  
  -t, --time int   Seconds to wait for stop before killing it (default 10)
docker stop 停掉容器的时候,默认会发送一个 SIGTERM 的信号,默认 10s 后容器没有停止的话,就 SIGKILL 强制停止容器。通过 -t 选项可以设置等待时间。
 
➜  ~ docker kill --help  
Usage:  docker kill [OPTIONS] CONTAINER [CONTAINER...]  
Kill one or more running containers  
Options:  
      --help            Print usage  
  -s, --signal string   Signal to send to the container (default "KILL")
通过 docker kill 的 -s 选项还可以指定给容器发送的信号。
 
所以,说了那么多,只要 Dockerfile 中通过 exec 格式执行容器启动命令就相安无事了?那当然是,没有那么简单的了,接下来我们通过实例来看看具体的效果是怎么样的。2 ENTRYPOINT 、 CMD
可能有人会问,说了半天,那信号和优雅的关闭容器有半毛钱的关系啊?话说,这和钱确实没关系,但是和如何优雅关闭容器却关系密切。
 
接着说 Dockerfile 中的 ENTRYPOINT 和 CMD 指令,它们的主要功能是指定容器启动时执行的程序。
 
CMD 有三种格式:
 
 CMD ["executable","param1","param2"] (exec 格式, 推荐使用这种格式)
 CMD ["param1","param2"] (作为 ENTRYPOINT 指令参数)
 CMD command param1 param2 (shell 格式,默认 /bin/sh -c )
ENTRYPOINT 有两种格式:
 
 ENTRYPOINT ["executable", "param1", "param2"] (exec 格式,推荐优先使用这种格式)
 ENTRYPOINT command param1 param2 (shell 格式)
其中,不管你 Dockerfile 用其中哪个指令,两个指令都推荐使用 exec 格式,而不是 shell 格式。原因就是因为使用 shell 格式之后,程序会以 /bin/sh -c 的子命令启动,并且 shell 格式下不会传递任何信号给程序。这也就导致,在 docker stop 容器的时候,以这种格式运行的程序捕捉不到发送的信号,也就谈不上优雅的关闭了。
 
➜  ~ docker stop --help  
Usage:  docker stop [OPTIONS] CONTAINER [CONTAINER...]  
Stop one or more running containers  
Options:  
      --help       Print usage  
  -t, --time int   Seconds to wait for stop before killing it (default 10)
docker stop 停掉容器的时候,默认会发送一个 SIGTERM 的信号,默认 10s 后容器没有停止的话,就 SIGKILL 强制停止容器。通过 -t 选项可以设置等待时间。
 
➜  ~ docker kill --help  
Usage:  docker kill [OPTIONS] CONTAINER [CONTAINER...]  
Kill one or more running containers  
Options:  
      --help            Print usage  
  -s, --signal string   Signal to send to the container (default "KILL")
通过 docker kill 的 -s 选项还可以指定给容器发送的信号。
 
所以,说了那么多,只要 Dockerfile 中通过 exec 格式执行容器启动命令就相安无事了?那当然是,没有那么简单的了,接下来我们通过实例来看看具体的效果是怎么样的。

(编辑:错新网)

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表