dongshi8038 2015-10-27 22:26
浏览 101
已采纳

将信号发送到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)
}

If I run this code on my local machine, I can send it a SIGINT with <kbd>Ctrl-C</kbd> and it will close the application. When I run it inside a docker container, I can't seem to kill it with <kbd>Ctrl-C</kbd>.

# 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

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

docker kill --signal=INT 9354f574afd4

Still running...

docker kill --signal=TERM 9354f574afd4

Still running...

docker kill --signal=KILL 9354f574afd4

Finally dead.

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).

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 <kbd>Ctrl-C</kbd> while they're in a docker container.. Why isn't Go be getting the signals?

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

Any help is much appreciated.

  • 写回答

1条回答 默认 最新

  • douzhi2017 2015-10-28 16:47
    关注

    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.

    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"]
    

    A note from ENTRYPOINT in the 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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 求一个会修改Javaweb 代码的,非常简单
  • ¥20 有没有会写mysql的,有偿做个问题
  • ¥20 win11账户锁定时间设为0无法登录
  • ¥45 C#学生成绩管理系统
  • ¥15 VB.NET2022如何生成发布成exe文件
  • ¥30 matlab appdesigner私有函数嵌套整合
  • ¥15 给我一个openharmony跑通webrtc实现视频会议的简单demo项目,sdk为12
  • ¥15 vb6.0使用jmail接收smtp邮件并另存附件到D盘
  • ¥30 vb net 使用 sendMessage 如何输入鼠标坐标
  • ¥15 关于freesurfer使用freeview可视化的问题