容器进程优雅退出

strace 工具

在我们用 docker stop 停止这个容器的时候,如果用 strace 工具来监控,就能看到容器里的 init 进程和另外一个进程收到的信号情况。

进程号为 15909 的就是容器里的 init 进程,而进程号为 15959 的是容器里另外一个进程。

在命令输出中我们可以看到,init 进程(15909)收到的是 SIGTERM 信号,而另外一个进程(15959)收到的果然是 SIGKILL 信号。

# ps -ef | grep c-init-sig
root     15857 14391  0 06:23 pts/0    00:00:00 docker run -it registry/fwd_sig:v1 /c-init-sig
root     15909 15879  0 06:23 pts/0    00:00:00 /c-init-sig
root     15959 15909  0 06:23 pts/0    00:00:00 /c-init-sig
root     16046 14607  0 06:23 pts/3    00:00:00 grep --color=auto c-init-sig

# strace -p 15909
strace: Process 15909 attached
restart_syscall(<... resuming interrupted read ...>) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
--- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=0, si_uid=0} ---
write(1, "received SIGTERM\n", 17)      = 17
exit_group(0)                           = ?
+++ exited with 0 +++

# strace -p 15959
strace: Process 15959 attached
restart_syscall(<... resuming interrupted read ...>) = ?
+++ killed by SIGKILL +++

信号注册

通过 signal() 这个系统调用,为这个信号注册一个特殊的 handler。

如果我们用 signal() 为 SIGKILL 注册 handler,那么它就会返回 SIG_ERR,不允许我们做捕获操作。

# cat reg_sigkill.c
#include 
#include 
#include 
#include 
#include 

typedef void (*sighandler_t)(int);

void sig_handler(int signo)
{
            if (signo == SIGKILL) {
                        printf("received SIGKILL\n");
                        exit(0);
            }
}
 
int main(int argc, char *argv[])
{
            sighandler_t h_ret;

            h_ret = signal(SIGKILL, sig_handler);
            if (h_ret == SIG_ERR) {
                        perror("SIG_ERR");
            }
            return 0;
}

# ./reg_sigkill
SIG_ERR: Invalid argument

你可能感兴趣的:(容器技术,linux,运维,服务器)