Как изменить размер томов Kubernetes StatefulSet
Kubernetes StatefulSets используются для развертывания приложений с отслеживанием состояния внутри вашего кластера. Каждый под в StatefulSet может получить доступ к локальным постоянным томам, которые остаются с ним даже после перепланирования. Это позволяет модулям поддерживать индивидуальное состояние, отдельное от их соседей в наборе.
К сожалению, у этих томов есть большое ограничение: Kubernetes не предоставляет способа изменить их размер из объекта StatefulSet. Свойство spec.resources.requests.storage
поля volumeClaimTemplates
StatefulSet является неизменяемым, что не позволяет вам применить любое увеличение емкости, которое вам требуется. Эта статья покажет вам, как обойти эту проблему.
Создание StatefulSet
Скопируйте этот YAML и сохраните его в ss.yaml
:
apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: selector: app: nginx ports: - name: nginx port: 80 clusterIP: None --- apiVersion: apps/v1 kind: StatefulSet metadata: name: nginx spec: selector: matchLabels: app: nginx replicas: 3 serviceName: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - name: web containerPort: 80 volumeMounts: - name: data mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: data spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 1Gi
Примените YAML к своему кластеру с помощью Kubectl:
$ kubectl apply -f ss.yaml
service/nginx created
statefulset.apps/nginx created
Для запуска этого примера вам понадобится класс хранилища и средство подготовки в вашем кластере. Он создает StatefulSet, который запускает три реплики веб-сервера NGINX.
Хотя это не показатель того, когда следует использовать StatefulSets, его достаточно для демонстрации проблем с объемом, с которыми вы можете столкнуться. Заявка на том с хранилищем объемом 1 Гигабайт монтируется в каталог данных NGINX. Ваш веб-контент может перерасти это относительно небольшое ограничение по мере масштабирования вашего сервиса. Однако попытка изменить поле volumeClaimTemplates.spec.resources.requests.storage
на 10Gi
сообщит о следующей ошибке при запуске kubectl apply
:
$ kubectl apply -f ss.yaml
service/nginx unchanged
The StatefulSet "nginx" is invalid: spec: Forbidden: updates to statefulset spec for fields other than 'replicas', 'template', 'updateStrategy', 'persistentVolumeClaimRetentionPolicy' and 'minReadySeconds' are forbidden
Это происходит потому, что почти все поля манифеста StatefulSet неизменяемы после создания.
Изменение размера томов StatefulSet вручную
Вы можете обойти это ограничение, вручную изменив размер заявки на постоянный том (PVC). Затем вам нужно будет воссоздать StatefulSet, чтобы освободить и повторно привязать том к вашим модулям. Это вызовет фактическое событие изменения размера тома.
Сначала используйте Kubectl, чтобы найти PVC, связанные с вашим StatefulSet:
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES
data-nginx-0 Bound pvc-ccb2c835-e2d3-4632-b8ba-4c8c142795e4 1Gi RWO
data-nginx-1 Bound pvc-1b0b27fe-3874-4ed5-91be-d8e552e515f2 1Gi RWO
data-nginx-2 Bound pvc-4b7790c2-3ae6-4e04-afee-a2e1bae4323b 1Gi RWO
Существует три PVC, потому что в StatefulSet есть три реплики. Каждый Pod получает свой индивидуальный том.
Теперь используйте kubectl edit
, чтобы настроить емкость каждого тома:
$ kubectl edit pvc data-nginx-0
В вашем редакторе появится YAML-манифест PVC. Найдите поле spec.resources.requests.storage
и измените его на новую желаемую емкость:
# ... spec: resources: requests: storage: 10Gi # ...
Сохраните и закройте файл. Kubectl должен сообщить, что изменение было применено к вашему кластеру.
persistentvolumeclaim/data-nginx-0 edited
Теперь повторите эти шаги для оставшихся PVC StatefulSet. Список постоянных томов вашего кластера должен показать новый размер для каждого из них:
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM
pvc-0a0d0b15-241f-4332-8c34-a24b61944fb7 10Gi RWO Delete Bound default/data-nginx-2
pvc-33af452d-feff-429d-80cd-a45232e700c1 10Gi RWO Delete Bound default/data-nginx-0
pvc-49f3a1c5-b780-4580-9eae-17a1f002e9f5 10Gi RWO Delete Bound default/data-nginx-1
Претензии пока сохранят старый размер:
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES
data-nginx-0 Bound pvc-33af452d-feff-429d-80cd-a45232e700c1 10Gi RWO
data-nginx-1 Bound pvc-49f3a1c5-b780-4580-9eae-17a1f002e9f5 10Gi RWO
data-nginx-2 Bound pvc-0a0d0b15-241f-4332-8c34-a24b61944fb7 10Gi RWO
Это связано с тем, что размер тома нельзя изменить, пока модули все еще его используют.
Воссоздание StatefulSet
Завершите изменение размера, освободив требование тома из StatefulSet, в котором оно содержится. Удалите StatefulSet, но используйте каскадный механизм orphan
, чтобы его модули оставались в вашем кластере. Это поможет минимизировать время простоя.
$ kubectl delete statefulset --cascade=orphan nginx
statefulset.apps "nginx" deleted
Затем отредактируйте исходный файл YAML, чтобы включить новый размер тома в файл spec.resources.requests.storage
. Затем используйте kubectl apply
, чтобы воссоздать StatefulSet в вашем кластере:
$ kubectl apply -f ss.yaml
service/nginx unchanged
statefulset.apps/nginx created
Новый StatefulSet возьмет на себя владение ранее потерянными модулями, поскольку они уже будут соответствовать его требованиям. На этом этапе размер томов может измениться, но в большинстве случаев вам придется вручную инициировать развертывание, которое перезапустит ваши модули:
$ kubectl rollout restart statefulset nginx
Развертывание происходит последовательно, ориентируясь на один Pod за раз. Это гарантирует, что ваш сервис останется доступным на протяжении всего времени.
Теперь ваши PVC должны показывать новый размер:
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES
data-nginx-0 Bound pvc-33af452d-feff-429d-80cd-a45232e700c1 10Gi RWO
data-nginx-1 Bound pvc-49f3a1c5-b780-4580-9eae-17a1f002e9f5 10Gi RWO
data-nginx-2 Bound pvc-0a0d0b15-241f-4332-8c34-a24b61944fb7 10Gi RWO
Попробуйте подключиться к одному из ваших модулей, чтобы убедиться, что увеличенная емкость видна изнутри:
$ kubectl exec -it nginx-0 bash
root@nginx-0:/# df -h /usr/share/nginx/html
Filesystem Size Used Avail Use% Mounted on
/dev/disk/by-id/scsi-0DO_Volume_pvc-33af452d-feff-429d-80cd-a45232e700c1 9.9G 4.5M 9.4G 1% /usr/share/nginx/html
Pod сообщает об ожидаемых 10 Гигабайтах хранилища.
Краткое содержание
Kubernetes StatefulSets позволяет запускать приложения с отслеживанием состояния в Kubernetes с томами постоянного хранилища, которые привязаны к отдельным модулям. Однако гибкость, которую это позволяет, заканчивается, когда вам нужно изменить размер одного из ваших томов. Это отсутствующая функция, которая в настоящее время требует последовательного выполнения нескольких ручных шагов.
Сопровождающие Kubernetes знают об этой проблеме. Существует открытый запрос функции для разработки решения, которое в конечном итоге должно позволить вам инициировать изменение размеров тома путем редактирования манифеста StatefulSet. Это будет намного быстрее и безопаснее, чем сейчас.
Последнее предостережение заключается в том, что изменение размеров тома зависит от драйвера хранилища, допускающего динамическое расширение. Эта функция стала общедоступной только в Kubernetes v1.24, и не все драйверы, дистрибутивы Kubernetes и облачные платформы будут ее поддерживать. Вы можете проверить, работает ли ваш, запустив kubectl get sc
и найдя true
в столбце ALLOWVOLUMEXPANSION
драйвера хранилища, который вы используете с вашим StatefulSets.