【问题标题】:Unable to gracefully shutdown a docker process无法正常关闭 docker 进程
【发布时间】:2018-01-16 22:16:17
【问题描述】:

我希望能够优雅地关闭 docker 进程。我按照这篇博文中的想法导出了这些文件:https://husobee.github.io/golang/ecs/2016/05/19/ecs-graceful-go-shutdown.html

这是我的文件

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

我通过运行构建图像

docker build -f Dockerfile -t docker-shutdown . 

我通过

启动一个容器
docker run  docker-shutdown

然后我尝试关闭它

docker stop <container id>

在运行 'docker run' 的控制台中,我可以看到:

waiting for finish

它只是终止,没有进一步的输出。

我希望至少会看到一些输出,例如

 caught sig <SIGNAL_VALUE>

那么为什么我的预期行为没有发生?我也是go 的新手,所以我不确定它是否与go 代码或Dockerfile 中的CMD 定义有关。

我的问题:

为什么go 进程无法捕捉到 TERMKILL 信号?

【问题讨论】:

    标签: docker go dockerfile


    【解决方案1】:

    go run 得到的是信号,而不是正在运行的程序。

    提前编译程序,直接在docker中运行二进制,就可以正常运行了。

    【讨论】:

      猜你喜欢
      • 2017-02-08
      • 1970-01-01
      • 1970-01-01
      • 2014-12-12
      • 1970-01-01
      • 1970-01-01
      • 2014-04-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多