init:true不转发信号

时间:2019-04-05 19:57:18

标签: docker go docker-compose signals

我希望我的dockerized进程能够正确处理终止信号,因此我正在使用init:true。我在docker-compose.yml文件中使用以下代码:

version: '3.7'

services:
  foo:
    build:
      context: ./foo
    init: true

但是,我的进程未接收到信号。

当我在docker的外部进程中运行并按下Ctrl-C时,我可以看到正在处理信号(我的程序在信号处理程序中打印一条消息),但是在内部,信号未处理(我的程序未打印消息)

编辑

这里是foo/Dockerfile

FROM golang:1.11.4-alpine3.8 AS build
WORKDIR /go/src/foo
COPY ./ ./
RUN go build -a -tags netgo .
FROM alpine:3.8
WORKDIR /app
COPY --from=build /go/src/foo .
CMD ["./foo"]

这里是foo / foo.go(只是在循环中打印“正在等待”消息,直到接收到信号为止):

package main

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

var done chan bool
var dur time.Duration

func main() {    
  sigs := make(chan os.Signal)
  done = make(chan bool)
  signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
  pid := os.Getpid()
  fmt.Println("pid:", pid)

  go func() {
    sig := <-sigs
    fmt.Println(sig)
    done <- true
  }()

  fmt.Println("waiting")

  dur, _ = time.ParseDuration("2s")

  waitLoop()  

  fmt.Println("exiting")
}

func waitLoop() {
  for {
    select {
      case _ = <-done:
       fmt.Println("got done")
       return

      case <- time.After(dur):
    }

    fmt.Println("still waiting")
  }
}

当我在没有Docker的情况下构建并运行foo.go时,当我按Ctrl-C时,程序会正常退出(打印“中断”,“完成”和“退出”)。当我使用Docker运行时,这些消息都不会被打印出来……。在这两种情况下,打印的pid> 1。

1 个答案:

答案 0 :(得分:0)

我无法重现您的问题:

$ docker-compose up -d            
Building foo                                                                 
...
Successfully built 985c899d39fc
Successfully tagged init-issue_foo:latest
WARNING: Image for service foo was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating init-issue_foo_1_5d74c24a9fce ... done

$ docker-compose stop foo
Stopping init-issue_foo_1_e08f90ae3c56 ... done

$ docker-compose logs foo
Attaching to init-issue_foo_1_e08f90ae3c56
foo_1_e08f90ae3c56 | pid: 8
foo_1_e08f90ae3c56 | waiting
foo_1_e08f90ae3c56 | still waiting
foo_1_e08f90ae3c56 | still waiting
foo_1_e08f90ae3c56 | still waiting
foo_1_e08f90ae3c56 | still waiting
foo_1_e08f90ae3c56 | still waiting
foo_1_e08f90ae3c56 | still waiting
foo_1_e08f90ae3c56 | still waiting
foo_1_e08f90ae3c56 | still waiting
foo_1_e08f90ae3c56 | still waiting
foo_1_e08f90ae3c56 | terminated
foo_1_e08f90ae3c56 | got done
foo_1_e08f90ae3c56 | exiting

如果我尝试直接运行它:

$ docker run -it --rm --init init-issue_foo
pid: 8
waiting
still waiting
^Cinterrupt
got done
exiting

在每种情况下,我都看到“完成”行。如果您仍然无法通过上面的示例成功完成此操作,请显示您的确切命令及其运行的输出。