Docker healthcheck

Configuration and examples

Docker healthcheck

Category: DevOps


16.09.2020

One of the available Design & Config about Dockerfile introduces the most important commands for container definition. Few of these commands deserve a longer explanation. In this blog post, I will focus on Docker healthcheck. It allows us to monitor easily the status of the container.

There are two main states of the container:

  • healthy – this means that whatever we defined as a check passed
  • unhealthy – the defined check failed

There is also an additional state that lasts until the first check. It shows as starting, which means we don’t know yet the status of the container.

Configuring Docker healthcheck

In order to configure Docker healthcheck in your Dockerfile add the following command:

HEALTHCHECK [OPTIONS] CMD command

where command is your check, which must exit with either code 0 for success or 1 for failure. Based on that code and options healthy/unhealthy status is assigned.

Additionally, we can modify options of the healthcheck using the following parameters:

  • –interval=DURATION (default: 30s) – how often check is performed
  • –timeout=DURATION (default: 30s) – how long does daemon waits for exit code = 0
  • –start-period=DURATION (default: 0s) – additional delay before first check
  • –retries=N (default: 3) – how many checks must fail one after another before assigning unhealthy status.

Example

Let’s make the use of the knowledge gathered above. In the example, I will run a single elasticsearch node to show you how it works and how can we implement Docker healthcheck in practice.

We can start by running container from an official elasticsearch image:

$ docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.9.0

To verify if it is running we can examine output of docker ps command:

As you can see there is no useful information about elasticsearch status. We know only that it has been running for some time, but it might not work as intended.

We can now build a new image that is based on elasticsearch but extends it with simple healthcheck. Create a file named elastic_health.Dockerfile with the following content:

FROM elasticsearch:7.9.0
HEALTHCHECK --interval=5s --timeout=3s CMD curl -f -X GET "localhost:9200/_cluster/health?wait_for_status=green&timeout=1s" || exit 1

The implemented check will perform a curl on a specific endpoint, which returns the health of the elasticsearch cluster. Do not confuse it with the container status. Elasticsearch has its own healthcheck, that we want to expose to the container status. The default response is json with some useful information, but in this case, only green status is in our focus. By providing additional options in the URL we ensure that this command ends with success if the status is green and fails otherwise. To make sure we are compliant with Docker healthcheck expected exit status in case of any error we exit with code 1.

Let’s see what is the difference between vanilla elasticsearch and the one with Docker healthcheck.

First of all, we need to build a new image based on the aforementioned Dockerfile:

$ docker build -f elastic_health.Dockerfile . -t elastic_health

and run the new container alongside the old one (we need to change ports to do so):

$ docker run --rm -d --name elastic_health -p 9201:9200 -p 9301:9300 -e "discovery.type=single-node" elastic_health

Having this done we can check status:

As mentioned before, the initial status is starting. After a couple of seconds, Docker enters a healthy state.

We can do one more experiment to verify that the unhealthy state also works correctly. Using the next command I will force elasticsearch to attempt to create a cluster with some arbitrary address (1.1.1.1). Of course, this will fail since no elasticsearch instance is at that address, so the status will be different from green:

$ docker run -d --name elastic_health -p 9201:9200 -p 9301:9300 -e "node.name=elastic_health" -e "discovery.seed_hosts=1.1.1.1" -e "cluster.initial_master_nodes=elastic_health,1.1.1.1" elastic_health

Author

Mateusz Buczkowski

Mateusz Buczkowski received his M.Sc. degree from Poznan University of Technology in 2012. Since then he is employed at the Chair of Telecommunication Systems and Optoelectronics in the Faculty of Electronics and Telecommunications as a teaching assistant. He is pursuing his PhD in field of image processing. His research interest cover the wide spectrum of image and video processing. In particular he is interested in image quality assessment, which is his PhD topic. As a R&D engineer he took part in two FP7 EU projects, namely 5GNOW and SOLDER, where he worked on solutions that can be used in 5-th Generation wireless networks, which is to come in 2020. In Grandmetric he is involved in wireless systems research.

Leave a Reply

Your email address will not be published. Required fields are marked *


 

Newsletter