Скачать CV

DevOps

Liveness в Kubernetes это не healthcheck Docker

Compose ждёт, пока php-fpm слушает. Kubelet убивает под, который ещё компилирует OPcache. Readiness и liveness это разные ручки.

Первый деплой этого стека в Kubernetes выглядел как crash loop. Локальный запуск это Docker Compose: nginx, php, queue, mysql, redis, memcached. Healthcheck, который дергает /up после bind FPM, хватает. В Kubernetes та же проверка как liveness убивала под на прогреве. Первый запрос компилирует LaraBoom в OPcache. Это дольше дефолтного зонда.

Пользователи ловили 502 через Service. Kubelet рестартил процесс, который ещё компилировал. Readiness убирает под из Service, пока он не готов к трафику. Liveness перезапускает зависший под. Один зонд на оба случая: медленный старт выглядит как мёртвый процесс. Реплика не становится Ready.

Compose ждал. Kubelet убивал. В этом всё расхождение.

Readiness держит трафик. Liveness убивает. Прогрев не должен выглядеть как смерть.
Readiness держит трафик. Liveness убивает. Прогрев не должен выглядеть как смерть.

Первую минуту держит startupProbe

Startup бьёт в /up каждые пять секунд с высоким failureThreshold. Kubelet не запускает liveness, пока это не успешно. Потом liveness может убивать. Readiness остаётся на nginx перед FPM, не на маршруте, который ещё поднимает Doctrine или Eloquent.

Rolling update нужен maxUnavailable, который оставляет хотя бы один Ready php под. SIGTERM с деплоя та же история, что в Compose: воркеры должны доработать. Liveness во время drain делает 502 хуже.

Liveness я сначала направил на тот же /up, который поднимает фреймворк. Зонд падал, пока наполнялся OPcache, и снова, пока воркеры дренились. Дешёвой TCP-проверки порта FPM хватает для liveness после startup. Readiness по-прежнему HTTP через nginx, чтобы связанный FPM с мёртвым nginx трафик не брал.

startupProbe закрывает компиляцию OPcache. Потом liveness может рестартить. Readiness на nginx.
startupProbe закрывает компиляцию OPcache. Потом liveness может рестартить. Readiness на nginx.

Для чего Compose ещё нужен

Этот сайт остаётся на Compose и VPS, пока нет нескольких нод. Kubernetes это следующий шаг, не переименование compose-файла. Зонды, PodDisruptionBudget и настоящий readiness это цена шага. Скопировать healthcheck из Dockerfile в liveness это заплатить дважды.

Ещё я узнал, что под воркера очереди не должен делить web-readiness. Horizon может быть жив, пока FPM не отдаёт HTML. Разные зонды, иначе web Service заберёт queue-поды. PDB на php считает Ready web-поды, не каждый контейнер в поде.

Какой опыт из этого

На прогреве смотрю Ready против Restarts, не то, что FPM уже слушает. Crash loop при компиляции OPcache это liveness, скопированный из Compose.

Одному зонду на start, live и ready я не верю. startupProbe закрывает компиляцию. Liveness после этого может быть TCP на FPM. Readiness это nginx перед FPM.

Правило, которое оставляю: maxUnavailable оставляет один Ready php под. Liveness во время drain не гонять. healthcheck из Dockerfile в liveness не копировать. Compose остаётся, пока нет нескольких нод.

К заметкам