可以在多克容器不能捕获SIGINT

问题描述:

我有以下的图像可以在多克容器不能捕获SIGINT

FROM golang:1.8.3 
WORKDIR /go/src/x/x/program 
RUN mkdir /logs 
VOLUME ["/go/src/x/x/program", "/logs"] 
CMD ["sh", "-c", "go install && program"] 

我的围棋服务器侦听通过以下方式

// ... Other stuff 

c := make(chan os.Signal, 1) 
signal.Notify(c, os.Interrupt) 

go func() { 
    <-c 
    signal.Stop(c) 

    // Server graceful shutdown 
    err := s.Shutdown(context.Background()) 
    if err != nil { 
     fileLogger.Printf("could not shutdown server: %v", err) 
    } else { 
     fileLogger.Print("server successfully shutdown") 
    } 

// ... Start server 

到SIGINT但我没能捕获并处理SIGINT 。我试过如下:

  • docker kill -s SIGINT <my_container>
  • (与撰写)docker-compose down/kill
  • docker exec -ti <my_container> /bin/bash
    • (后面)kill -SIGINT <go program PID>

没有得到记录,所以我想SIGINT不是由我的公关处理的一点都不。


测试时,我设法做到这一点通过执行以下操作(这是不适合用于生产)

  • docker run -ti -v <local_path_to_log>:/logs <my_image> /bin/bash
    • go run *.go
    • CTRL + C中断过程

我在我的文件中看到日志。

我也只是想出了该方法我的图像被设置时,它最终有运行两个过程:

docker exec -ti <my_container> /bin/bash 
[email protected]:/go/src/x/x/x# ps aux | grep program 
root   1 0.0 0.0 4332 716 ?  Ss 03:47 0:00 sh -c go install && program 
root  32 0.0 0.3 335132 6624 ?  Sl 03:47 0:00 program 
[email protected]:/go/src/x/x/x# kill -SIGINT 32 

所以如上述所示,杀死所述第二过程(而不是PID 1)发送信号情报到程序,它可以比陷阱和处理它。


我知道我接近从容器外部发送SIGINT的解决方案。但我还没有把握。

在这里有一个正确的方法有一个容器可以接收SIGINT到正确的过程?

码头工人将信号传递给PID 1进程。就你而言,由于你产生了一个孩子的过程,你没有得到信号。 如果只有1处理CMD,你可以这样做:

CMD ["/bin/ping","localhost"] 

如果你是做多操作,如你在上面说,你可以运行CMD脚本,并在脚本中有信号处理并将其传递给您的后台进程。另一种选择是在CMD中只有一个命令处理。您可以在上一步中执行“安装”,然后在CMD中运行可执行文件。

+0

我写了构建和运行程序的脚本。我如何将信号传递给子进程? – sargas

+0

这是我见过的处理脚本中的信号并传递到另一个进程的方法(https://medium.com/@gchudnov/trapping-signals-in-docker-containers-7a57fdda7d86)。如果你可以避免脚本,只有一个进程,那更好。 – Sreeni