Модуль 11 / 18
Healthcheck, залежності та restart policies
Зміст
1. Цілі та модель готовності
Після модуля ви зможете розрізняти running, healthy і ready, проєктувати probes, керувати startup dependencies та обирати restart policy.
- running означає лише існування PID 1
- healthcheck виконується всередині container
- unhealthy сам не перезапускає container
- depends_on задає порядок та умови
- restart policy реагує на завершення процесу
2. Теорія: HEALTHCHECK
Контейнер із healthcheck проходить starting → healthy або unhealthy. Exit 0 означає успіх, 1 — відмову, 2 зарезервований. Engine зберігає короткий output останніх перевірок і створює health_status events.
interval задає період, timeout обмежує probe, retries рахує послідовні відмови. start_period не враховує ранні failures, start_interval задає їх частоту; успіх завершує пільговий режим.
3. Теорія: якісна перевірка
Probe має швидко, дешево й детерміновано перевіряти здатність екземпляра обслуговувати запит. Лише існування процесу дає мало інформації, а глибока перевірка всіх dependencies створює каскадні відмови.
Healthcheck не розділяє Kubernetes readiness/liveness. Застосунок усе одно потребує retry, backoff та graceful degradation.
4. Теорія: depends_on
Короткий depends_on чекає лише запуск dependency. service_healthy чекає healthy; service_completed_successfully підходить для migration/job. Compose створює та видаляє services у dependency order.
Це startup coordination, а не runtime supervision. restart: true у long-form depends_on стосується явної Compose-операції, а не автоматичного Engine restart.
5. Теорія: restart policies
no не перезапускає; on-failure[:N] реагує на non-zero exit; always і unless-stopped переживають daemon restart з різницею після ручної зупинки. Моніторинг починається після успішного запуску близько 10 секунд.
Unhealthy не завершує PID 1 і тому не активує restart policy. Restart loop усувають через root cause, обмеження attempts і backoff.
6. Теорія: межі та failure modes
Startup order не гарантує постійну готовність, а healthy не гарантує всі business operations. Клієнти мають переживати reconnect.
Не поєднуйте Docker restart policy з конкуруючим host process manager. Probe не має змінювати дані, вимагати privileges чи виводити secret.
7. Методичні вказівки
- Спочатку визначте властивість для перевірки
- Timeout має бути меншим за interval
- Залиште retries для transient failure
- Start_period лише для реального bootstrap
- Output без secrets
- Перевіряйте State, Health.Log та events
- Не плутайте restart counter з health failures
- Тестуйте recovery
8. Лабораторна робота
Створіть повільний gate, успішну migration та залежний застосунок. --wait має завершитися після виконання умов.
mkdir -p /tmp/docker-module-11
printf '%s\n' 'name: docker-m11' 'services:' ' gate:' ' image: alpine:3.21' ' command: ["sh", "-c", "rm -f /tmp/ready; sleep 4; touch /tmp/ready; sleep 300"]' ' healthcheck:' ' test: ["CMD", "test", "-f", "/tmp/ready"]' ' interval: 1s' ' timeout: 1s' ' retries: 5' ' start_period: 2s' ' start_interval: 500ms' ' restart: unless-stopped' ' migrate:' ' image: alpine:3.21' ' command: ["sh", "-c", "echo migration=complete"]' ' app:' ' image: alpine:3.21' ' command: ["sh", "-c", "date -u +app_started=%FT%TZ; sleep 300"]' ' depends_on:' ' gate:' ' condition: service_healthy' ' migrate:' ' condition: service_completed_successfully' > /tmp/docker-module-11/compose.yaml
cd /tmp/docker-module-11
docker compose config --quiet
docker compose up --detach --wait --wait-timeout 30
docker compose ps --all
docker compose logs --no-color gate migrate appcd /tmp/docker-module-11
docker inspect docker-m11-gate-1 --format 'state={{.State.Status}} health={{.State.Health.Status}} restarts={{.RestartCount}}'
docker inspect docker-m11-gate-1 --format '{{json .State.Health.Log}}' | jq '.[-3:] | map({Start,End,ExitCode,Output})'
docker events --since 10m --until 0s --filter container=docker-m11-gate-1 --filter event=health_statusЗробіть gate unhealthy без restart, потім відновіть ready state.
cd /tmp/docker-module-11
docker compose exec --interactive=false gate rm /tmp/ready
sleep 6
docker inspect docker-m11-gate-1 --format 'state={{.State.Status}} health={{.State.Health.Status}} restarts={{.RestartCount}}'
docker compose exec --interactive=false gate touch /tmp/ready
sleep 2
docker inspect docker-m11-gate-1 --format 'state={{.State.Status}} health={{.State.Health.Status}} restarts={{.RestartCount}}'Окремо перевірте обмежений on-failure restart.
docker run --detach --name docker-m11-restart --restart on-failure:2 alpine:3.21 sh -c 'n=0; test -f /attempt && n=$(cat /attempt); n=$((n+1)); echo "$n" > /attempt; echo attempt=$n; test "$n" -ge 3 && sleep 300; exit 1'
sleep 6
docker inspect docker-m11-restart --format 'state={{.State.Status}} exit={{.State.ExitCode}} restarts={{.RestartCount}}'
docker logs docker-m11-restart
docker update --restart no docker-m11-restartКритерій: app стартує після healthy та migration; unhealthy має RestartCount 0; restart-demo доходить до третьої спроби.
9. Діагностика starting, unhealthy та restart loop
Розділяйте failure probe, застосунку та runtime.
cd /tmp/docker-module-11
docker compose ps --all
docker inspect docker-m11-gate-1 --format '{{json .State}}' | jq
docker inspect docker-m11-gate-1 --format '{{json .Config.Healthcheck}}' | jq
docker compose logs --no-color --timestamps --tail 50
docker events --since 10m --until 0s --filter type=container | tail -30- Config.Healthcheck — command і timers
- State.Health.Log — exit, duration та output
- State.ExitCode/OOMKilled/Error — завершення PID 1
- RestartCount та events — рестарти
- Compose logs — порядок dependencies
- ручний probe — після evidence
10. Контроль і cleanup
- Чому running не ready?
- Як працює start_period?
- Чи restart робить unhealthy?
- service_started чи service_healthy?
- Коли service_completed_successfully?
- always чи unless-stopped?
- Чим небезпечний restart loop?
- Що містить Health.Log?
docker rm --force docker-m11-restart 2>/dev/null || true
cd /tmp/docker-module-11
docker compose down --remove-orphans
cd /
rm -f /tmp/docker-module-11/compose.yaml
rmdir /tmp/docker-module-11
docker ps -a --filter name=docker-m11Модуль засвоєно, якщо ви доводите готовність фактами й відрізняєте startup dependency від runtime recovery.