StatefulSet, Stateless vs Stateful и Headless Service

From wiki.baghirzade.pro
Revision as of 21:44, 6 January 2026 by Sadmin (talk | contribs) (Created page with "=== 1. Stateless vs Stateful: В чем разница? === * '''Stateless (Без состояния):''' ** '''Примеры:''' Веб-серверы (Nginx), микросервисы. ** '''Суть:''' Любой под можно удалить и заменить новым, ничего не потеряв. Данные сессии обычно хранятся во внешнем хранилище (Redis). ** '''Объект в K8s:''' <code>Deployment</code...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

1. Stateless vs Stateful: В чем разница?

  • Stateless (Без состояния):
    • Примеры: Веб-серверы (Nginx), микросервисы.
    • Суть: Любой под можно удалить и заменить новым, ничего не потеряв. Данные сессии обычно хранятся во внешнем хранилище (Redis).
    • Объект в K8s: Deployment.
    • Хранилище: Все реплики могут использовать один и тот же PV/PVC (общая папка).
  • Stateful (С состоянием):
    • Примеры: Базы данных (PostgreSQL, MySQL), брокеры сообщений (Kafka, RabbitMQ).
    • Суть: Каждому поду нужны его собственные уникальные данные. Если pod-0 упал, он должен подняться именно как pod-0 и подключиться к своему старому диску.
    • Объект в K8s: StatefulSet.

2. Особенности StatefulSet

  1. Стабильные имена: Поды получают индексы: web-0, web-1, web-2. При перезагрузке имя сохраняется.
  2. Порядок запуска/удаления: Поды запускаются по очереди (0 -> 1 -> 2) и удаляются в обратном порядке (2 -> 1 -> 0). Это критично для кластеров БД (сначала Master, потом Replica).
  3. Volume Claim Templates: Вместо одного общего PVC, в StatefulSet описывается шаблон. K8s автоматически создает отдельный PVC для каждой реплики.
    • Пример: Для web-0 будет создан data-web-0, для web-1data-web-1.

3. Headless Service (Сервис без IP)

Для баз данных (например, Master-Slave) нам нужно обращаться не к "любому" поду через балансировщик, а к конкретному (например, только к Master для записи).

  • Настройка: В манифесте Service указывается clusterIP: None.
  • Результат: Сервис не получает виртуальный IP. Вместо этого DNS-запрос к сервису возвращает список IP-адресов всех подов.
  • DNS-имя пода: Становится возможным обратиться напрямую к поду по адресу: <pod-name>.<service-name>.
    • Пример: mysql-0.mysql-service.

4. Жизненный цикл и Graceful Shutdown (Мягкое завершение)

Когда K8s удаляет под, он посылает сигнал SIGTERM. По умолчанию у пода есть 30 секунд (terminationGracePeriodSeconds), чтобы закончить работу.

  • Проблема: База данных может закрывать транзакции дольше 30 секунд.
  • Решение — PreStop Hook: Это команда, которая выполняется перед тем, как под начнет удаляться.
    • Пример: Скрипт, который переключает Master на другую ноду или корректно завершает сессии.
lifecycle:
  preStop:
    exec:
      command: ["/bin/sh", "-c", "sleep 60"] # Даем приложению время доработать

5. Практический пример: Кластер PostgreSQL

Для создания полноценного кластера БД в K8s требуется связка:

  1. ConfigMap: Скрипты инициализации и настройки репликации.
  2. Secret: Пароли для суперпользователя и репликации.
  3. Headless Service: Для связи между узлами (Master видит Slave-ов).
  4. Standard Service: Для чтения (Read-only балансировщик между всеми узлами).
  5. StatefulSet: Сами поды с БД и volumeClaimTemplates для дисков.

Главные выводы урока:

  • Используйте StatefulSet, если приложению важна идентичность (имя и диск).
  • Headless Service необходим для того, чтобы компоненты кластера (например, узлы MySQL) знали адреса друг друга напрямую.
  • PreStop Hooks — обязательная настройка для баз данных, чтобы избежать повреждения данных при перезагрузке нод или обновлении кластера.