qubsup
qubsup

Reputation: 1391

How to get a docker container to the state: dead for debugging?

I need to get some containers to dead state, as I want to check if a script of mine is working. Any advice is welcome. Thank you.

Upvotes: 6

Views: 4587

Answers (2)

Robert
Robert

Reputation: 36783

You've asked for a dead container.

TL;DR: This is how to create a dead container

Don't do this at home:

ID=$(docker run --name dead-experiment -d -t alpine sh)
docker kill dead-experiment
test "$ID" != "" && chattr +i -R /var/lib/docker/containers/$ID
docker rm -f dead-experiment

And voila, docker could not delete the container root directory, so it falls to a status=dead:

docker ps -a -f status=dead
CONTAINER ID        IMAGE         COMMAND       CREATED             STATUS        PORTS         NAMES
616c2e79b75a        alpine        "sh"          6 minutes ago       Dead                        dead-experiment

Explanation

I've inspected the source code of docker and saw this state transition:

container.SetDead()
// (...)
if err := system.EnsureRemoveAll(container.Root); err != nil {
    return errors.Wrapf(err, "unable to remove filesystem for %s", container.ID)
}
// (...)
container.SetRemoved()

So, if docker cannot remove the container root directory, it remain as dead and does not continue to the Removed state. So I've forced the file permissions to not permit root remove files (chattr -i).

PS: to revert the directory permissions do this: chattr -i -R /var/lib/docker/containers/$ID

Upvotes: 5

Weike
Weike

Reputation: 1270

For docker-1.12+, instruction HEALTHCHECK can help you.

The HEALTHCHECK instruction tells Docker how to test a container to check that it is still working. This can detect cases such as a web server that is stuck in an infinite loop and unable to handle new connections, even though the server process is still running.

For example, we have a Dockerfile to define my own webapp:

FROM nginx:1.13.1

RUN apt-get update \
    && apt-get install -y curl \
    && rm -rf /var/lib/apt/lists/*

HEALTHCHECK --interval=15s --timeout=3s \
    CMD curl -fs http://localhost:80/ || exit 1

check every five minutes or so that a web-server is able to serve the site’s main page within three seconds. The command’s exit status indicates the health status of the container. The possible values are:

0: success - the container is healthy and ready for use
1: unhealthy - the container is not working correctly
2: reserved - do not use this exit code

Then use docker build command to build an image:

$ docker build -t myapp:v1 .

And run a container using this image:

$ docker run -d --name healthcheck-demo -p 80:80 myapp:v1

check the status of container:

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                            PORTS                NAMES
b812c8d6f43a        myapp:v1            "nginx -g 'daemon ..."   3 seconds ago       Up 2 seconds (health: starting)   0.0.0.0:80->80/tcp   healthcheck-demo

At the beginning, the status of container is (health: starting); after a while, it changes to be healthy:

$ docker ps                        
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                   PORTS                NAMES
d2bb640a6036        myapp:v1            "nginx -g 'daemon ..."   2 minutes ago       Up 5 minutes (healthy)   0.0.0.0:80->80/tcp   healthcheck-demo

It takes retries consecutive failures of the health check for the container to be considered unhealthy.

You can use your own script to replace the command curl -fs http://localhost:80/ || exit 1. What's more, stdout and stderr of your script can be fetched from docker inspect command:

$ docker inspect --format '{{json .State.Health}}' healthcheck-demo |python -m json.tool
{
    "FailingStreak": 0,
    "Log": [
        {
            "End": "2017-06-09T19:39:58.379906565+08:00",
            "ExitCode": 0,
            "Output": "  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current\n                                 Dload  Upload   Total   Spent    Left  Speed\n\r  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0\r100   612  100   612    0     0  97297      0 --:--:-- --:--:-- --:--:--   99k\n<!DOCTYPE html>\n<html>\n<head>\n<title>Welcome to nginx!</title>\n<style>\n    body {\n        width: 35em;\n        margin: 0 auto;\n        font-family: Tahoma, Verdana, Arial, sans-serif;\n    }\n</style>\n</head>\n<body>\n<h1>Welcome to nginx!</h1>\n<p>If you see this page, the nginx web server is successfully installed and\nworking. Further configuration is required.</p>\n\n<p>For online documentation and support please refer to\n<a href=\"http://nginx.org/\">nginx.org</a>.<br/>\nCommercial support is available at\n<a href=\"http://nginx.com/\">nginx.com</a>.</p>\n\n<p><em>Thank you for using nginx.</em></p>\n</body>\n</html>\n",
            "Start": "2017-06-09T19:39:58.229550952+08:00"
        }
    ],
    "Status": "healthy"
}

Hope this helps!

Upvotes: 2

Related Questions