-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider making Consul act as a viable "pid 1" in containers #1183
Comments
To expand on the motivation: Even many small inits ends up at hundreds of KB when compiled with gcc. Including musl in the build process reduces the size drastically at the cost of pulling in additional stuff in the build process. A standalone minimal Go init ended up at 2.9MB. Busybox is an alternative, but then requires an inittab and additional hassle to achieve the equivalent of a proper entrypoint that can take arguments as its init can't take arguments on the command line. Adding the few lines above takes away all of the hassle for users that wish to build a reliable containerised Consul. |
Consul is 18MB. Seems excessive to worry about a few hundred KB? |
And fwiw, you can compile a static tini in under a minute with no requirement other than docker, so correct my 'about a few hundred KB' to 'about 30KB'.
|
@aidanhs It's not just the "few hundred KB" that's the issue, though I on principle don't like unnecessarily adding lots of unnecessary bloat to avoid this small amount of code. The bigger issue is that it complicates building a container for Consul by requiring pulling in and building packages for another Init, or setting up an inittab for something like Busybox, when the issue can be avoided entirely with <10 lines of code in Consul. This is a step that, by searching for "consul" on Dockerhub and checking the Dockerfiles, almost nobody are aware they need to take: At least 8 out of the first 10 available Consul containers I checked has this problem. Which means a lot of people are going to run into slowly building zombies, and potentially containers locking up when the process table fills. Fixing that either requires educating everyone who builds these containers, or making Consul resilient to it. And while the ideal situation might be to educate everyone about it anyway, I'm a big fan of defensive programming when the cost is low... |
@aidanhs That's great, but you're paying that cost to avoid 6-7 lines of code in Consul. Seems like a really bad tradeoff to me. Especially given that to fix this issue it'd still be necessary to convince everyone building Consul containers to do it right in every Dockerfile. And it clearly in that case needs to be documented, as it's clear it's totally non-obvious to pretty much everyone who tries to package Consul.. (edit: I really appreciate the example of using an Alpine container to build stuff against musl, though - I'm definitively stealing that) |
Talked about this internally and we will go ahead and add the child reaping to Consul itself. Seems like an easy way to reduce the complexity of running inside a container. |
More background in this ticket: gliderlabs/docker-consul#45
Basically, because of the consul support for executing health checks etc., if consul is run under Docker as pid 1, and a health check in effect double forks, say because the health check is a shell script shelling out to the docker client or curl and then gets killed when it exceeds the interval, the "double-forked" processes will end up as zombies until the container is restarted.
This is not a bug in Consul, as in a "normal" Linux environment init will reap those zombies. One solution is simply to run Consul under an init. However it is also desirable to make containers as simple as possible, and an alternative approach would be to include something similar to this when starting the Consul server if it is started as pid 1 (it shouldn't do any harm to do it unconditionally):
Thoughts?
The text was updated successfully, but these errors were encountered: