在 Docker 中向 Golang 应用程序发送信号
Sending signals to Golang application in Docker
我正在尝试 运行 在 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)
}
如果我在我的本地机器上 运行 这段代码,我可以用 Ctrl-C 发送 SIGINT
它会关闭应用程序。当我 运行 它在 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
然后我继续使用 docker 向容器发送信号。
docker kill --signal=INT 9354f574afd4
还在运行宁...
docker kill --signal=TERM 9354f574afd4
还在运行宁...
docker kill --signal=KILL 9354f574afd4
终于死了
我没有在我的代码中捕捉到任何信号并忽略它们。我什至尝试扩充上面的代码以捕获信号并将它们打印出来(这在我的主机上有效,但在容器中时,就好像信号从未到达程序一样)。
有没有人遇到过这种情况?我没有用另一种语言尝试过类似的东西,但是我可以使用 Ctrl-C 杀死服务器(例如 mongo
、nginx
)在 docker 容器中。为什么 Go 没有收到信号?
不确定这是否有影响,但我在 OSX 上并使用 docker-machine。
非常感谢任何帮助。
你是 运行 你的服务器在 shell 里面,shell 是接收信号的进程。在您强制 shell 退出之前,您的服务器不会退出。
当您使用 "shell" 形式的 CMD 时,它将作为 /bin/sh -c
的参数启动您的服务器。为了直接执行服务器二进制文件,您需要向 CMD 或 ENTRYPOINT 提供一个参数数组,从可执行文件的完整路径开始。
CMD ["/go/bin/simple_server"]
来自 ENTRYPOINT 的注释 Dockerfile docs:
The shell form prevents any CMD or run command line arguments from being used, but has the disadvantage that your ENTRYPOINT will be started as a subcommand of /bin/sh -c, which does not pass signals.
我正在尝试 运行 在 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)
}
如果我在我的本地机器上 运行 这段代码,我可以用 Ctrl-C 发送 SIGINT
它会关闭应用程序。当我 运行 它在 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
然后我继续使用 docker 向容器发送信号。
docker kill --signal=INT 9354f574afd4
还在运行宁...
docker kill --signal=TERM 9354f574afd4
还在运行宁...
docker kill --signal=KILL 9354f574afd4
终于死了
我没有在我的代码中捕捉到任何信号并忽略它们。我什至尝试扩充上面的代码以捕获信号并将它们打印出来(这在我的主机上有效,但在容器中时,就好像信号从未到达程序一样)。
有没有人遇到过这种情况?我没有用另一种语言尝试过类似的东西,但是我可以使用 Ctrl-C 杀死服务器(例如 mongo
、nginx
)在 docker 容器中。为什么 Go 没有收到信号?
不确定这是否有影响,但我在 OSX 上并使用 docker-machine。
非常感谢任何帮助。
你是 运行 你的服务器在 shell 里面,shell 是接收信号的进程。在您强制 shell 退出之前,您的服务器不会退出。
当您使用 "shell" 形式的 CMD 时,它将作为 /bin/sh -c
的参数启动您的服务器。为了直接执行服务器二进制文件,您需要向 CMD 或 ENTRYPOINT 提供一个参数数组,从可执行文件的完整路径开始。
CMD ["/go/bin/simple_server"]
来自 ENTRYPOINT 的注释 Dockerfile docs:
The shell form prevents any CMD or run command line arguments from being used, but has the disadvantage that your ENTRYPOINT will be started as a subcommand of /bin/sh -c, which does not pass signals.