【问题标题】:Sending signals to Golang application in Docker在 Docker 中向 Golang 应用程序发送信号
【发布时间】:2016-01-27 13:10:00
【问题描述】:

我正在尝试在 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

终于死了。

我没有在我的代码中捕获任何信号并忽略它们。我什至尝试增强上面的代码来捕获信号并将它们打印出来(这在我的主机上工作,但在容器中时,就好像信号从未到达程序一样)。

以前有人经历过吗?我还没有用另一种语言尝试过这样的事情,但我能够在服务器(例如mongonginx)在 docker 容器中时使用 Ctrl-C 杀死它们。为什么Go 不是在收到信号吗?

不确定这是否会有所不同,但我在 OSX 上并使用 docker-machine。

非常感谢任何帮助。

【问题讨论】:

标签: go docker boot2docker dockerfile


【解决方案1】:

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

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

CMD ["/go/bin/simple_server"]

Dockerfile docs 中来自 ENTRYPOINT 的注释:

shell 形式阻止使用任何 CMD 或运行命令行参数,但缺点是您的 ENTRYPOINT 将作为 /bin/sh -c 的子命令启动,它不会传递信号。

【讨论】:

  • 谢谢!!这就是问题所在!
  • 哇,谢谢。对于那些以后来的人...ENTRYPOINT app 不会捕获信号,但ENTRYPOINT ["app"] 会:-|
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-14
  • 2018-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多