当前位置: 首页 > 面试题库 >

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

王季萌
2023-03-14
问题内容

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

任何帮助深表感谢。


问题答案:

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

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

CMD ["/go/bin/simple_server"]

Dockerfile文档中
ENTRYPOINT的注释:

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



 类似资料:
  • #include <stdio.h> #include <signal.h> void handler(int sig); void handler(int sig) { signal(sig, handler); printf("Receive signal: %d\n", sig); } int main(void) { signal(SI

  • 问题内容: 我正在使用自定义信号处理程序在自定义Java守护程序中捕获TERM,ABRT和INT信号。我在代码中有此处理程序,以便可以向其发送TERM信号,并通过kill命令正常关闭程序。信号处理程序现在可以正常工作,但是当我编译代码时,我收到以下警告(很多次): 警告:sun.misc.SignalHandler是Sun专有的API,将来的发行版中可能会删除它。 在使用这些类时: 有没有更好的方

  • 我已在我的应用程序(ASP.NET Core)上使用elasticsearch将nlog配置为nlog.config,如下所示: 应用程序上的设置是: 当我通过dotnet-run运行应用程序时,我有一只麋鹿在这样的码头工人那里长大——https://github.com/deviantony/docker-elk 所有日志都会被保存。 但当我将我的应用程序添加到docker映像时,它就不起作用了

  • 问题内容: 在终端中,我执行了一个主父进程,该进程将派生一个子进程。在父进程和子进程中,我都实现了SIGINT信号处理程序。因此,当我按“ ctrl + c”时,是否将同时调用两个处理程序?还是我需要在父进程的处理程序中显式调用子进程的信号处理程序? 我查看了这篇文章: Ctrl-C如何终止子进程?表示“ SIGINT信号由终端线路规则生成,并广播到终端的 前台 进程组中的所有进程 ”。我只是不太

  • 我正在开发跨平台的Unity应用程序。大约一个月前,我在Android和iOS上测试了应用程序,它们可以正确旋转。但现在Android应用程序没有旋转。但iOS应用程序仍然完美地旋转。 当我旋转移动设备时,我会在Android Monitor中收到下一条消息: 我试图覆盖活动的<code>onConfigurationChanged(),就像这里一样,但它在手机旋转时不会调用,所以它会更早停止。

  • 我不确定我遇到的问题是概念问题还是技术问题,因为配置错误。 目标是在应用程序容器中托管的Java EE应用程序(特别是WildFly)和独立运行的Java SE应用程序之间发送双向消息,都使用标准JMS协议和主题。我认为这应该是可能的,只要他们都使用相同的经纪人和相同的主题。 因此,我有一个外部 Artemis 实例作为消息代理运行,并在 Java EE 应用程序的单独 Bean 中成功设置了生产