2017-07-31 61 views
0

我有以下的圖像可以在多克容器不能捕獲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到正確的過程?

回答

0

碼頭工人將信號傳遞給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

相關問題