Паттерн «общий ресурс между релизами»
Что нужно знать перед уроком
- M6.04 — Паттерн «Job-миграция перед Deployment» — нужен опыт с аннотациями Nelm перед изучением следующего паттерна
Что нужно знать перед уроком
M6 урок 4 — первый паттерн управления порядком через аннотации Nelm. Здесь — паттерн для другой задачи: что делать, когда один и тот же ресурс должен быть общим между несколькими независимыми релизами (Helm-релизами/Application-инстансами), и как защитить его от случайного удаления.
Теория
Дефолтное поведение Nelm: ownership: release
По умолчанию Nelm считает, что каждый ресурс в кластере принадлежит ровно одному релизу — тому, который его создал. Если этот релиз будет удалён (nelm release uninstall, M4 урок 5) — все его ресурсы, включая данный, будут удалены вместе с ним. Это разумное поведение по умолчанию для подавляющего большинства ресурсов (никто не хочет «осиротевших» ConfigMap/Service после удаления релиза), но создаёт проблему, если конкретный ресурс намеренно должен переживать удаление отдельного релиза, т.к. используется несколькими.
werf.io/ownership: anyone — явное объявление совместного владения
| |
Пример из официальной документации — общий TLS-сертификат (Secret), используемый несколькими чартами/релизами (например, wildcard-сертификат для целого поддомена, которым пользуются сразу несколько Application-инстансов одной команды). Аннотация werf.io/ownership: anyone сообщает Nelm: «этот ресурс не принадлежит единолично данному релизу — не удаляй его при uninstall этого конкретного релиза, т.к. другие релизы тоже могут на него ссылаться».
Почему без этой аннотации Nelm удалит секрет
Без ownership: anyone при выполнении nelm release uninstall для любого из релизов, которые рендерят этот Secret в своих шаблонах, Nelm посчитает себя единоличным владельцем ресурса (дефолт ownership: release) и удалит его — даже если другие релизы всё ещё от него зависят. Результат — неожиданный обрыв работы других, казалось бы, не затронутых операцией удаления релизов, чьи ресурсы внезапно ссылаются на несуществующий Secret.
Другой контекст ownership: anyone — дефолт для hooks и CRD
Важная деталь для полноты картины (хотя CRD неприменимо для Application из-за ограничений M5 урока 5): ownership: anyone — это дефолтное поведение для служебных категорий ресурсов вроде hooks и CRD в crds/-директории Module-чартов, но не дефолт для обычных ресурсов (Deployment/Service/Secret/ConfigMap) — для них дефолт всегда release, и ownership: anyone нужно указывать явно, только когда есть осознанная необходимость совместного владения. Полный разбор всех lifecycle-аннотаций — M7 урок 3.
Частые ошибки и подводные камни
- Ставить
ownership: anyone«на всякий случай» на все ресурсы. Это лишает Nelm возможности корректно очищать ресурсы при реальном удалении релиза — приводит к накоплению «осиротевших» объектов в кластере, которые никто не удаляет автоматически ни при каких обстоятельствах. - Забывать про
ownership: anyoneдля действительно общих ресурсов и получать неожиданное удаление при, казалось бы, несвязанной операцииuninstallдругого релиза. Это довольно коварная ошибка — проблема проявляется не в том релизе, который вы удаляли, а в совершенно другом, использующем тот же ресурс. - Не документировать, какие ресурсы являются общими между релизами. Если в команде несколько разработчиков управляют разными Application-инстансами, использующими общий ресурс, отсутствие явной документации о совместном использовании создаёт риск случайного удаления кем-то, кто не знает о зависимости других релизов.
Практика в кластере
Смоделируйте сценарий двух инстансов Umami (как в M5 уроке 7), совместно использующих один TLS-секрет:
- Добавьте общий
Secretс аннотациейownership: anyoneв шаблоны, устанавливаемые обоими инстансами:
| |
- Установите оба инстанса, оба рендерят один и тот же
Secret:
| |
- Удалите один из релизов и убедитесь, что общий
Secretне был удалён:
| |
- Для сравнения, повторите эксперимент без аннотации
ownership: anyone(в отдельном тестовом namespace) и убедитесь, чтоSecretдействительно удаляется при первом жеuninstall.
Практика разработки
Практики разработки в этом уроке нет — весь материал относится к аннотациям шаблонов, применённым в практике выше.
Шпаргалка команд урока
| |
Вопросы для самопроверки
Дефолтное поведение — единоличное владение релизом, создавшим ресурс.
Источник: Deckhouse — Nelm-аннотации
anyone сообщает Nelm, что ресурс не принадлежит единолично текущему релизу.
Источник: Deckhouse — Nelm-аннотации
Для Deployment/Service/Secret/ConfigMap и подобных ресурсов дефолт — release, anyone нужно указывать явно.
Источник: Deckhouse — Nelm-аннотации
Дефолт release означает единоличное владение — удаление A затронет ресурсы, на которые ссылается B, если не указан anyone.
Источник: Deckhouse — Nelm-аннотации
ownership: anyone нужно использовать точечно, только для действительно намеренно общих ресурсов.
Источник: Рекомендуемая литература
Рекомендуемая литература
Официальная документация
Статьи и блоги
- Разворачиваем приложение в кластере 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.04 — Паттерн «Job-миграция перед Deployment».
- Следующий урок: M6.06 — Паттерн «ожидание внешнего оператора».
- Множественные инстансы: M5 урок 7.
✓ Урок пройден — все вопросы самопроверки отвечены верно