I have been trying to figure out a practical way to execute a health-check command within an application task that is deployed via the docker containerizer. I have not seen any discussions on this topic, and it seems like something of a challenge. The "obvious" solution would seem to be to have the command that is listed within the health-check specification execute within the application container - i.e., via a "docker exec" operation. Unfortunately, what seems to happen is that the command is executed within the context of the mesos-slave - which itself is running in a docker container in my CoreOS environment.
I can run a "docker exec" command from there, but the problem is not knowing the container ID for the application. The command can include references to the IP address and assigned PORTs of the application task, but I have not seen that there is a similar substitution variable for container ID -- and I can imagine it would be more of a challenge to have such a thing, as I guess the HOST and PORTs are part of the resource offer made by mesos to marathon, whereas Container ID would not be.
I have found a way to do this, assuming that there is a mapped port that can be used to identify which container is which on the mesos-slave. In my particular case, I have a mapping for port 22 (sshd) defined to an allocated port number. With this, I can create a command line attached to the health-check specification that extracts the container ID from a "docker ps" command output, and then use it in a "docker exec" command. Here is the JSON file that creates my application:
{
"id":"hc-test",
"cpus":0.1,
"mem":16,
"instances":4,
"container": {
"type":"DOCKER",
"docker": {
"image": "registry.cgbu/ubuntu_sshd",
"network":"BRIDGE",
"portMappings":[
{ "containerPort":22, "hostPort":0 }
]
}
},
"healthChecks": [
{
"protocol":"COMMAND",
"command": { "value":"docker exec $(docker ps | grep 0\\.0\\.0\\.0:$PORT-\\>22/tcp | cut -f1 -d\\ ) /root/bin/health-check" },
"gracePeriodSeconds":30,
"intervalSeconds":20,
"timeoutSeconds":5,
"maxConsecutiveFailures":3
}
]
}
The problem with this approach, it seems to me, is just that it is a rather convoluted way to accomplish what seems like would be a common need - the ability to run a command within the application task container that reports on its health.
Have I missed something that would make this simpler? Several things could potentially simplify it:
a) The COMMAND health check, when run for a task started by the docker containerizer could by default execute the command within the appropriate container. That would be a change in behavior, it seems, but I haven't found anything that actually documents what context the command runs in today (through experimentation, I found it runs in the mesos-slave container).
b) There could be an option added to the healthCheck input in the JSON file, something like "context":"container" or "context":"host", to identify where the command line should be executed - within the container or in the host.
c) There could be an environment variable set with the container ID, which could be referenced by the health-check command, so the command could be simplified to something like, "docker exec $CONTAINER_ID /root/bin/health-check".
Have there been any previous discussions about this?