Как успешно реализовать проверку состояния контейнера в Docker Compose

1. Введение

Под термином Healthcheck следует понимать способ проверки рабочего состояния ресурса. Он определяет состояние запущенного в Docker контейнера.

Создаваемая команда Healthcheck определяет возможность тестирования контейнера, чтобы убедиться в его работоспособности. Docker без Healthcheck не сможет определить, действительно ли запущены работающие в контейнере службы.

Есть два способа определения рабочего состояния контейнера:

  • Dockerfile
  • Файл Docker-Compose.

Рассмотрим здесь только Docker-Compose Healthchecks.

2. Пример использования Nginx

Посмотрим, как работают проверки с помощью простого веб-сервиса Nginx. Чтобы создать очень простой веб-сайт, нужны три файла:

docker-compose.very-simple-web.yml, Dockerfile и index.html:

version: '3.4'
services:
web:
image: very-simple-web
build:
context: ./
dockerfile: Dockerfile
ports:
- "80:80"
restart: unless-stopped
FROM nginx
COPY html /usr/share/nginx/html
<html>
<head>
<title>Hello World FTP</title>
</head>
<body>
Hello World
</body>
</html>

Эти три файла должны быть сохранены в такой структуре

Теперь создадим службу:

$> docker-compose up -d --build

Если открыть веб-браузер на локальном хостинге, то увидим “Hello World”.

3. Зачем нужен Healthcheck?

Обычно для простого веб-сайта проверка рабочего состояния с помощью Nginx не требуется. Но при запуске в рабочей среде нескольких процессов иногда может произойти сбой.

При этом сайтом можно будет пользоваться, но даже если к нему невозможно будет получить доступ, служба Docker по-прежнему будет действовать.

Если она запущена в Docker Swarm, то Swarm все равно будет считать, что все работает правильно, потому что контейнер находится в запущенном состоянии. Возникает проблема, когда Swarm считает, что все в порядке, и не перезапускает контейнер для восстановления работоспособности.

4. Настройка Healthcheck в файле Сompose

Например, docker-compose.very-simple-web.yml будет расширен простой curl на основе Healthcheck (объяснение далее):

version: '3.4'
services:
web:
image: very-simple-web
build:
context: ./
dockerfile: Dockerfile
restart: unless-stopped
ports:
- "80:80"
healthcheck:
test: curl --fail http://localhost || exit 1
interval: 60s
retries: 5
start_period: 20s
timeout: 10s

Healtcheck в Docker Compose содержит пять свойств:

· test —  это свойство определяет выполняемую команду, которая является health check для контейнера. Если все настроено правильно, эта команда ДОЛЖНА быть доступной и действующей.

· interval — это свойство определяет задержку (в секундах) перед выполнением проверки работоспособности, а затем частоту, с которой будут выполняться последующие проверки состояния.

· timeout — это период (в секундах) исполнения команды проверки работоспособности, по истечении которого Docker вернет код завершения с ошибкой.

· retries — это свойство определяет количество последовательных сбоев health check, необходимых для объявления контейнера неисправным (unhealthy).

· start_period — это свойство определяет необходимое для контейнера время начальной загрузки (в секундах). Проверки в течение этого периода с кодом завершения больше нуля не будут отмечать контейнер как unhealthy, а код состояния 0 пометит контейнер как работоспособный (healthy).

Обратите внимание, что эта проверка работоспособности основана на curl. Для ее применения нужна предварительная установка curl в образе, используемом для запуска службы.

Если curl недоступен, часто используется другая проверка работоспособности, основанная на wget она выглядит следующим образом:

wget --no-verbose --tries=1 --spider http://localhost || exit 1

Просто замените команду curl в ранее определенном файле compose.

5. Часто используемые проверки работоспособности Docker

5.1 WGET

healthcheck:
test: wget --no-verbose --tries=1 --spider http://localhost || exit 1
interval: 60s
retries: 5
start_period: 20s
timeout: 10s

5.2 CURL

healthcheck:
test: curl --fail http://localhost || exit 1
interval: 60s
retries: 5
start_period: 20s
timeout: 10s

5.3 Что делать, если недоступны CURL/WGET ?

Если в используемом образе нет curl или wget, их необходимо установить. Сделать этого можно добавлением команды установки в Dockerfile.

curl

RUN apk --update --no-cache add curl

wget

RUN apt-get update && apt-get install -y wget

Следует помнить, что после добавления curl или wget, можно также добавить все поверхности атаки (attack surfaces) этих двух инструментов.

Хорошим обходным решением будет создание собственной программы, включаемой затем в тестовую команду docker health check.

6. Пользовательский health check

В сравнении с curl или wget, пользовательская проверка состояния решает все проблемы, связанные с использованием внешнего инструмента:

1. В этом случае и приложение, и health check выполняются в одной рабочей среде, поэтому не нужна установка дополнительных предварительных условий.

2. Разработчик выбирает логику проверки состояния, которая может быть закрытой, поэтому только платформа Docker может выполнять этот код.

Недостатком является необходимость создания и поддержки отдельного фрагмента кода. Но поскольку он будет создан на том же языке, что и само приложение, сделать это намного проще, чем разработка сложной команды curl или wget (если она сложная).

7. Заключение

Следует понимать, что запущенный в Docker контейнер не гарантирует соответствующую замыслу разработчика работу приложения. Проверки health checks в Docker позволяют быстро выявлять возможные ошибки в программе, прежде чем они станут реальной проблемой.

Учтите эту возможность в следующий раз при создании файла Docker-Compose.

Читайте также:

Читайте нас в TelegramVK и Яндекс.Дзен


Перевод статьи Paul Knulst: How To Successfully Implement A Healthcheck In Docker Compose

Предыдущая статьяКарусель изображений в React Native
Следующая статьяСоздание платформы обработки и анализа данных Bazaar