Live data from Hacker News

Introducing dumb-init, an init system for Docker containers

engineeringblog.yelp.com

11–20 of 40 posts

Re: Introducing dumb-init, an init system for Docker containers

#11
post #10

This looks to be an alternative https://github.com/krallin/tini

Yup, tini is really really similar and looks pretty cool! They're solving much of the same problem. It's unfortunate that we didn't find tini before we went and wrote 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.

Re: Introducing dumb-init, an init system for Docker containers

#12
post #7
post #4

Is there any reason you wouldn't run normal "non-dumb" init for this using 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?

Generally accepted practice is no - they aren't worth having. Containers should only contain a single process. That process shouldn't be writing logs to disk (hence no logrotate) and timed tasks would generally be done outside the container rather than in it (though there are a lot of ways to skin that cat). Single process containers generally don't need all the baggage of a full init system or other dependencies - h…

At my current job, we're basically using Docker as a sort of package manager and deployment script runner. Our containers are very fat, things are installed with apt. One of them has GCC in it but I'm not sure why. One installs Node and runs a few js scripts during the build process, then never runs it again but keeps it around. It's obviously wrong, but I think it's just a new set of bad ideas that this software has allowed people to have.

Re: Introducing dumb-init, an init system for Docker containers

#13
post #4

Is there any reason you wouldn't run normal "non-dumb" init for this using 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?

> I feel like logrotate, cron, etc, are worth having inside container no?

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.

Re: Introducing dumb-init, an init system for Docker containers

#14
post #12
post #7

Earlier quoted context omitted.

Generally accepted practice is no - they aren't worth having. Containers should only contain a single process. That process shouldn't be writing logs to disk (hence no logrotate) and timed tasks would generally be done outside the container rather than in it (though there are a lot of ways to skin that cat). Single process containers generally don't need all the baggage of a full init system or other dependencies - h…

At my current job, we're basically using Docker as a sort of package manager and deployment script runner. Our containers are very fat, things are installed with apt. One of them has GCC in it but I'm not sure why. One installs Node and runs a few js scripts during the build process, then never runs it again but keeps it around. It's obviously wrong, but I think it's just a new set of bad ideas that this software has…

Under a time crunch I've not found a way to use language-package managers and not wind up with gcc in the container.

The problem is apt does a poor job of letting you setup something like build-essential and then remove it and leave just the runtime shared libraries you need for the other things you build to actually work.

Re: Introducing dumb-init, an init system for Docker containers

#15
post #11
post #10

This looks to be an alternative https://github.com/krallin/tini

Yup, tini is really really similar and looks pretty cool! They're solving much of the same problem. It's unfortunate that we didn't find tini before we went and wrote 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 o…

Quick disclaimer: I'm the author of Tini (thanks for the hat tip, by the way!).

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. : )

Re: Introducing dumb-init, an init system for Docker containers

#16
> Having a shell as PID 1 actually makes signaling your process almost impossible. Signals sent to the shell won’t be forwarded to the subprocess, and the shell won’t exit until your process does. The only way to kill your container is by sending it SIGKILL (or if your process happens to die).

Noob question. Why is it impossible? You have the PID, no?

Re: Introducing dumb-init, an init system for Docker containers

#17
post #14
post #12

Earlier quoted context omitted.

At my current job, we're basically using Docker as a sort of package manager and deployment script runner. Our containers are very fat, things are installed with apt. One of them has GCC in it but I'm not sure why. One installs Node and runs a few js scripts during the build process, then never runs it again but keeps it around. It's obviously wrong, but I think it's just a new set of bad ideas that this software has…

Under a time crunch I've not found a way to use language-package managers and not wind up with gcc in the container. The problem is apt does a poor job of letting you setup something like build-essential and then remove it and leave just the runtime shared libraries you need for the other things you build to actually work.

I kinda solve that by doing something like this:

    # install runtime deps
    dpkg -l | awk '{print $2}' | sort > old.txt
    # install build deps
    # build software
    dpkg -l | awk '{print $2}' | sort > new.txt
    apt-get -y remove --purge $(comm -13 old.txt  new.txt)
Probably a better way to accomplish that, but it was the easiest way I could see to implement an 'undo'

Re: Introducing dumb-init, an init system for Docker containers

#18

> Having a shell as PID 1 actually makes signaling your process almost impossible. Signals sent to the shell won’t be forwarded to the subprocess, and the shell won’t exit until your process does. The only way to kill your container is by sending it SIGKILL (or if your process happens to die). Noob question. Why is it impossible? You have the PID, no?

Good question! The problem is trying to signal it from outside the Docker container.

If your container has a process tree like

    PID 1: /bin/sh
    +--- PID 2: 
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.

Re: Introducing dumb-init, an init system for Docker containers

#19
post #5

If it's such a straightforward fix, why isn't it part of the docker core? I'd love to hear from the docker team why it's not a concern for them. Presumably if it was they'd have addressed it by now. 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?

Zombies are not uncommon to see for an app running in a container that forks off other processes. This isn't every program but forking processes is pretty common, enough so to be worrisome.

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.

Re: Introducing dumb-init, an init system for Docker containers

#20
post #14

Earlier quoted context omitted.

Under a time crunch I've not found a way to use language-package managers and not wind up with gcc in the container. The problem is apt does a poor job of letting you setup something like build-essential and then remove it and leave just the runtime shared libraries you need for the other things you build to actually work.

I kinda solve that by doing something like this: # install runtime deps dpkg -l | awk '{print $2}' | sort > old.txt # install build deps # build software dpkg -l | awk '{print $2}' | sort > new.txt apt-get -y remove --purge $(comm -13 old.txt new.txt) Probably a better way to accomplish that, but it was the easiest way I could see to implement an 'undo'

If doing this sort of thing, make sure to accomplish it in a single step (image layer) in the Dockerfile. Otherwise you won't be doing any good as the "removed" files actually persist behind a layer which specifies them as removed.
Post reply on HN