将信号发送到Docker中的Golang应用程序 [英] Sending signals to Golang application in Docker

查看:199
本文介绍了将信号发送到Docker中的Golang应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to run servers written in golang inside docker containers. For example:

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 杀死它.

If I run this code on my local machine, I can send it a SIGINT with Ctrl-C and it will close the application. When I run it inside a docker container, I can't seem to kill it with 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向容器发送信号.

I then proceeded to use docker to send signals to the container.

docker kill --signal=INT 9354f574afd4

仍在运行...

docker kill --signal=TERM 9354f574afd4

仍在运行...

docker kill --signal=KILL 9354f574afd4

最后死了.

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

I'm not catching any signals in my code and ignoring them. I've even tried augmented the code above to catch signals and print them out (which works on my host, but when in the container, it's as if the signals never got to the program).

有人曾经经历过吗?我没有尝试用另一种语言尝试过这种方法,但是当它们位于Docker容器中时,我可以使用 Ctrl-C 杀死服务器(例如mongonginx).去获取信号吗?

Has anyone experienced this before? I haven't tried something like this in another language, but I able to kill servers (e.g. mongo, nginx) using Ctrl-C while they're in a docker container.. Why isn't Go be getting the signals?

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

Not sure if this makes a difference, but I am on OSX and using docker-machine.

非常感谢您的帮助.

推荐答案

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

You are running your server inside a shell, and the shell is the process receiving the signals. Your server doesn't exit until you force the shell to quit.

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

When you use the "shell" form of CMD, it starts your server as an argument to /bin/sh -c. In order to exec the server binary directly, you need to provide an array of arguments to either CMD or ENTRYPOINT, starting with the full path of the executable.

CMD ["/go/bin/simple_server"]

来自ENTRYPOINT的 Dockerfile文档中的注释:

A note from ENTRYPOINT in the Dockerfile docs:

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

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应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