АрхитектураОблако и инфраструктураИнженер по DevOps и контейнерной инфраструктуре

При изменении большого файла, пришедшего из образа, как механизм copy on write влияет на место на диске и с...

При изменении большого файла, пришедшего из образа, как механизм copy-on-write влияет на место на диске и сохранность образа?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

Copy-on-write оставляет слои образа неизменяемыми, а запись изменённого файла выполняет в отдельном записываемом слое контейнера. Если файл уже существует в образе, перед изменением он обычно копируется в верхний слой целиком, поэтому свободное место может уменьшиться примерно на размер файла или изменяемой копии. Сам образ при этом не меняется, а изменения записываемого слоя обычно исчезают вместе с контейнером.

Исторический контекст

Контейнерные образы строятся из переиспользуемых слоёв. Это позволяет нескольким образам совместно использовать одинаковые базовые данные, экономить место и передавать при публикации только новые слои.

Чтобы запущенный контейнер мог выглядеть изменяемым, поверх неизменяемых слоёв образа создаётся отдельный записываемый слой. Такой подход сочетает эффективность хранения образов с изоляцией изменений конкретного контейнера.

Постановка проблемы

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

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

Подробное решение

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

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

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

Записываемый слой принадлежит конкретному экземпляру контейнера и не входит обратно в образ автоматически. Перезапуск того же контейнера может сохранить этот слой, но удаление и пересоздание контейнера обычно его теряет. Для долговечных данных используют подключённый том или внешнее хранилище; для журналов часто применяют сбор через стандартный поток вывода и отдельную систему логирования.

Copy-on-write экономит место, пока данные не изменяются, но имеет ограничения: копирование больших файлов увеличивает задержку первой записи, создаёт дополнительный ввод-вывод и может ухудшить работу приложений с интенсивными изменениями. Поэтому изменяемые рабочие данные обычно выносят на том, а образ оставляют неизменяемым.

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

Ситуация из практики

Сервис обрабатывал загруженные документы, а образ содержал шаблонный файл размером 2 ГБ. При обновлении метаданных приложение изменяло этот файл, и на узлах неожиданно быстро заполнялся локальный диск.

Рассматривались три варианта. Увеличение диска устраняло симптом, но не меняло модель хранения и повышало стоимость. Запись в новый файл уменьшала число copy-up только для конкретного сценария, но не решала вопрос долговечности данных. Подключение тома сохраняло данные, однако требовало выбрать подходящий класс хранилища и учесть его задержки.

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

Что кандидаты часто упускают

  1. Вопрос: Сохранятся ли изменения, если контейнер просто перезапустить?

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

  2. Вопрос: Обходится ли copy-on-write, если приложение изменяет файл из образа через подключённый том?

    Ответ: Если путь находится на подключённом томе, операции выполняются в файловой системе тома, а не в записываемом слое образа. Поэтому copy-up слоя образа для этого файла не требуется. Это не делает любую запись дешёвой: сетевой или распределённый том может иметь собственные ограничения по задержке, пропускной способности и согласованности.

  3. Вопрос: Почему удаление файла из контейнера не обязательно освобождает место на узле?

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