PVC и данные приложения

Уровень: advanced ~45 мин Практика: Umami (продолжение M5) (MIT)

Что нужно знать перед уроком

  • M6.06 — Паттерн «ожидание внешнего оператора» — нужен опыт с lifecycle-аннотациями перед последним паттерном модуля
  • M1.06 — Volumes/PVC/StorageClass — нужна база PVC/StorageClass/reclaimPolicy из Kubernetes

Что нужно знать перед уроком

M1 урок 6PersistentVolumeClaim, StorageClass, reclaimPolicy. M6 урок 5werf.io/ownership: anyone для защиты от удаления при uninstall другого релиза. Здесь — специфичная и критичная тема: как защитить данные приложения (не сам ресурс, а именно PVC с реальными данными) от потери в разных сценариях удаления.

Теория

Два независимых уровня защиты — и оба нужны одновременно

flowchart TB A["PVC с данными приложения"] --> B["Уровень 1: helm.sh/resource-policy: keep\nЗащита от Nelm/Helm (uninstall релиза, удаление из чарта)"] A --> C["Уровень 2: persistentVolumeReclaimPolicy: Retain на StorageClass\nЗащита от прямого kubectl/d8 k delete pvc"]

Это два разных механизма, действующих на разных уровнях стека, и ни один не заменяет другой.

Уровень 1: helm.sh/resource-policy: keep

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: {{ .Application.Instance.Name }}-postgres-data
  annotations:
    helm.sh/resource-policy: keep
spec:
  accessModes: [ReadWriteOnce]
  resources:
    requests:
      storage: 50Gi
  storageClassName: gp3

Эта аннотация действует только в контексте операций 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

1
2
3
4
5
6
7
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: gp3-retain
provisioner: ebs.csi.aws.com
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer

Это настройка уровня 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 предотвращает потерю данных, но не предоставляет автоматического восстановления.

Практика в кластере

🧩 Практика урока: Umami (продолжение M5) · лицензия MIT
  1. Создайте (если ещё не создан в предыдущих модулях) StorageClass с reclaimPolicy: Retain для критичных данных PostgreSQL, используемого Umami через managed-postgres, или для собственного PVC приложения, если применимо:
1
d8 k get storageclass -o custom-columns=NAME:.metadata.name,RECLAIM:.reclaimPolicy
  1. Если у вашего пакета Umami есть собственный PVC (например, для локального кэша), добавьте helm.sh/resource-policy: keep:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: {{ .Application.Instance.Name }}-cache
  annotations:
    helm.sh/resource-policy: keep
spec:
  accessModes: [ReadWriteOnce]
  resources:
    requests:
      storage: 1Gi
  1. Смоделируйте uninstall релиза и убедитесь, что PVC сохранился:
1
2
3
4
nelm release install -n course-m6-umami -r umami-pvc-demo . --auto-rollback
d8 k get pvc -n course-m6-umami
nelm release uninstall -n course-m6-umami -r umami-pvc-demo
d8 k get pvc -n course-m6-umami   # PVC должен остаться
  1. Смоделируйте прямое удаление PVC и убедитесь, что resource-policy: keep в этом случае не помогает (ожидаемое, документированное поведение):
1
2
3
d8 k delete pvc umami-pvc-demo-cache -n course-m6-umami
d8 k get pvc -n course-m6-umami   # PVC действительно удалён — resource-policy: keep не защищает от прямой команды
d8 k get pv | grep Released        # если StorageClass был с Retain — соответствующий PV должен быть в Released

Практика разработки

Практики разработки в этом уроке нет — весь материал относится к аннотациям и настройкам, применённым в практике выше.

Шпаргалка команд урока

1
helm.sh/resource-policy: keep # на PVC — защита от Nelm/Helm uninstall
1
reclaimPolicy: Retain # на StorageClass — защита от прямого delete pvc

Вопросы для самопроверки

Защищает ли helm.sh/resource-policy: keep от прямой команды kubectl delete pvc?

Это явно задокументированное ограничение — resource-policy: keep не заменяет защиту на уровне reclaimPolicy.

Источник: Deckhouse — Nelm-аннотации

Что делает persistentVolumeReclaimPolicy: Retain на StorageClass?

Retain — защита на уровне Kubernetes, не связанная с логикой Helm/Nelm, действующая при ЛЮБОМ удалении PVC.

Источник: Deckhouse — Nelm-аннотации

Почему нужны ОБА механизма защиты одновременно, а не один из них?

Таблица сценариев показывает, что ни один механизм в одиночку не покрывает все возможные пути потери данных.

Источник: Рекомендуемая литература

Что происходит с PV в состоянии Released при reclaimPolicy: Retain?

Retain предотвращает потерю данных, но не предоставляет автоматического восстановления — это осознанный компромисс.

Источник: Kubernetes — PersistentVolume reclaim policy

Защищает ли helm.sh/resource-policy: keep от случайного удаления всего namespace?

Это худший сценарий из таблицы курса — только физическая защита данных через StorageClass спасает в этом случае.

Источник: Рекомендуемая литература

Рекомендуемая литература

Официальная документация

Статьи и блоги

Книги

  • Michael Hausenblas, Stefan Schimanski. Programming Kubernetes. 2019. ISBN 978-1492047107.

Связанные материалы