После удаления объекта Deployment его ReplicaSet и поды исчезают не сразу, но в итоге удаляются автоматически. Какой механизм Kubernetes обеспечивает эту цепочку удаления?
Цепочку удаления обеспечивает сборщик мусора Kubernetes — Garbage Collector. Он анализирует связи ownerReferences: ReplicaSet принадлежит Deployment, а под принадлежит ReplicaSet, поэтому при удалении владельца зависимые объекты также удаляются согласно выбранной политике распространения удаления.
Удаление выполняется асинхронно. Поэтому между удалением Deployment и исчезновением ReplicaSet или подов может существовать временный промежуток.
Kubernetes управляет объектами декларативно: пользователь описывает желаемое состояние, а контроллеры приводят кластер к нему. В такой модели жизненный цикл связанных ресурсов должен управляться автоматически, иначе после удаления верхнеуровневого объекта оставались бы осиротевшие ReplicaSet, поды, задачи или другие зависимые ресурсы.
Механизм владения и сборки мусора отделяет управление зависимостями от логики каждого конкретного контроллера. Контроллер создаёт ресурсы с указанием владельца, а общий механизм Kubernetes затем отслеживает их жизненный цикл.
Deployment обычно создаёт или изменяет ReplicaSet, а ReplicaSet создаёт поды. Если удалить только Deployment, но не удалить связанные объекты, ReplicaSet может продолжить поддерживать нужное ему число подов. Приложение тогда продолжит работать, хотя исходный объект управления уже отсутствует.
Неверное понимание механизма опасно при автоматизации: можно преждевременно считать ресурсы удалёнными, случайно оставить рабочие поды или, наоборот, удалить общий ресурс вместе с объектом, который ошибочно указан его владельцем.
Связь задаётся полем ownerReferences. В ней указывается идентификатор владельца, его тип и признак controller, показывающий, что данный владелец является контроллером зависимого объекта. Для стандартной цепочки это выглядит так: Deployment владеет ReplicaSet, а ReplicaSet — подами.
Когда объект удаляется, Kubernetes Garbage Collector находит зависимые объекты. При стандартном фоновом удалении сначала удаляется владелец, а зависимые ресурсы удаляются сборщиком мусора асинхронно. Контроллер ReplicaSet может некоторое время ещё существовать и наблюдаться, но после удаления его самого поды также становятся кандидатами на удаление.
Политика распространения удаления определяет порядок и судьбу зависимостей:
Конкретное удаление может зависеть от прав доступа, финализаторов и корректности ссылок на владельца. Финализатор способен задержать фактическое исчезновение объекта, пока контроллер или оператор не выполнит обязательную очистку. Кроме того, контроллер может создать новый ресурс снова, если его верхнеуровневый объект всё ещё существует и описывает такое желаемое состояние.
Важно отличать сборщик мусора от контроллеров. Сборщик удаляет зависимые объекты по отношениям владения, а контроллеры поддерживают состояние своих ресурсов. Например, удаление одного пода обычно приводит к созданию нового ReplicaSet, потому что ReplicaSet всё ещё существует и требует заданное число реплик; это не «воскрешение» удалённого пода сборщиком мусора.
Оператор удалил Deployment во время аварийного переключения и сразу проверил отсутствие приложения по списку подов. Часть подов ещё отображалась, потому что удаление ReplicaSet и подов выполнялось асинхронно. Дополнительная проблема возникла из-за финализатора на одном из ресурсов, который задерживал завершение удаления.
Рассматривались три варианта. Ожидание завершения удаления было безопасным, но требовало корректного контроля состояния; принудительное удаление финализатора ускоряло операцию, но могло оставить внешние ресурсы; сохранение зависимостей через orphan-политику позволяло быстро передать нагрузку другому объекту, но требовало последующей ручной уборки.
Выбрали обычное фоновое удаление с ожиданием фактического исчезновения зависимостей и отдельной проверкой финализатора. Это сохранило штатную семантику Kubernetes и не создало осиротевшие поды. Для критичных операций добавили проверку цепочки владельцев, а не только проверку удаления верхнеуровневого объекта.
Deployment продолжит существовать и будет наблюдать, что управляемого ReplicaSet нет либо число реплик не соответствует желаемому состоянию. Его контроллер создаст новый ReplicaSet или восстановит необходимое состояние. Поэтому удаление промежуточного объекта не является способом остановить приложение, пока сохраняется владелец верхнего уровня.
При orphan зависимые объекты не удаляются вместе с владельцем: ссылки на владельца становятся неактуальными, а сами ресурсы сохраняются. Это полезно, когда нужно передать существующие поды или другие ресурсы под управление другому объекту, но требует осторожности: без нового владельца они могут остаться без автоматического управления и очистки.
Нет. Для автоматической сборки мусора нужна корректная связь ownerReferences, а не произвольное поле, label или annotation. Метки помогают выбирать объекты селекторам, но сами по себе не устанавливают отношение владения и не определяют, какой ресурс должен быть удалён вместе с другим.