Ответ
StatefulSet — это контроллер рабочей нагрузки в Kubernetes, предназначенный для развертывания и управления stateful-приложениями, которым требуется сохранение состояния, стабильные сетевые идентификаторы и гарантированный порядок развертывания.
Ключевые отличия от Deployment:
- Стабильные идентификаторы подов: Каждому поду присваивается предсказуемое и неизменяемое имя (например,
app-0,app-1), которое сохраняется при перезапуске. - Стабильное сетевое имя: Каждый под получает DNS-имя по шаблону:
$(pod-name).$(service-name).$(namespace).svc.cluster.local. - Упорядоченное развертывание и масштабирование: Поды создаются и удаляются последовательно (от 0 до N-1), что критично для кластерных приложений.
- Устойчивое хранилище: Используя
volumeClaimTemplates, каждому поду выделяется свой уникальный PersistentVolumeClaim (PVC). При пересоздании пода он подключается к тому же тому.
Типичные сценарии использования:
- Кластеры баз данных (MySQL, PostgreSQL, MongoDB).
- Системы обмена сообщениями (Kafka, RabbitMQ).
- Кэши и хранилища данных (Redis, Elasticsearch, Cassandra).
Пример манифеста для StatefulSet с MySQL:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql-hs # Обязательно указывается Headless Service
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumeClaimTemplates: # Шаблон для создания PVC для каждого пода
- metadata:
name: mysql-data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 10Gi Ответ 18+ 🔞
А, StatefulSet! Ну это, блядь, такая штука в кубере, когда твоему приложению нельзя просто так взять и переехать на новое место, как бомжу под мостом. Ему там своя койка нужна, свой шкафчик и имя, чтобы не путали с другими.
Если простыми словами — это для тех приложений, которые помнят. Ну, как бабушка, которая тебя в детстве по попе шлёпала, и ты до сих пор не можешь спокойно слышать звук ремня. Им нужно состояние сохранять, сеть стабильную и чтоб всё по порядку.
Чем он от обычного Deployment отличается, ёпта?
- Имена подов — на века. Тут не будет этих рандомных
app-xyz123. Тут всё чинно-благородно:app-0,app-1. Перезапустился под — имя его не меняется. Как паспорт, блядь. Удобно. - Сеть тоже не подведёт. У каждого пода свой собственный адрес в сети, по которому его можно найти. Типа
mysql-1.mysql-service.default.svc.cluster.local. Предсказуемо, как восход солнца после хорошей пьянки. - Порядок — всё. Создаются и удаляются они строго по очереди: сначала нулевой, потом первый и так далее. Нельзя второго запустить, пока первый не встал как вкопанный. И наоборот, при удалении — сначала последнего грохнут. Это чтобы в кластерах, типа баз данных, не было каши в репликации.
- Диски — родные. Самое сокровенное. Каждому поду через
volumeClaimTemplatesвыдают его личный, именной жесткий диск (PersistentVolumeClaim). Упал под, воскрес — а данные его ждут. Как верная собака. В Deployment'е же при пересоздании под прикручивается новый, пустой том, и все твои гигабайты логов накрываются медным тазом.
Где эту хрень использовать? Да везде, где приложение не тупая статика, а хитрая жопа со своим характером:
- Базы данных всякие (MySQL, Postgres, Mongo) — им же репликацию настраивать надо.
- Очереди сообщений (Kafka, RabbitMQ) — там тоже свой порядок важен.
- Разные Elasticsearch, Redis, Cassandra — короче, всё, что stateful.
Вот тебе пример, как это выглядит, на случай MySQL:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql-hs # Вот это ОБЯЗАТЕЛЬНО! Без Headless Service — нихуя не заработает.
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumeClaimTemplates: # А вот это магия! Для каждого пода свой PVC создаст.
- metadata:
name: mysql-data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 10Gi
Короче, если твоё приложение — не безмозглая статика, а что-то посерьёзнее, что данные терять не хочет, то StatefulSet — твой выбор. Просто помни, что это овердохуища ответственности: удалишь StatefulSet не глядя — и твои PVC с данными могут остаться висеть сиротами, если специально не почистишь. Так что, э, бошка думай, прежде чем что-то делать.