dongrui6787 2019-04-05 19:57
浏览 139

init:true不转发信号

I want my dockerized process to handle termination signals correctly, so I am using init:true. I am using the following code in my docker-compose.yml file:

version: '3.7'

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

However, the signal is not being received by my process.

When I run my process outside of docker and hit Ctrl-C, I can see that the signal is being handled (my program prints a message in the signal handler), but inside of docker, the signal is not handled (my program doesn't print the message)

EDIT:

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

Here is foo/foo.go (just prints "waiting" messages in a loop until it receives a signal):

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

When I build and run foo.go without Docker, when I hit Ctrl-C, the program exits gracefully (prints "interrupt", "got done" and "exiting"). When I run with Docker, none of these messages are printed.... it just exits. In both cases, the pid printed is > 1.

  • 写回答

1条回答 默认 最新

  • douji6940 2019-04-09 15:06
    关注

    I'm unable to reproduce your issue:

    $ 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
    

    And if I try running it directly:

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

    In each case I see the "got done" line. If you are still not able to get this working successfully from the above example, please show your exact commands and their output that you run.

    评论

报告相同问题?

悬赏问题

  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 划分vlan后不通了
  • ¥15 GDI处理通道视频时总是带有白色锯齿
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大