PVC и данные приложения
Что нужно знать перед уроком
- M6.06 — Паттерн «ожидание внешнего оператора» — нужен опыт с lifecycle-аннотациями перед последним паттерном модуля
- M1.06 — Volumes/PVC/StorageClass — нужна база PVC/StorageClass/reclaimPolicy из Kubernetes
Что нужно знать перед уроком
M1 урок 6 — PersistentVolumeClaim, StorageClass, reclaimPolicy. M6 урок 5 — werf.io/ownership: anyone для защиты от удаления при uninstall другого релиза. Здесь — специфичная и критичная тема: как защитить данные приложения (не сам ресурс, а именно PVC с реальными данными) от потери в разных сценариях удаления.
Теория
Два независимых уровня защиты — и оба нужны одновременно
Это два разных механизма, действующих на разных уровнях стека, и ни один не заменяет другой.
Уровень 1: helm.sh/resource-policy: keep
| |
Эта аннотация действует только в контексте операций Nelm/Helm: nelm release uninstall (M4 урок 5) или удаление конкретного ресурса из шаблонов чарта (если вы просто убрали блок PVC из templates/ и обновили релиз) не удалит PVC с этой аннотацией — Nelm пропустит его при вычислении «что нужно удалить» на стадии Plan. При этом ресурс продолжает обновляться обычным образом, пока он присутствует в рендере — keep защищает только от удаления, не «замораживает» ресурс полностью.
Важная оговорка из документации: helm.sh/resource-policy: keep не защищает от прямой команды удаления — если кто-то выполнит kubectl delete pvc <name> или d8 k delete pvc <name> напрямую, эта аннотация никак не помешает — она действует только внутри логики самого Nelm/Helm при операциях над релизом.
Уровень 2: persistentVolumeReclaimPolicy: Retain на StorageClass
| |
Это настройка уровня Kubernetes (M1 урок 6), никак не связанная с Nelm/Helm: reclaimPolicy: Retain определяет, что произойдёт с реальным PersistentVolume (физическим хранилищем), когда связанный с ним PersistentVolumeClaim будет удалён (неважно, кем именно — прямой командой kubectl delete pvc или как следствие uninstall релиза, если resource-policy: keep не был указан или был обойдён). При Retain данные на диске физически сохраняются (PV переходит в состояние Released, но не удаляется и не может быть автоматически переиспользован новым PVC без ручного вмешательства администратора) — в отличие от дефолтного для многих StorageClass reclaimPolicy: Delete, при котором удаление PVC немедленно приводит к удалению и физических данных.
Почему нужны оба уровня одновременно
| Сценарий | Защищает resource-policy: keep? | Защищает reclaimPolicy: Retain? |
|---|---|---|
nelm release uninstall (случайный/намеренный) | Да — PVC не удаляется вообще | Не требуется, PVC не тронут |
| PVC убран из шаблонов чарта, релиз обновлён | Да — PVC остаётся, несмотря на удаление из чарта | Не требуется |
Прямая команда kubectl delete pvc администратором/пользователем с доступом | Нет — аннотация Helm не действует вне логики Helm/Nelm | Да — физические данные на диске сохраняются, PV помечается Released |
Случайное удаление всего namespace (kubectl delete namespace) | Нет — вместе с namespace удаляются все объекты внутри, включая PVC | Да — единственная линия защиты в этом сценарии |
Именно из этой таблицы видно: resource-policy: keep покрывает сценарии, связанные с логикой Helm/Nelm-релиза, но полностью беспомощен против прямых команд Kubernetes API (включая случайное удаление целого namespace) — только reclaimPolicy: Retain на уровне StorageClass защищает от этого класса рисков, сохраняя физические данные независимо от того, как именно был удалён PVC.
Частые ошибки и подводные камни
- Полагаться только на
helm.sh/resource-policy: keep, считая данные полностью защищёнными. Эта аннотация не защищает от прямого удаления PVC вне контекста Nelm/Helm — для полноценной защиты нужны оба уровня. - Использовать
StorageClassсreclaimPolicy: Delete(дефолт для многих облачных провайдеров) для критичных данных без явного создания собственногоStorageClassсRetain. Дефолтное поведение большинства динамических provisioner’ов — немедленное удаление данных вместе с PVC, если явно не переопределено. - Забывать, что
Retainтребует ручного вмешательства администратора для повторного использования данных. PV в состоянииReleasedне может быть автоматически привязан к новому PVC — нужна ручная очисткаclaimRefили пересоздание PV, указывающего на тот же физический том — это осознанный компромисс:Retainпредотвращает потерю данных, но не предоставляет автоматического восстановления.
Практика в кластере
- Создайте (если ещё не создан в предыдущих модулях)
StorageClassсreclaimPolicy: Retainдля критичных данных PostgreSQL, используемого Umami через managed-postgres, или для собственного PVC приложения, если применимо:
| |
- Если у вашего пакета Umami есть собственный PVC (например, для локального кэша), добавьте
helm.sh/resource-policy: keep:
| |
- Смоделируйте
uninstallрелиза и убедитесь, что PVC сохранился:
| |
- Смоделируйте прямое удаление PVC и убедитесь, что
resource-policy: keepв этом случае не помогает (ожидаемое, документированное поведение):
| |
Практика разработки
Практики разработки в этом уроке нет — весь материал относится к аннотациям и настройкам, применённым в практике выше.
Шпаргалка команд урока
| |
| |
Вопросы для самопроверки
Это явно задокументированное ограничение — resource-policy: keep не заменяет защиту на уровне reclaimPolicy.
Источник: Deckhouse — Nelm-аннотации
Retain — защита на уровне Kubernetes, не связанная с логикой Helm/Nelm, действующая при ЛЮБОМ удалении PVC.
Источник: Deckhouse — Nelm-аннотации
Таблица сценариев показывает, что ни один механизм в одиночку не покрывает все возможные пути потери данных.
Источник: Рекомендуемая литература
Retain предотвращает потерю данных, но не предоставляет автоматического восстановления — это осознанный компромисс.
Это худший сценарий из таблицы курса — только физическая защита данных через StorageClass спасает в этом случае.
Источник: Рекомендуемая литература
Рекомендуемая литература
Официальная документация
Статьи и блоги
- Разворачиваем приложение в кластере Kubernetes под управлением Deckhouse c помощью werf — Flant на Habr.
- Вышла werf 2.0: новый движок развёртывания Nelm — Flant на Habr.
- Готовим Gitea со вкусом werf CI/CD в кластере Deckhouse. Часть 3 — Flant на Habr.
Книги
- Michael Hausenblas, Stefan Schimanski. Programming Kubernetes. 2019. ISBN 978-1492047107.
Связанные материалы
- Предыдущий урок: M6.06 — Паттерн «ожидание внешнего оператора».
- Следующий урок: M6.08 — Итоговая связка.
- База PVC/StorageClass: M1 урок 6.
✓ Урок пройден — все вопросы самопроверки отвечены верно