在Docker中向Golang应用程序发送信号

eha*_*enr 3 go docker boot2docker dockerfile

我正在尝试运行在docker容器内的golang编写的服务器.例如:

package main

import "net/http"

func main() {
  http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello"))
  })
  http.ListenAndServe(":3000", nil)
}
Run Code Online (Sandbox Code Playgroud)

如果我在我的本地机器上运行此代码,我可以把它SIGINTCtrl-C,它会关闭应用程序.当我在一个docker容器中运行它时,我似乎无法用它来杀死它Ctrl-C.

# Dockerfile
FROM ubuntu:14.04

RUN apt-get update && apt-get -y upgrade
RUN apt-get install -y golang

ENV GOPATH /go

COPY . /go/src/github.com/ehaydenr/simple_server

RUN cd /go/src/github.com/ehaydenr/simple_server && go install

CMD /go/bin/simple_server
Run Code Online (Sandbox Code Playgroud)

然后我继续使用docker向容器发送信号.

docker kill --signal=INT 9354f574afd4
Run Code Online (Sandbox Code Playgroud)

仍在运行...

docker kill --signal=TERM 9354f574afd4
Run Code Online (Sandbox Code Playgroud)

仍在运行...

docker kill --signal=KILL 9354f574afd4
Run Code Online (Sandbox Code Playgroud)

终于死了.

我没有在代码中捕获任何信号而忽略它们.我甚至尝试增加上面的代码来捕获信号并将它们打印出来(它可以在我的主机上运行,​​但是当它在容器中时,就像信号永远不会进入程序一样).

有谁之前经历过这个吗?我还没有尝试过这样的事情在另一种语言,但我能杀服务器(例如mongo,nginx)使用Ctrl-C,而他们是在一个码头工人容器..为什么不去会得到的信号?

不确定这是否有所作为,但我在OSX上并使用docker-machine.

任何帮助深表感谢.

Jim*_*imB 7

您正在shell中运行服务器,shell是接收信号的进程.在强制shell退出之前,您的服务器不会退出.

当您使用CMD的"shell"形式时,它会将您的服务器作为参数启动/bin/sh -c.为了直接执行服务器二进制文件,您需要从CMD或ENTRYPOINT提供一个参数数组,从可执行文件的完整路径开始.

CMD ["/go/bin/simple_server"]
Run Code Online (Sandbox Code Playgroud)

来自Dockerfile文档中 ENTRYPOINT的注释:

shell表单可以防止使用任何CMD或运行命令行参数,但缺点是ENTRYPOINT将作为/ bin/sh -c的子命令启动,它不传递信号.