Гид по технологиям

Увеличение томов PVC в StatefulSet Kubernetes

3 min read Kubernetes Обновлено 16 Dec 2025
Увеличение томов PVC в StatefulSet Kubernetes
Увеличение томов PVC в StatefulSet Kubernetes

Логотип Kubernetes

Kubernetes не позволяет прямо изменить поле volumeClaimTemplates в манифесте StatefulSet. Чтобы увеличить размер томов, вручную измените PVC, затем временно удалите (orphan) StatefulSet, примените обновлённый манифест и перезапустите поды. Этот процесс минимизирует простой и гарантирует фактическое расширение томов при условии, что драйвер хранения поддерживает расширение.

Быстрые ссылки

  • Создание StatefulSet

  • Ручное изменение размера томов StatefulSet

  • Воссоздание StatefulSet

  • Краткое резюме

Введение

StatefulSet в Kubernetes используют для развёртывания stateful-приложений внутри кластера. Каждый Pod в StatefulSet получает свой собственный PersistentVolumeClaim (PVC), который привязан к Pod и остаётся за ним даже после перезапуска. Это позволяет Pod-ам хранить уникальное состояние, отдельное от соседей.

Важно: стандартный объект StatefulSet не поддерживает изменение размера поля volumeClaimTemplates.spec.resources.requests.storage — оно считается неизменяемым после создания манифеста. Поэтому попытка просто изменить YAML и выполнить kubectl apply приведёт к ошибке.

Проблема: immutable volumeClaimTemplates

Поле

volumeClaimTemplates

в манифесте StatefulSet содержит шаблон для PVC, и большинство его свойств становятся неизменяемыми после создания StatefulSet. Например, попытка изменить “storage” с 1Gi на 10Gi в этом шаблоне выдаст ошибку вида:

The StatefulSet "nginx" is invalid: spec: Forbidden: updates to statefulset spec for fields other than 'replicas', 'template', 'updateStrategy', 'persistentVolumeClaimRetentionPolicy' and 'minReadySeconds' are forbidden

Это ограничение заставляет администраторов выполнять дополнительные ручные шаги для увеличения размера томов.

Создание 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


Примените в кластер:

$ kubectl apply -f ss.yaml


Ожидаемый вывод:

service/nginx created

statefulset.apps/nginx created


Это создаёт StatefulSet с тремя репликами NGINX и PVC размером 1Gi для каждого Pod. В реальной среде размер данных может вырасти — и вам потребуется увеличить объём.

## Когда прямое изменение не сработает

Если вы отредактируете ss.yaml и измените volumeClaimTemplates.spec.resources.requests.storage на 10Gi, а затем выполните kubectl apply, вы получите ошибку (см. раздел выше). Это нормальное поведение — манифест StatefulSet в этом отношении иммутабелен.

## Ручное изменение размера PVC

Обходной путь — напрямую изменить каждый PVC, созданный на основе volumeClaimTemplates. После этого потребуется заставить Kubernetes фактически выполнить расширение тома — обычно это достигается временным освобождением PVC от контроллера StatefulSet и перезапуском подов.

Шаги:

1. Найдите 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


2. Отредактируйте каждый PVC и измените spec.resources.requests.storage на желаемый объём:

$ kubectl edit pvc data-nginx-0


В редакторе найдите:

spec: resources:

requests:
  storage: 10Gi

Сохраните и закройте редактор. Kubectl сообщит об успешном редактировании:

persistentvolumeclaim/data-nginx-0 edited


Повторите для остальных PVC.

3. Проверьте PV — провиженер должен отразить новый размер:

$ 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


Обратите внимание: PVC могут временно показывать старый размер, пока томы всё ещё примонтированы к запущенным подам. Расширение файловой системы внутри пода обычно выполняется после размонтирования/перемонтирования или перезапуска пода.

## Освобождение томов и воссоздание StatefulSet

Чтобы фактически применить увеличение, нужно освободить PVC от контроллера StatefulSet, не удаляя сами поды. Для этого удалите StatefulSet с флагом --cascade=orphan:

$ kubectl delete statefulset –cascade=orphan nginx


Это удалит объект StatefulSet, но не поды и не PVC. После этого поды продолжают работать, но уже не контролируются StatefulSet.

