При необходимости перестраивайте контейнеры

Контейнер приложения обычно состоит из трех частей:

  • Базовый образ, который, в случае Linux, содержит основные инструменты POSIX и системные библиотеки (например, FROM debian:stable)
  • Библиотеки времени выполнения или вспомогательные инструменты обычно устанавливаются из какого-либо пакета (например, RUN apt-get update && apt-get python3-numpy && …—Для базового Python или Java и т. Д. Обычно есть готовый базовый контейнер для использования, но приложение все еще может иметь дополнительные зависимости).
    • Та же проблема относится к зависимостям, связанным с приложением (например, внешние зависимости, загруженные maven или nuget и т. Д.). Было бы неплохо, если бы существовало общее решение, которое также справилось бы с этим, но в противном случае потребуется другое решение для конкретного инструмента.
  • Само приложение (например, COPY …/application/ /usr/local/python3.8/dist-packages/application/ и установите точку входа).

Контейнер, который перейдет в производственную среду, обычно создается на сервере сборки. Теперь перестройка, когда в приложение вносятся изменения, очевидно, и для чего предназначены CI-серверы.

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

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

Обратите внимание, что просто бег docker build --pull --no-cachenightly не является решением, потому что при этом будет создан новый контейнер, даже если зависимости фактически не изменились из-за разных временных меток установленных файлов. И бегает простоdocker build --pull не работает, потому что либо есть кеш, но затем проверяет только, Dockerfile был изменен и фактически не проверяет список пакетов, или кеша нет, потому что он работает на другом агенте сборки или агент сборки был очищен, как обычно, для получения надежных сборок.

Он может использовать любой конструктор контейнеров, не обязательно докер.

2 ответа

Решение

Ответ, как и для многих других проблем, связанных с докерами, - отказаться от докера и переключиться на buildah. Обаbuildah bud, который заменяет docker build, а buildah commit, который предназначен для написания сценария сборки другими способами, имеют --timestampпараметр, который принудительно устанавливает как временную метку, записанную в манифест, так и временные метки файлов в новых слоях на указанное значение. Кажется, это единственный недетерминизм самого инструмента; стандартные методы детерминированной сборки все еще необходимо применять к сборке самого приложения, но это явно выходит за рамки возможностей buildah.

Бег docker build --pull --no-cacheпримерно раз в неделю - разумный компромисс. Очень вероятно, что в этот период времени в пакетах уровня ОС будет какое- то исправление, поэтому вы собираетесь перезапустить контейнер с новым образом, чтобы получить обновления безопасности, что разумно. В зависимости от того, как часто вы выполняете развертывание в производственной среде, "при каждом производственном развертывании" может быть или не быть подходящим временем для этого.

Если для вас важна согласованность между средами, рассмотрите возможность использования версии с отметкой даты debian изображение (FROM debian:stable-20200422) или создание собственного базового образа, который можно сохранить в реестре. Затем вы можете использовать DockerfileARG указать дату, и если вы это сделаете, вам никогда не понадобится --no-cache. (Но вам придется вручную обнаружить текущую версию.)

# Build with
#   docker build --build-arg DATE_STAMP=-20200422
# This must have a leading hyphen
ARG DATE_STAMP

FROM debian:stable${DATE_STAMP:-}

Для языковых пакетов также учтите, что большинство менеджеров пакетов имеют файл блокировки, в котором указывается точная версия используемых пакетов (NPMpackage-lock.json, yarn.lock, Ruby Bundler Gemfile.lock, Python requirements.txt или Pipfile.lock). В этих случаях вам нужно запустить некую операцию "обновления", чтобы обновить файл блокировки; при этом создается фиксация, которая запускает систему CI, и изменение файла, которое делает недействительным кеш сборки Docker.

Другие вопросы по тегам