Финализаторы

Финализаторы

Финализаторы — это ключи с пространством имён, которые предписывают Kubernetes дождаться выполнения определённых условий, прежде чем окончательно удалить ресурсы, помеченные на удаление. Финализаторы сообщают контроллерам о том, что нужно очистить ресурсы, которыми владел удаляемый объект.

Когда вы поручаете Kubernetes удалить объект, для которого заданы финализаторы, API Kubernetes помечает объект на удаление, заполняя поле .metadata.deletionTimestamp, и возвращает код состояния 202 (HTTP «Accepted»). Целевой объект остаётся в состоянии завершения, пока управляющий слой или другие компоненты выполняют действия, заданные финализаторами. После завершения этих действий контроллер убирает соответствующие финализаторы из целевого объекта. Когда поле metadata.finalizers оказывается пустым, Kubernetes считает удаление завершённым и удаляет объект.

С помощью финализаторов можно управлять сбором мусора ресурсов. Например, можно определить финализатор, который очистит связанные ресурсы API или инфраструктуру, прежде чем контроллер удалит финализируемый объект.

С помощью финализаторов можно управлять сбором мусора объектов: они сообщают контроллерам о том, что перед удалением целевого ресурса нужно выполнить определённые задачи по очистке.

Обычно финализаторы не содержат кода, который нужно выполнить. Как правило, это просто списки ключей у конкретного ресурса, похожие на аннотации. Часть финализаторов Kubernetes задаёт автоматически, но вы можете задавать и свои.

Как работают финализаторы

Создавая ресурс из файла манифеста, вы можете указать финализаторы в поле metadata.finalizers. Когда вы попытаетесь удалить этот ресурс, API-сервер, обрабатывающий запрос на удаление, заметит значения в поле finalizers и сделает следующее:

  • Изменит объект, добавив в него поле metadata.deletionTimestamp со временем, когда вы начали удаление.
  • Не даст удалить объект, пока из его поля metadata.finalizers не будут убраны все элементы.
  • Вернёт код состояния 202 (HTTP «Accepted»).

Контроллер, отвечающий за этот финализатор, заметит, что у объекта появилось поле metadata.deletionTimestamp, то есть что удаление объекта запрошено. После этого контроллер попытается выполнить требования финализаторов, заданных для этого ресурса. Каждый раз, когда условие очередного финализатора выполнено, контроллер убирает соответствующий ключ из поля finalizers ресурса. Когда поле finalizers опустеет, объект с заданным полем deletionTimestamp будет удалён автоматически. Кроме того, с помощью финализаторов можно защитить от удаления ресурсы, которыми никто не управляет.

Типичный пример финализатора — kubernetes.io/pv-protection, который защищает объекты PersistentVolume от случайного удаления. Когда объект PersistentVolume используется Подом, Kubernetes добавляет к нему финализатор pv-protection. Если вы попытаетесь удалить такой PersistentVolume, он перейдёт в состояние Terminating, но контроллер не сможет его удалить, потому что финализатор на месте. Когда Под перестанет использовать этот PersistentVolume, Kubernetes уберёт финализатор pv-protection, и контроллер удалит том.

Примечание:

  • Когда вы удаляете объект запросом DELETE, Kubernetes проставляет для него время удаления и сразу же начинает ограничивать изменения поля .metadata.finalizers у объекта, который теперь ожидает удаления. Существующие финализаторы можно убирать (удаляя запись из списка finalizers), но добавить новый уже нельзя. Изменить deletionTimestamp после того, как он проставлен, тоже нельзя.

  • После того как удаление запрошено, вернуть объект к жизни не получится. Единственный выход — удалить его и создать новый такой же.

Примечание:

Имена пользовательских финализаторов обязаны быть публично квалифицированными, например example.com/finalizer-name. Kubernetes следит за соблюдением этого формата: API-сервер отклоняет запись в объекты, если изменение использует неквалифицированное имя для любого пользовательского финализатора.

Ссылки на владельца, метки и финализаторы

Как и метки, ссылки на владельца описывают связи между объектами в Kubernetes, но служат другой цели. Когда контроллер управляет объектами вроде Подов, он использует метки, чтобы отслеживать изменения в группах связанных объектов. Например, когда Job создаёт один или несколько Подов, контроллер Job проставляет этим Подам метки и отслеживает изменения всех Подов кластера с такой же меткой.

Кроме того, контроллер Job добавляет к этим Подам ссылки на владельца, указывающие на создавший их Job. Если удалить Job, пока эти Поды работают, Kubernetes определит, какие Поды в кластере нужно очистить, именно по ссылкам на владельца, а не по меткам.

Финализаторы Kubernetes обрабатывает и тогда, когда обнаруживает ссылки на владельца у ресурса, назначенного к удалению.

В некоторых ситуациях финализаторы могут заблокировать удаление зависимых объектов, из-за чего целевой объект-владелец останется неудалённым дольше, чем ожидалось. В таких случаях стоит проверить финализаторы и ссылки на владельца у целевого объекта-владельца и у зависимых объектов, чтобы найти причину.

Примечание:

Если объекты застряли в состоянии удаления, не убирайте финализаторы вручную, чтобы протолкнуть удаление. Обычно финализаторы добавляют к ресурсам не просто так, и их принудительное удаление может привести к проблемам в кластере. Делать это стоит только тогда, когда вы понимаете назначение финализатора и добиваетесь того же результата другим способом (например, вручную очищаете зависимый объект).

Что дальше