英文:
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 应用程序中被处理,通过在退出之前执行清理代码来处理。在这种情况下,代码是在退出之前执行的单个日志语句。
问题
- 是否保证在执行这个语句之前容器不会停止存在?
- 如果是,这是否适用于其他信号?
- 如果不是,是否有其他信号适用于这个情况?
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
- Is it guaranteed that container won't cease to exist before this statement is executed?
- If yes does it apply to other signals?
- If no are there signals to which this do apply?
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") // 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论