小编典典

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

go

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

如果我在本地计算机上运行此代码,则可以将其发送给SIGINTwith
Ctrl-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

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

docker kill --signal=INT 9354f574afd4

仍在运行…

docker kill --signal=TERM 9354f574afd4

仍在运行…

docker kill --signal=KILL 9354f574afd4

终于死了。

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

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

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

任何帮助深表感谢。


阅读 211

收藏
2020-07-02

共1个答案

小编典典

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

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

CMD ["/go/bin/simple_server"]

Dockerfile文档中
ENTRYPOINT的注释

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

2020-07-02