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

问题描述 投票:0回答:1

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

终于死了。

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

有人经历过这种情况吗?我还没有在其他语言中尝试过类似的操作,但是当服务器位于 docker 容器中时,我可以使用

Ctrl-C
来杀死服务器(例如
mongo
nginx)。为什么不 Go 是收到信号了吗?

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

非常感谢任何帮助。

go docker boot2docker dockerfile
1个回答
9
投票

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

当您使用 CMD 的“shell”形式时,它会作为

/bin/sh -c
的参数启动您的服务器。为了直接执行服务器二进制文件,您需要向 CMD 或 ENTRYPOINT 提供一组参数,从可执行文件的完整路径开始。

CMD ["/go/bin/simple_server"]

来自 Dockerfile 文档中 ENTRYPOINT 的注释

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

© www.soinside.com 2019 - 2024. All rights reserved.