Недавно я изучаю dumb-init. и если я правильно понял, он пытается:
- работает как PID1, действуя как простая система инициализации (процессы-зомби)
- сигнальный прокси/переадресация (чего не делает bash)
В обоих здесь и здесь все упоминали, что bash
способен пожинать зомби процесс, поэтому я пытаюсь проверить это, но не смог заставить его работать.
Прежде всего, я написал простую программу на Go, которая порождает 10 зомби-процессов:
func main() {
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM, syscall.SIGKILL)
go func() {
for i := 0; i < 10; i++ {
sleepCmd := exec.Command("sleep", "1")
_ = sleepCmd.Start()
}
}()
fmt.Println("awaiting signal")
sig := <-sigs
fmt.Println()
fmt.Printf("received %s, exiting\n", sig.String())
}
создайте образ для него:
FROM golang:1.15-alpine3.12 as builder
WORKDIR /
COPY . .
RUN go build -o main main.go
FROM alpine:3.12
RUN apk --no-cache --update add dumb-init bash
WORKDIR /
COPY --from=builder /main /
COPY --from=builder /entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/main"]
и если я запускаю docker run -d <image>
, он работает, как и ожидалось, я вижу 10 процессов зомби в ps
:
vagrant@vagrant:/vagrant/dumb-init$ ps aux | grep sleep
root 4388 0.0 0.0 0 0 ? Z 13:54 0:00 [sleep] <defunct>
root 4389 0.0 0.0 0 0 ? Z 13:54 0:00 [sleep] <defunct>
root 4390 0.0 0.0 0 0 ? Z 13:54 0:00 [sleep] <defunct>
root 4391 0.0 0.0 0 0 ? Z 13:54 0:00 [sleep] <defunct>
root 4392 0.0 0.0 0 0 ? Z 13:54 0:00 [sleep] <defunct>
root 4393 0.0 0.0 0 0 ? Z 13:54 0:00 [sleep] <defunct>
root 4394 0.0 0.0 0 0 ? Z 13:54 0:00 [sleep] <defunct>
root 4395 0.0 0.0 0 0 ? Z 13:54 0:00 [sleep] <defunct>
root 4396 0.0 0.0 0 0 ? Z 13:54 0:00 [sleep] <defunct>
root 4397 0.0 0.0 0 0 ? Z 13:54 0:00 [sleep] <defunct>
2-й шаг — убедиться, что bash
действительно способен обрабатывать процесс, поэтому я обновляю свой образ докера ENTRYPOINT до entrypoint.sh, который просто обертывает мою программу с помощью bash:
#!/bin/bash
/clever
если я запускаю ps
в контейнере, то там все еще висят зомби-процессы:
/ # ps
PID USER TIME COMMAND
1 root 0:00 {entrypoint.sh} /bin/bash /entrypoint.sh
7 root 0:00 /clever
13 root 0:00 [sleep]
14 root 0:00 [sleep]
15 root 0:00 [sleep]
16 root 0:00 [sleep]
17 root 0:00 [sleep]
18 root 0:00 [sleep]
19 root 0:00 [sleep]
20 root 0:00 [sleep]
21 root 0:00 [sleep]
22 root 0:00 [sleep]
31 root 0:00 /bin/sh
39 root 0:00 ps
Пробовал несколько других способов, но так и не смог понять, как правильно пожинать процесс зомби.
Спасибо за помощь.
ps
процесс запуска все еще выполняется (pid 7), и я ожидаю, что он будет родителем процессовsleep
(pid 13, 14, ...), что означает, что корневой процессbash
(pid 1 ) не пожнет их. - person David Maze   schedule 01.03.2021wait
за ребенка и игнорироватьSIGCHLD
. Как только вы убьете родителя, зомби-процессы будут перемещены в PID 1 в качестве нового родителя. - person jordanvrtanoski   schedule 01.03.2021