>[...] the init process must also wait for child processes to terminate,
>before terminating itself.
>If the init process terminates prematurely then all children are terminated uncleanly by the kernel.
0: https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zomb...In general docker is half-trying to be the init system, but most people using it are putting a whole child os with its own init system in their container. I think the approach that rkt uses where it uses systemd to run the process is safer. Now if people would just start using lightweight containers...
[0]: https://github.com/phusion/baseimage-docker/blob/master/imag...
I should be able to take Yelp's dumb-init and add it easily to any linux container I want -- including things such as Alpine[1]
[0] https://github.com/phusion/baseimage-docker/blob/master/imag... [1] https://github.com/gliderlabs/docker-alpine
I use it in my Alpine containers.
"The motivation: modeling Docker containers as regular processes
[...] we want processes to behave just as if they weren’t running inside a container. That means handling user input, responding the same way to signals, and dying when we expect them to. In particular, when we signal the docker run command, we want that same signal to be received by the process inside."
and that seems to me as the core reason why they can't just use a simple init system (like e.g. runit I suppose?)
Noob question. Why is it impossible? You have the PID, no?
If your container has a process tree like
PID 1: /bin/sh
+--- PID 2: <your Python server>
then if you use `docker signal` from the host, it will only send a signal to PID 1, which is the shell. However the shell won't forward it on to your Python server, so nothing happens (in most cases).dumb-init basically replaces the shell in that diagram, but forwards signals when it receives them. So when you use `docker signal`, the Python process receives the signal.
Alternatively, just eliminating the shell (so your Python app is PID 1) works for some cases, but you get special kernel behavior applied to PID 1 which you usually don't want. This is the main purpose of dumb-init.
There are some minor differences (dumb-init looks like it's probably a bit better for interactive commands since it e.g. handles SIGTSTP). You can also get process group behavior at run-time with dumb-init rather than compile time, and it's on by default unlike tini (as far as I can tell from a brief reading). But for most cases it won't make a difference.
Note that for interactive usage, Tini actually hands over the tty (if there is one) to the child, so in that case signals that come "from the TTY" (though in a Docker environment this is an over-simplication) actually bypass Tini and are sent to the child directly. This should include SIGSTP, though I'm not sure I tested this specifically.
That being said, both tools are probably indeed very similar — after all there is little flexibility in that kind of tool! Process group behavior is probably indeed where they differ the most. : )
I've created an Ubuntu PPA packaging of it (https://launchpad.net/~danieldent/+archive/ubuntu/pidunu) and you can see an example of it in use at: https://github.com/DanielDent/docker-powerdns
For situations involving multiple processes, there's also https://github.com/just-containers/s6-overlay
Example use: https://github.com/DanielDent/docker-nginx-ssl-proxy (automated Let's Encrypt SSL front-end)
From my own experience with docker in production, I'm yet to see any of the described scenarios crop up. Has anyone else, or is this solving an extreme edge case?
The biggest issue we see at Yelp is leaking containers in test (e.g. Jenkins aborting a job but leaving the containers it spawned still running).
Depending on how you orchestrate containers, you might not encounter the issue in prod. If you're using something like Kubernates or Marathon or Paasta, they're probably going to do the "right thing" and ensure the containers are actually stopped.
We also use containers a lot in development. For example, we might put a single tool into a container, and then when developers call that tool, they're actually spawning a container without realizing it. For this use case, it's really important that signals are handled properly so that Ctrl-C (and similar) continues working.
Also,you guys should comment on https://github.com/docker/docker/pull/5773 which is work on unprivileged systemd in docker. I think you guys can influence the bug with your experience in this.
For instance, some programs watch the Docker event stream and can reload, say, HAproxy configuration to automatically load balance any new containers which come up. In my experience, running such a program in a container can make reloading the HAproxy process frequently tend to create a huge variety of zombie processes - and once they're present, zombies are difficult to eliminate without a reboot.
trap 'kill $(jobs -p)' EXITSee https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zomb..., section "A simple init system".
CMD ["/sbin/init", "2"]
and start your app using init.d scripts or supervidord as usual?I feel like logrotate, cron, etc, are worth having inside container no?
Single process containers generally don't need all the baggage of a full init system or other dependencies - hence this project.
It depends. If you are treating the container as a mini virtual system, then sure.
There is no need for logrotate if you are writing logs to stdout and letting the container system handle shipping then somewhere.
There's no need for cron in the container if you have a separate system for running scheduled tasks - somehing like Chronos.
I'd rather have a few tens of simple, single-process containers logging to a shared collector (or to their stdout, which is then collected) than deal with managing logrotate for them all and solve processing all those files for every host somehow.