Далее обновите ss.yaml, чтобы volumeClaimTemplates указывал новый размер (например, 10Gi), и снова примените его:

$ kubectl apply -f ss.yaml


Ожидаемый вывод:

service/nginx unchanged

statefulset.apps/nginx created


Новый StatefulSet «заберёт» существующие поды, поскольку они удовлетворяют его селекторам и требованиям. Часто потребуется инициировать контролируемый rollout, чтобы поды были перезапущены по одному и файловые системы увидели новый размер:

$ kubectl rollout restart statefulset nginx


Rollout будет выполняться последовательно (по одному 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


Файловая система показывает ожидаемые ~10 Gi.

## Ограничения и требования

- Драйвер хранения должен поддерживать динамическое расширение (allowVolumeExpansion). Начиная с Kubernetes v1.24 это стало общедоступной возможностью, но не все провайдеры или дистрибуции поддерживают её одинаково. Проверьте:

$ kubectl get sc


и убедитесь, что в колонке ALLOWVOLUMEEXPANSION стоит true для используемого StorageClass.

- Расширение блоковых томов обычно работает без проблем. Для расширения файловой системы внутри пода может потребоваться её размонтировать/перемонтировать или перезапустить под.

- Если том используется одновременно несколькими нодами в режиме, несовместимом с расширением, вы не сможете увеличить размер онлайн.

## Риски и смягчения

- Риск: человеческая ошибка при редактировании PVC приведёт к потере данных.
  - Смягчение: делайте snapshot/backup перед операцией, выполняйте изменения поочерёдно и проверяйте состояние PV/PVC.

- Риск: StorageClass не поддерживает расширение.
  - Смягчение: проверить поддержку заранее и подготовить план миграции томов (создание нового PV + синхронизация данных).

- Риск: несовместимость с облачным провайдером.
  - Смягчение: протестировать процедуру в тестовом кластере перед PROD.

## Побочные подходы и альтернативы

1. Миграция данных на новый PVC / PV

   - Создайте новый PVC с нужным размером.
   - Распакуйте или синхронизируйте данные (rsync, tar, копирование внутри кластера).
   - Обновите Deployment/StatefulSet для использования нового PVC (может потребовать создания нового StatefulSet и поочерёдного переключения).

   Плюсы: не зависит от allowVolumeExpansion. Минусы: сложнее и дольше.

2. Использовать CSI-операторы или кастомные контроллеры

   - Некоторые CSI-драйверы или операторы предоставляют дополнительные возможности по управлению томами и миграциям.

3. Планирование и мониторинг заполнения

   - Используйте метрики (Prometheus) и оповещения, чтобы заранее узнавать, что томы заполняются, и выполнять resize заранее.

## Пошаговый SOP для администратора (Playbook)

1. Подготовка
   - Убедитесь, что у вас есть бэкап/снимок данных.
   - Проверьте allowVolumeExpansion у StorageClass: `kubectl get sc`.
   - Оповестите команду о плановом окне.

2. Изменение PVC
   - Для каждого PVC выполните `kubectl edit pvc <имя>` и обновите `spec.resources.requests.storage`.
   - Подтвердите изменение: `kubectl get pv` — проверьте CAPACITY.

3. Освобождение StatefulSet
   - Выполните `kubectl delete statefulset --cascade=orphan `.

4. Обновление манифеста
   - Обновите volumeClaimTemplates в ss.yaml на новый размер.
   - Примените `kubectl apply -f ss.yaml`.

5. Rollout
   - Запустите `kubectl rollout restart statefulset `.
   - Мониторьте статус: `kubectl rollout status statefulset `.

6. Верификация
   - Для каждого пода: `kubectl exec -it  -- df -h `.
   - Проверьте приложения и метрики.

7. Откат (если необходимо)
   - Если обнаружены проблемы, восстановите данные из бэкапа и верните предыдущий манифест.

## Роль‑ориентированные контрольные списки

Администратор кластера

- Проверить allowVolumeExpansion в StorageClass.
- Сделать snapshot или бэкап.
- Координировать окно изменений.

DevOps / Разработчик

- Обновить ss.yaml с новым размером.
- Подтвердить, что приложение корректно перезагружается.

Storage‑администратор

- Подтвердить поддержку расширения в провайдере хранения.
- Проверить состояние PV после изменений.

## Быстрый чек-лист для тестирования (Test cases)

- После изменения PVC PV показывает новый CAPACITY.
- После перезапуска pod внутри df -h показывает ожидаемый размер.
- Нагрузка на приложение остаётся в допустимых пределах во время поочередного rollout.

## Полезные heuristics и ментальные модели

- Всегда работайте с одним PVC за раз в продакшене, если не уверены в проводимости процесса.
- Подход «orphan и reapply» минимизирует время, когда поды вовсе отсутствуют, т.к. они остаются запущенными.
- Хранение данных и контроль за их размерами — плановая задача мониторинга, а не реактивная операция.

## Troubleshooting — распространённые проблемы и решения

Проблема: PVC не расширился, PV остался прежнего размера.
- Возможная причина: драйвер хранения не поддерживает динамическое расширение.
- Решение: проверьте StorageClass, обратитесь к поставщику, используйте миграцию на новый PV.

Проблема: файл система внутри пода не показывает увеличение после расширения PV.
- Причина: файловая система не была расширена автоматически.
- Решение: перезапустите pod или выполните ручное расширение (например, resize2fs для ext4) внутри пода.

Проблема: при удалении StatefulSet с --cascade=orphan поды утрачивают нужные метаданные и не привязываются обратно.
- Решение: проверьте селекторы и labels в манифесте нового StatefulSet. Они должны совпадать с теми, что есть у существующих подов.

## Совместимость и миграция

Проверьте следующее перед операцией:

- StorageClass.allowVolumeExpansion = true
- Версия Kubernetes >= 1.24 (рекомендуется) для стабильного поведения расширения томов
- Документация облачного провайдера/CSI-драйвера на предмет известных ограничений

Если driver не поддерживает расширение:
- Рассмотрите миграцию данных на новый PVC с желаемым размером.
- Используйте инструменты синхронизации (rsync) или snapshot/restore.

## Мермад-диаграмма решения (decision tree)

flowchart TD A[Нужно увеличить том StatefulSet?] –> B{Поддерживает ли StorageClass allowVolumeExpansion?} B – Да –> C[Редактировать PVC напрямую и изменить size] C –> D{Прикреплён ли PVC к запущенным подам?} D – Да –> E[Удалить StatefulSet –cascade=orphan] D – Нет –> F[Применить новый манифест StatefulSet] E –> F F –> G[Rollout restart StatefulSet] G –> H[Проверить df -h внутри пода] B – Нет –> I[Создать новый PVC + синхронизация данных] I –> J[Перенести приложение на новый PVC]


## Краткое резюме

- StatefulSet не позволяет менять размер volumeClaimTemplates напрямую.
- Рабочий обход: отредактировать PVC, удалить StatefulSet с --cascade=orphan, обновить манифест и перезапустить rollout.
- Убедитесь, что StorageClass поддерживает allowVolumeExpansion. Всегда имейте резервную копию данных.

Важно: процесс требует аккуратности и тестирования в непроизводственной среде перед применением в продакшене.

## Глоссарий (1 строка каждого термина)

- PVC: PersistentVolumeClaim — запрос на постоянный том в Kubernetes.
- PV: PersistentVolume — реальный том, предоставленный кластером.
- StorageClass: класс хранения, описывающий провиженер и параметры PV.
- StatefulSet: контроллер Kubernetes для управляния stateful-приложениями.

---

Ниже приведены ключевые команды для быстрой работы:

kubectl get pvc kubectl edit pvc <имя> kubectl get pv kubectl delete statefulset –cascade=orphan kubectl apply -f ss.yaml kubectl rollout restart statefulset kubectl exec -it – df -h


Важно: перед операциями на продакшене делайте бэкап и тестируйте процедуру в staging.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Вернуть Панель управления в меню Windows X
Windows

Вернуть Панель управления в меню Windows X

Диагностика интернета через Chrome
Техника

Диагностика интернета через Chrome

Как просмотреть архивированные публикации в Instagram
Социальные сети

Как просмотреть архивированные публикации в Instagram

Видео TikTok как обои на Android
Android.

Видео TikTok как обои на Android

Отключить подсказки поиска в Windows
Windows

Отключить подсказки поиска в Windows

Устранение проблем Android Auto
Руководства

Устранение проблем Android Auto