Statefulsets
Определение
StatefulSet – это контроллер Kubernetes, применяемый для эксплуатации сохраняющих состояние приложений в виде контейнеров (подов) в кластере Kubernetes.
StatefulSet присваивают каждому поду идентификатор-липучку (sticky identity) – порядковый номер начиная с нуля — а не случайные ID каждой реплике пода. Новый под создается клонированием данных уже существовавшего пода. Если ранее существовавший под находился в ожидающем состоянии, то новый под создан не будет. Удаление подов происходит в обратном порядке, а не в случайном. Например, если у вас было четыре реплики, и в результате масштабирования их количество было сокращено до трех, то под номер 3 будет удален.
Что такое приложения с сохранением состояния?
Это приложения, которые сохраняют данные и помогают их отслеживать. Все базы данных, в частности, MySQL, Oracle и PostgreSQL – это примеры приложений, сохраняющих состояние. С другой стороны, в приложениях без сохранения состояния данные долго не держатся. Примеры приложений без сохранения состояния — Node.js и Nginx. Если состояние в приложении не сохраняется, то на каждый запрос приложение будет получать новые данные и обрабатывать их.
В современных веб-приложениях такие приложения без сохранения состояния соединяются с приложениями, сохраняющими состояние, чтобы обслужить пользовательский запрос. Приложение Node.js не сохраняет состояние, оно получает новые данные при каждом запросе, поступающем от пользователя. Далее это приложение соединяется для обработки данных с другим, сохраняющим состояние, например, с базой данных MySQL. База данных MySQL сохраняет данные и продолжает их обновлять, исходя из пользовательского запроса.
Когда использовать StatefulSets
Есть несколько причин, по которым может быть целесообразно использовать StatefulSets. Рассмотрим два примера:
Допустим, вы развернули базу данных MySQL в кластере Kubernetes и масштабировали ее до трех реплик, а клиентское приложение пытается получить доступ к кластеру MySQL, чтобы считывать и записывать данные. Запрос на считывание будет переадресовываться на три пода. Однако запрос на запись будет переадресовываться только на первый (ведущий) под, а записанные сюда данные будут синхронизироваться с другими подами. Это достижимо при помощи StatefulSets.
Если удалить StatefulSet или отмасштабировать вниз, то не будут удалены тома, связанные с приложением, сохраняющим состояние. Так вашим данным обеспечивается безопасность. Если удалить или перезапустить под с MySQL, то вы сможете обращаться к данным из все того же тома, что и раньше.
Как создать StatefulSets в Kubernetes
Для создания нам необходим файл с YAML расширением.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql-state
spec:
selector:
matchLabels:
app: mysql
serviceName: "mysql"
replicas: 3
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0.34
ports:
- containerPort: 3306
name: web
volumeMounts:
- name: mysql-store
mountPath: /var/lib/mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: MYSQL_ROOT_PASSWORD
volumeClaimTemplates:
- metadata:
name: mysql-store
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "longhorn"
resources:
requests:
storage: 1Gi
Пройдемся по некоторым значениям:
В поле Kind мы прописываем значение файла;
Значение name в поле metadata, будущее название Pod'ов;
В matchlabels поле app необходимо чтобы связать statefulset с подконтрольными подами;
В разделе containers задается образ, который мы планируем равзернуть;
volumesMount задает путь монтирования томов хранения;
В поле env мы можем указать переменные и их значения, в данном случае мы указавали пароль, который хранится в серкрете mysql-secret, его нам предложат ввести на входе в БД;
volumeClaimTemplates представляет собой хранилище, у которого мы запрашиваем 1Гб памяти для одного пода с доступом ReadWriteOnce;
После того, как мы описали файл, его необходимо упомянуть в кубе при создании:
$ kubectl apply -f statefulset.yml
$ kubectl get sts
NAME READY AGE
mysql-state 3/3 23h
Увидеть список развернутых подов:
$ kubectl get pods
mysql-state-0 1/1 Running 0 23h
mysql-state-1 1/1 Running 0 23h
mysql-state-2 1/1 Running 0 23h