docker-alpine icon indicating copy to clipboard operation
docker-alpine copied to clipboard

not all alpine can easily avoid pid=1

Open carlvine500 opened this issue 4 years ago • 6 comments

pid=1 in docker will cause many java tools exec exception, to avoid pid=1, we can easily put a command ahead , such as "set -ex;"

but we found only alpine3.7 alpine3.4 can avoid pid=1 by "set -ex;" we expect alpine3.x all support this .

the following test show alpine3.7/alpine3.4 pid=8, but other alpine pid=1 image

carlvine500 avatar Jan 08 '21 03:01 carlvine500

A simpler / more reliable solution would be to use Docker's --init flag which will add a simple PID 1 inside your container that reaps zombie processes for you.

tianon avatar Jan 08 '21 06:01 tianon

@tianon kubernetes not support the flag --init

carlvine500 avatar Jan 11 '21 08:01 carlvine500

I guess that's fair (IMO Kubernetes really should, but that's a different topic).

This is easily remedied via apk add --no-cache tini in your image, and then set it as your entrypoint via something like ENTRYPOINT ["/sbin/tini", "--"] (https://stackoverflow.com/a/50819443/433558).

(Tini is the exact solution Docker itself uses for implementing --init.)

tianon avatar Jan 11 '21 19:01 tianon

@tianon google show several way to resolve the problem, but now the simple way is add "set -e" , we hope alpine will resolve it , alpine start with pid>1

carlvine500 avatar Jan 14 '21 03:01 carlvine500

just did quick debugging with strace, there was a slight difference in syscall between alpine 3.7 and 3.7+ on alpine 3.7 (or older version) the 'sleep' program would be running as a child process spawned by the syscall 'fork', so the pid was NOT 1, but on alpine 3.7+ this program was running inside the original process. see the strace syscalls snips below: on alpine 3.7

8366  03:12:37.855639 execve("/bin/sh", ["sh", "-c", "set -ex; sleep 370m"], [/* 6 vars */]) = 0 <0.000390>
...
# spawned a child process running "sleep" program
# pid 13 was the child process pid namespaced by the kernel
8366  03:12:37.865776 fork()            = 13 <0.000420>
....
# pid 8367 was the child process pid in the root PID namespace
8367  03:12:37.868389 execve("/bin/sleep", ["sleep", "370m"], [/* 6 vars */]) = 0 <0.000552>

on alpine 3.8

9172  04:27:39.751880 execve("/bin/sh", ["sh", "-c", "set -ex; sleep 380m"], [/* 6 vars */]) = 0 <0.001089>
...
# the 'sleep' program running inside in the original process.
9172  04:27:39.763537 execve("/bin/sleep", ["sleep", "380m"], [/* 6 vars */]) = 0 <0.002119>

after deeper dig & debugging the behavior was intended, and related to the code commit in the busybox, @carlvine500, based on such code commit you can run 'sh' with the '-s' additional option, as following:

# the sh option '-s' can fork another process to execute your actual program, which the pid is NOT 1 
# inside docker circumstance.  see below: 
$ docker run --name 3.10 -idt alpine:3.10 sh -cs "set -ex;sleep 310h"
6a1d ...
$ docker exec -it 3.10 ps aux
PID   USER     TIME  COMMAND
    1 root      0:00 sh -cs set -ex;sleep 310h
    6 root      0:00 sleep 310h
    7 root      0:00 ps aux

hope it helps, thanks

inter169 avatar Jan 18 '21 20:01 inter169

@inter169 thanks for your help ,it works in alpine3.10 but not woks in alpine3.14 .

WeChat189ccccbd94c928a64848352ac00c1d4

carlvine500 avatar Oct 20 '21 02:10 carlvine500