docker 退出机制

docker 的退出有两种

  1. docker stop
  2. docker kill

docker stop

在docker stop命令执行的时候,会先向容器中PID为1的进程发送系统信号SIGTERM,然后等待容器中的应用程序终止执行,如果等待时间达到设定的超时时间,或者默认的10秒,会继续发送SIGKILL的系统信号强行kill掉进程。在容器中的应用程序,可以选择忽略和不处理SIGTERM信号,不过一旦达到超时时间,程序就会被系统强行kill掉,因为SIGKILL信号是直接发往系统内核的,应用程序没有机会去处理它。在使用docker stop命令的时候,我们唯一能控制的是超时时间,比如设置为20秒超时:

docker stop --time=20 container_name

docker kill

接着我们来看看docker kill命令,默认情况下,docker kill命令不会给容器中的应用程序有任何gracefully shutdown的机会。它会直接发出SIGKILL的系统信号,以强行终止容器中程序的运行。

程序进行配合

在第一种方式docker stop的时候我们的程序有10S中的时间来处理好未处理的事情。 .net core 是用下面的两个事件来处理的 在windows的情况下可以用ctrl+c 来模拟 (直接去点console的X是没有机会处理到它的)

//主要是处理这两个事件
Console.CancelKeyPress += Console_CancelKeyPress;
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;

//我们可以对cancellationTokenSource进行Cancel
cancellationTokenSource.Cancel()

golang是可以直接接收到这个信号

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!")
		//Do something...
	}

	fmt.Println("Exiting...")
}

如果我们的docker是主要跑在K8s的环境下的话,在k8s里面我们有一个额外的处理方式 preStop

最近更新的
...