Какие механизмы в Kubernetes используются для проверки работоспособности и готовности приложения?

Ответ

В Kubernetes для проверки состояния приложения в контейнере используются Probes (пробы или проверки). Они помогают kubelet понять, когда нужно перезапустить контейнер или когда он готов принимать трафик.

Существует три основных типа проб:

  1. Liveness Probe (Проверка жизнеспособности)

    • Назначение: Проверяет, работает ли приложение. Если проба завершается неудачно, kubelet убивает контейнер, и он перезапускается в соответствии со своей restartPolicy.
    • Пример использования: Обнаружение дедлоков или ситуаций, когда приложение зависло, но процесс еще существует.
  2. Readiness Probe (Проверка готовности)

    • Назначение: Проверяет, готово ли приложение принимать трафик. Если проба не проходит, эндпоинты этого пода удаляются из объектов Service. Трафик на него перестает поступать, пока проба снова не станет успешной.
    • Пример использования: Приложение запущено, но ему нужно время на загрузку конфигурации, данных или установку соединений с базой данных.
  3. Startup Probe (Проверка запуска)

    • Назначение: Используется для приложений, которые долго запускаются. Она отключает Liveness и Readiness пробы до тех пор, пока сама не завершится успешно. Это предотвращает убийство контейнера до того, как он успел полностью запуститься.
    • Пример использования: Тяжеловесные Java-приложения или приложения, которым нужно прочитать большой объем данных при старте.

Способы проверки

Для всех проб можно настроить один из трех механизмов проверки:

  • httpGet: Выполняет GET-запрос к указанному эндпоинту. Ответ с кодом 2xx или 3xx считается успешным.
  • tcpSocket: Пытается установить TCP-соединение с указанным портом. Успешное соединение — успех.
  • exec: Выполняет команду внутри контейнера. Код завершения 0 — успех.

Пример манифеста:

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: my-app-container
    image: my-app-image
    ports:
    - containerPort: 8080
    # Проверка, что приложение готово принимать трафик
    readinessProbe:
      httpGet:
        path: /ready
        port: 8080
      initialDelaySeconds: 15 # Начать проверку через 15 секунд после старта
      periodSeconds: 10     # Проверять каждые 10 секунд

    # Проверка, что приложение "живо"
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
      initialDelaySeconds: 30
      periodSeconds: 20
      failureThreshold: 3 # Считать сбоем после 3 неудачных попыток

Ответ 18+ 🔞

О, блядь, смотри, что я тебе сейчас расскажу про Кубер! Это ж, ёпта, целая наука, как понять, жив твой контейнер или уже накрылся медным тазом.

Вот представь: запустил ты приложение в поде, а оно, сука, зависло. Процесс вроде есть, а отзывается нихуя. Или наоборот — запускается оно долго, как черепаха в сиропе, а Кубер уже нервничает и пытается его прибить. Вот для этого и придумали Probes, или пробы, если по-нашему. Это такие штуки, которые тыкают палкой в твое приложение и смотрят, отзовётся ли оно.

Их три вида, и каждый — со своим характером, блядь:

  1. Liveness Probe (Проверка жизнеспособности)

    • Задача простая, как три копейки: понять, не сдохло ли приложение. Если эта проба говорит «всё, пиздец», то kubelet без лишних слов прибивает контейнер. А дальше срабатывает политика перезапуска (restartPolicy), и он воскресает, как феникс, только, возможно, с теми же багами.
    • Когда юзать: Когда приложение может зависнуть в дедлоке. С виду процесс есть, а по факту — труп. Вот эта проба его и вычислит.
  2. Readiness Probe (Проверка готовности)

    • Тут уже хитрее: она проверяет, готово ли приложение работать. Не просто запустилось, а именно принимать трафик. Если проба провалилась, под выпиливают из списка эндпоинтов Service. И весь трафик на него, блядь, перестаёт идти. Сидит он в углу, думает о своём поведении, пока не исправится.
    • Когда юзать: Приложение встало, но ему надо полминуты, чтобы подключиться к базе, загрузить конфиги или просто проснуться. Чтобы в это время на него не сыпались запросы, которые оно всё равно проебёт.
  3. Startup Probe (Проверка запуска)

    • Это для тех, кто долго раскачивается: представь себе здоровенное Java-приложение, которое стартует минуты три. Пока оно грузится, liveness и readiness пробы будут тыкаться в него каждые 10 секунд и охуевать от неудач. И в итоге убьют его ещё до того, как оно успело полностью родиться! Startup Probe решает эту проблему. Она говорит: «Отстаньте все, дайте ему запуститься!». И только когда эта проба скажет «ок», остальные две начнут свою работу.
    • Когда юзать: Для монстров, которые долго идут на старт. Спасёт от преждевременного убийства.

Как тыкать палкой?

Есть три способа, блядь, проверить приложение:

  • httpGet: Просто послать GET-запрос на какой-нибудь /health эндпоинт. Если в ответе код 200 или 304 — значит, живой. Если 500 — ну, извини, дружок.
  • tcpSocket: Попытаться достучаться до порта. Соединение установилось — красава. Нет — пиши пропало.
  • exec: Запустить команду прямо внутри контейнера. Если она выполнилась и вернула код 0 — всё заебись. Не 0 — ну ты понял.

Смотри, как это в коде выглядит:

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: my-app-container
    image: my-app-image
    ports:
    - containerPort: 8080
    # Проверка, что приложение готово принимать трафик
    readinessProbe:
      httpGet:
        path: /ready
        port: 8080
      initialDelaySeconds: 15 # Не лезь к нему сразу, дай 15 секунд на раскачку
      periodSeconds: 10     # И потом тыкайся каждые 10 секунд

    # Проверка, что приложение "живо"
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
      initialDelaySeconds: 30 # А эту проверку начни ещё позже
      periodSeconds: 20       # Тыкай раз в 20 секунд
      failureThreshold: 3 # И только после трёх пиздюлей считай, что всё — конец

Вот и вся магия, ёпта. Настроил пробы — и спи спокойно. А то без них твой под может быть мёртвым, но красивым, и трафик на него будет идти, как в чёрную дыру.