docker容器如何优雅的终止详解

2020-06-17 06:38:03易采站长站整理
docker stop
命令的时候,我们唯一能控制的是超时时间,比如设置为20秒超时:


docker stop --time=20 container_name

docker kill

接着我们来看看

docker kill
命令,默认情况下,
docker kill
命令不会给容器中的应用程序有任何gracefully shutdown的机会。它会直接发出SIGKILL的系统信号,以强行终止容器中程序的运行。通过查看
docker kill
命令的帮助,我们可以看到,除了默认发送SIGKILL信号外,还允许我们发送一些自定义的系统信号:


→ 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中的程序发送SIGINT信号,我们可以这样来实现:


docker kill --signal=SIGINT container_name

与docker stop命令不一样的地方在于,

docker kill
没有任何的超时时间设置,它会直接发送SIGKILL信号,以及用户通过signal参数指定的其他信号。

其实不难看出,docker stop命令,更类似于Linux系统中的kill命令,二者都是发送系统信号SIGTERM。而

docker kill
命令,更像是Linux系统中的kill -9或者是kill -SIGKILL命令,用来发送SIGKILL信号,强行终止进程。

在程序中接收并处理信号

了解了

docker stop
docker kill
的区别,我们能够知道,
docker kill
适合用来强行终止程序并实现快速停止容器。而如果希望程序能够gracefully shutdown的话,
docker stop
才是不二之选。这样,我们可以让程序在接收到SIGTERM信号后,有一定的时间处理、保存程序执行现场,优雅的退出程序。

接下来我们可以写一个简单的Go程序来实现信号的接收与处理,程序在启动过后,会一直阻塞并监听系统信号,直到监测到对应的系统信号后,输出控制台并退出执行。


// main.go
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
fmt.Println("Program started...")
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGTERM)
s := <-ch
if s == syscall.SIGTERM {
fmt.Println("SIGTERM received!")