Is it safe to shutdown go application running inside a container this way on `docker kill –signal=SIGX`?

huangapple go评论72阅读模式
英文:

Is it safe to shutdown go application running inside a container this way on `docker kill --signal=SIGX`?

问题

上下文

有一个运行在 Docker 容器中的应用程序。当发送 docker stop %container_id% 命令时,容器会接收到 SIGTERM 信号。这个信号在 Golang 应用程序中被处理,通过在退出之前执行清理代码来处理。在这种情况下,代码是在退出之前执行的单个日志语句。

问题

  1. 是否保证在执行这个语句之前容器不会停止存在?
  2. 如果是,这是否适用于其他信号?
  3. 如果不是,是否有其他信号适用于这个情况?
func main() {
    http.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(rw, "chirtkem mudila")
    })

    go func() {
        if err := http.ListenAndServe(":8080", nil); err != nil {
            log.Fatal(err)
        }
    }()

    interupt := make(chan os.Signal, 1)
    signal.Notify(interupt, syscall.SIGTERM, syscall.SIGINT)
    <-interupt

    log.Println("graceful shutdown") // 是否保证在容器停止存在之前执行?
}
英文:

Context

There is an app running inside docker container. When docker stop %container_id% is sent the container receives SIGTERM. This signal is handled inside golang application via executing cleanup code before exiting. In this case code is a single log statement before exiting.

Questions

  1. Is it guaranteed that container won't cease to exist before this statement is executed?
  2. If yes does it apply to other signals?
  3. If no are there signals to which this do apply?
func main() {
    http.HandleFunc(&quot;/&quot;, func(rw http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(rw, &quot;chirtkem mudila&quot;)
    })

    go func() {
        if err := http.ListenAndServe(&quot;:8080&quot;, nil); err != nil {
            log.Fatal(err)
        }
    }()

    interupt := make(chan os.Signal, 1)
    signal.Notify(interupt, syscall.SIGTERM, syscall.SIGINT)
    &lt;-interupt

    log.Println(&quot;graceful shutdown&quot;) // is it guaranteed to execute before container ceases to exist?
}

答案1

得分: 2

在执行docker stop %container_id%命令时,Docker会发送SIGTERM信号,并等待一段时间(默认为10秒),然后发送SIGKILL信号。

可以使用--time选项来配置这个等待时间,具体请参考文档

用法:docker stop [选项] CONTAINER [CONTAINER...]
停止一个或多个正在运行的容器
选项:
  -t, --time int   在终止之前等待的秒数(默认为10)

因此,如果执行的语句需要的时间超过这个等待时间,不能保证容器在语句执行完成时仍然存活。

对于问题(2)和(3),由于问题(1)的答案是否定的,并且docker stop命令没有覆盖信号的选项,所以不适用于其他信号。

docker kill命令可以使用--signal标志来覆盖信号,默认为SIGKILL。具体请参考文档

> 虽然默认的信号(SIGKILL)会终止容器,但通过--signal设置的信号可能是非终止的,这取决于容器的主进程。例如,大多数情况下,SIGHUP信号是非终止的,容器在接收到信号后将继续运行。

因此,根据命令中提供的信号,容器在处理信号后可能会被终止或继续运行。

英文:

In case of docker stop %container_id% docker sends SIGTERM and waits for timeout, default 10 seconds, and sends a SIGKILL.

This timeout is configurable with --time option, docs

Usage:  docker stop [OPTIONS] CONTAINER [CONTAINER...]
Stop one or more running containers
Options:
  -t, --time int   Seconds to wait for stop before killing it (default 10)

Thus (1) it is not guaranteed that the container will be alive during completion of the statement, if the statement takes more than this time.

For (2) and (3) As (1) is a no and docker stop has no override for signals, does not apply to other signals.

docker kill has an override for signal, default being SIGKILL, with --signal flag. docs

> While the default (SIGKILL) signal will terminate the container, the
> signal set through --signal may be non-terminal, depending on the
> container’s main process. For example, the SIGHUP signal in most cases
> will be non-terminal, and the container will continue running after
> receiving the signal.

Thus depending on the signal supplied in command, the container may or may not be killed after processing of signal.

huangapple
  • 本文由 发表于 2022年9月3日 19:56:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/73592068.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定