drti52047 2017-08-09 06:58
浏览 556
已采纳

无法正常关闭Docker进程

I want to be able to shutdown a docker process gracefully. I derived the these files by following the idea in this blog post: https://husobee.github.io/golang/ecs/2016/05/19/ecs-graceful-go-shutdown.html

Here are my files

1) Dockerfile

FROM debian:jessie
ADD app /app
RUN apt-get update --fix-missing
RUN apt-get install -y golang
CMD ["go", "run", "/app/main.go"] 

2) app/main.go

package main

import "os"
import "syscall"
import "fmt"
import "time"
import "os/signal"


func main() {
    // create a "returnCode" channel which will be the return code of the application
    var returnCode = make(chan int)

    // finishUP channel signals the application to finish up
    var finishUP = make(chan struct{})

    // done channel signals the signal handler that the application has completed
    var done = make(chan struct{})

    // gracefulStop is a channel of os.Signals that we will watch for -SIGTERM
    var gracefulStop = make(chan os.Signal)

    // watch for SIGTERM and SIGINT from the operating system, and notify the app on
    // the gracefulStop channel
    signal.Notify(gracefulStop, syscall.SIGTERM)
    signal.Notify(gracefulStop, syscall.SIGINT)

    // launch a worker whose job it is to always watch for gracefulStop signals
    go func() {
        // wait for our os signal to stop the app
        // on the graceful stop channel
        // this goroutine will block until we get an OS signal
        sig := <-gracefulStop
        fmt.Printf("caught sig: %+v", sig)

        // send message on "finish up" channel to tell the app to
        // gracefully shutdown
        finishUP<-struct{}{}

        // wait for word back if we finished or not
        select {
        case <-time.After(30*time.Second):
            // timeout after 30 seconds waiting for app to finish,
            // our application should Exit(1)
            returnCode<-1
        case <-done:
            // if we got a message on done, we finished, so end app
            // our application should Exit(0)
            returnCode<-0
        }
    }()


    // ... Do business Logic in goroutines

    fmt.Println("waiting for finish")
    // wait for finishUP channel write to close the app down
    <-finishUP
    fmt.Println("stopping things, might take 2 seconds")

    // ... Do business Logic for shutdown simulated by Sleep 2 seconds
    time.Sleep(2*time.Second)

    // write to the done channel to signal we are done.
    done <-struct{}{}
    os.Exit(<-returnCode)
}

I build the image by running

docker build -f Dockerfile -t docker-shutdown . 

I start a container by

docker run  docker-shutdown

Then I try to shut it down by

docker stop <container id>

In the console that runs 'docker run', I can see:

waiting for finish

and it just terminated with no further output.

I would expect to see at least some output like

 caught sig <SIGNAL_VALUE>

So why my expected behavior did not happen? I am also new to go so I am not sure if it may have something to do with the go code or the CMD definition in the Dockerfile.

My question:

Why the go process cannot catch the either TERM and KILL signals?

  • 写回答

1条回答 默认 最新

  • dongwuxie7976 2017-08-09 07:35
    关注

    go run is getting the signal, not the program that is being run.

    Compile the program ahead of time and run the binary directly in docker, and it will work as expected.

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

报告相同问题?

悬赏问题

  • ¥30 vb net 使用 sendMessage 如何输入鼠标坐标
  • ¥200 求能开发抖音自动回复卡片的软件
  • ¥15 关于freesurfer使用freeview可视化的问题
  • ¥100 谁能在荣耀自带系统MagicOS版本下,隐藏手机桌面图标?
  • ¥15 求SC-LIWC词典!
  • ¥20 有关esp8266连接阿里云
  • ¥15 C# 调用Bartender打印机打印
  • ¥15 我这个代码哪里有问题 acm 平台上显示错误 90%,我自己运行好像没什么问题
  • ¥50 C#编程中使用printDocument类实现文字排版打印问题
  • ¥15 找会编程的帅哥美女 可以用MATLAB里面的simulink编程,用Keil5编也可以。