init: true не передает сигналы - PullRequest
2 голосов
/ 05 апреля 2019

Я хочу, чтобы мой докеризованный процесс правильно обрабатывал сигналы завершения, поэтому я использую init:true.Я использую следующий код в моем docker-compose.yml файле:

version: '3.7'

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

Однако мой процесс не получает сигнал.

Когда я запускаю свой процесс за пределами докера и нажмите 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")
  }
}

Когда я собираю и запускаю foo.go без Docker, когда я нажимаю Ctrl-C, программа корректно завершает работу (печатает)прерывание "," сделано "и" выход ").Когда я запускаю с Docker, ни одно из этих сообщений не печатается .... оно просто выходит.В обоих случаях напечатанный pid> 1.

1 Ответ

0 голосов
/ 09 апреля 2019

Я не могу воспроизвести вашу проблему:

$ 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

В каждом случае я вижу строку "получено".Если вы все еще не можете заставить это работать успешно из приведенного выше примера, пожалуйста, покажите свои точные команды и их вывод, который вы выполняете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...