-
Notifications
You must be signed in to change notification settings - Fork 18.6k
-
Notifications
You must be signed in to change notification settings - Fork 18.6k
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
Proposal: Containers should not be considered started until the TCP ports they expose are open #7445
Comments
I could see this being more generalized to containers should support health checking. Of which port check is just one, eg you might want a custom URL to hit for eg an app server which may come up quickly but take some time initializing backends. |
+1 I'ld love to see some sort of health check system |
Couple of things come to mind with this.... 2 - dependencies between components is tricky but in general I think its better to assume that people will need to write code to deal with failure instead of relying on order/timing dependencies. For example, in the cases where an app needs to wait for its DB to be ready, I would claim the app needs to be written in such a way that it will recover from cases where the DB goes away at times. If they handled this situation nicely then there's no issue when the DB isn't started before the app because the app will deal with it automatically. So, overall, I'm not sure Docker can (or should) do a lot for people here. The health check system thing might be interesting though, I'm just not sure it can be based on listening to ports - or at least w/o the admin specifically asking for it check certain ports - like @pnasrat was suggesting. |
In my opinion this is in the realm of integration tests; I also have a use case for this (e.g. run specific tests when container is starting). However I would prefer that problem is framed in a more generic "script that container will run to assert it's healthy", so that could be plugged in and allow to pass a red/green light to the daemon. |
I find myself imagining an out of process Docker plugin which can poll (in the above image's specific fashion) which returns @bfirsh what do you think? so rather than the daemon specific value of I guess its just as easy to use a different |
+1 on this. This would be extremely helpful functionality. |
+1 |
2 similar comments
👍 |
👍 |
+1, i also need this feature. |
+1 |
3 similar comments
👍 |
+1 |
👍 |
What does it mean for "TCP port" to be "open"? do you also need healthcheck to return TRUE? What if it is not HTTP based protocol? All in all, IMHO: implement this in docker is in the wrong layer of abstraction 。 What you actually need is a service manager. |
Agree with @thefallentree , if you need such behaviour, it should be either implemented in the application itself or via some scripts which are invoked via CMD and hang in some kind of waiting loop till the according health check of connection is true. |
A TCP port being open means it responds to TCP packets, generally to test On Mon, May 11, 2015 at 6:07 AM, Artem Sidorenko notifications@github.com
Sincerely, Colton Leekley-Winslow |
But what about UDP? What about applications, which open the socket very fast, but start to provide a service a bit later? (I'm pretty sure somebody will have such case) What we talk here about is more or less a functionality of an orchestrator which manages software deployments:
We have a bit another picture with dockerµservices: you instantiate containers from image(s) and have some kind of initialization phase (which takes a while, otherwise we wouldn't have this discussion). But you don't have this classical SW deployment here, as its usually part of building the images. So this issue is about to have similar behaviour within docker, it might be a feature for fig/compose (docker/compose#374) (with open questions regarding reliable health checks not only on the TCP layer, but higher layers as well) , which implements the abstraction layer around hypervisor. but IMHO not for hypervisor itself. I deal with this problem like this (simple TCP check):
/etc/docker/start:
|
For the records, I have been using something similar to what @artem-sidorenko does, but more in the context of bringing up a cluster of containers e.g. before continuing the orchestration, make sure that service X on container Y is healthy. |
No idea if this can be done, but I think it would be nice getting an event through the |
Having compose allow you to define conditions that must be met before that On Wed, May 13, 2015 at 7:09 AM, Günter Zöchbauer notifications@github.com
Sincerely, Colton Leekley-Winslow |
Review with @crosbymichael @LK4D4 @duglin @diogomonica @calavera @cpuguy83 @vishh @ewindisch It feels like this functionality should not be Docker's responsibility: there will never be enough use cases to support (TCP, UDP, why not HTTP?) and it would bring more technical complexity, when really it should be the caller's responsibility to make sure the container is "ready" as opposed to "started". This would rather be orchestration tools' responsibility. Health checks are a great use case, but again, there seems to be consensus on the fact that they are the orchestration tools' responsibility. Ping @mavenugo what do you think? Also there was an argument in favor, stating that docker users and docker image authors are separate people, and although one could expect from image authors to better handle failure to establish a handshake, one cannot expect that from docker users that simply want to run existing applications that aren't as failsafe. The counterargument is that there is no way to make failsafe, an application that is not. If a container is considered "started" when its tcp endpoint is listening, just so that all another application has to do is @aanand @bfirsh @vieux @aluzzardi @mavenugo what do you guys think? Could compose or swarm provide health checks and some guarantees? I'm closing this, but feel free to continue the discussion. We will reconsider if needed. |
@tiborvass While the discussion veered, I think the original proposal was primarily for the use case of the builtin linking functionality. The protocol is therefore not arbitrary -- TCP status is what determines if a link will succeed. |
@tiborvass I think it would enormously beneficial for the container to have a standardised way of determining its health, even if its an orchestration system which actually runs the check. This would allow monitoring systems, etc, to determine whether the container was healthy, without having to know what was inside the container. Perhaps this could be more generic than the proposal suggested here:
I'll open a new issue about this. |
@bfirsh I think that having a container determine it's own health status, and having a standard way to report it out might make sense. In particular, if the only thing that dockerd does is periodically run We should absolutely make it clear that the responsibility of doing actions based on the output of that check is of an external application, not docker. |
Great suggestion |
@artem-sidorenko I am trying to do something similar but I have 3 separate services that each have a linked postgres db container... should I do something like this?
postgres.sh
ps that doesnt work I get |
@erichonkanen you should run the checks in |
@artem-sidorenko when you say I should have a command that starts the service after DB is ready, do you mean just exit the loop and let compose spin it up? (thats all ive done so far w/docker-compose), or are you referring to any app-level stuff I need to run e.g. "python manage.my runserver" (this is indeed what runs inside my contentservice bootstrap.sh |
@erichonkanen I mean something what gets called after db is ready, something like
|
@artem-sidorenko ok great thanks a bunch! |
in case anyone else arrives here looking to find a way to ensure postgres connection is open before proceeding with a webapp.. here is what I landed on and works nicely. (Add postgresql-client to the webapp Dockerfile)
|
@tiborvass I think the Engine should provide a high level way of doing health checks. This should include something like, how to check (tcp connect, http, custom command), how many retries and delay between retries. I don't think Swarm should be doing that - every machine should be checking its own containers and Swarm could actually leverage such checks. |
decking has an option |
+1 |
👍 for HEALTHCHECK instruction. |
I don't feel this should be part of Docker itself especially as ports may or not be open depending on whatever conditions. This should be part of whatever is handling the startup of containers if they are meant to be run as a web service (e.g. Kubernetes). |
@aluzzardi Having the runtime health check the things its running sounds like a recipe for disaster if you really think about it ;) It would be like giving a kid a credit card and letting them reconcile the bill, ya mom, i didn't spend all the money. Having a runtime do healthchecks creates a SPOF. Healthchecking should be a 'third party' app making sure the runtime is held accountable for what it is supposed to run. |
+1 |
👍 Sort of defeats purpose of orchestration, if containers are started before containers it depends on are ready. |
Consider the following situation: you are booting up a database container and then a web container which links to the database container. The database container may take a little time to start up, but you don't want to start the web container until the database has started.
A similar situation is where you are starting up a web server and want to wait until it has started before adding it to the load balancer.
Current solutions typically involve an entrypoint script that waits for the port to be open (see docker/compose#374 or aanand/docker-wait, or even just a fixed
/bin/sleep
command.I propose that a container should not be considered started or be able to be linked to until the exposed TCP ports are ready to accept connections. The
docker run -d
ordocker start
commands should also not return until they are ready. This will allow you to safely do things like:I am not fully familiar with the internals of container state, so I'm not sure how this should be implemented. I expect it'll be something like a
Ready
attribute on a container's state, perhaps with a modification to the/container/(id)/wait
endpoint that will wait for a container to be ready.Backwards compatibility
Existing containers may not open exposed ports. Perhaps there could be a timeout, or it could be an opt-in feature in a next version, switching to default behaviour in a version after that.
Future
This could be expanded into some kind of health check system. E.g. don't consider a container started and ready to be linked to until it is responding to HTTP requests with code 200.
The text was updated successfully, but these errors were encountered: