Изображения в докере упоминаются по ссылке, наиболее распространенной из которых является репозиторий изображений и тег. И этот тег представляет собой относительную свободную строку, указывающую на определенное изображение. Теги лучше всего рассматривать как изменяемый указатель, его можно изменить, у вас может быть несколько указателей, указывающих на одно и то же изображение, и его можно удалить, в то время как базовое изображение может остаться нетронутым.
Поскольку докер не применяет большую структуру тегов (кроме проверки того, что они содержат допустимые символы и не превышают ограничения по длине), обеспечение соблюдения этого требования остается на усмотрение каждого сопровождающего репозитория, и в результате появилось множество различных решений.
Для сопровождающих репозиториев вот несколько распространенных реализаций:
Вариант А. В идеале специалисты по обслуживанию репозитория следуют некоторой форме semver. Этот номер версии должен соответствовать версии упакованного программного обеспечения, часто с дополнительным номером исправления для версии образа. Важно отметить, что изображения, помеченные таким образом, должны включать теги не только для версии 1.2.3-1, но и для версий 1.2.3, 1.2 и 1, каждая из которых обновлена до последней версии в соответствующей иерархии. Это позволяет нижестоящим пользователям полагаться на 1.2 и автоматически получать обновления для 1.2.4, 1.2.5 и т. д. по мере выхода исправлений ошибок и обновлений безопасности.
Вариант Б. Подобно варианту semver выше, многие проекты включают в свои теги другие важные метаданные, например. какая архитектура или базовый образ использовались для этой сборки. Это обычно наблюдается при сравнении образов alpine и debian/slim или скомпилированного кода arm и amd. Они часто будут сочетаться с semver, поэтому вы можете увидеть такие теги, как alpine-1.5
, в дополнение к тегам alpine-1
и alpine
.
Вариант C. Некоторые проекты следуют скользящим выпускам, которые не обещают обратной совместимости. Это часто делается с помощью номеров сборок или строки даты, и действительно, сам Docker использует это, хотя и с процессом, чтобы исключить функции и избежать критических изменений. Я видел довольно много внутренних проектов с компаниями, использующими эту стратегию для версии своих образов, полагаясь на номер сборки с сервера CI.
Вариант D: я не сторонник размещения хэшей версий Git в качестве тегов изображений, поскольку они не передают никакой информации без ссылки на репозиторий Git. Не у каждого пользователя может быть такой доступ или навык для понимания этого справочника. И, глядя на два разных хэша, я без внешней проверки не могу понять, какой из них новее или совместим с моим приложением. Они также предполагают, что единственным важным номером версии является Git, и игнорируют тот факт, что одна и та же версия Git может использоваться для создания нескольких образов из разных родительских образов, разных архитектур или просто нескольких файлов Dockerfile/multistage target в одном и том же репозитории Git. Вместо этого мне нравится использовать схему ярлыков и, в конечном итоге, аннотации спецификаций изображений, как только мы получим инструменты для аннотаций изображений, чтобы отслеживать такие детали, как версии Git. Это помещает версию Git в метаданные, которые вы можете запросить для проверки изображения, при этом сам тег остается информативным для пользователя.
Для пользователей изображений, если у вас есть требование избежать неожиданных изменений из восходящего потока, есть два варианта, о которых я знаю.
Первый — запустить собственный сервер реестра и перенести внешние зависимости на локальный сервер. Docker включает в себя образ автономного реестра, который вы можете установить, а открытый API позволяет многие поставщики репозиториев артефактов поддерживают реестр докеров. Позаботьтесь о регулярном обновлении этого реестра и предусмотрите возможность возврата к предыдущим версиям, если обновление нарушит вашу среду.
Второй вариант — перестать зависеть от изменяемых тегов. Вместо этого вы можете использовать закрепление изображения, которое ссылается на уникальную ссылку реестра sha256 на манифест, который нельзя изменить. Вы можете найти это значение в RepoDigests при проверке образа, полученного с сервера реестра:
$ docker inspect -f '{{json .RepoDigests}}' debian:latest
["debian@sha256:de3eac83cd481c04c5d6c7344cd7327625a1d8b2540e82a8231b5675cef0ae5f"]
$ docker run -it --rm debian@sha256:de3eac83cd481c04c5d6c7344cd7327625a1d8b2540e82a8231b5675cef0ae5f /bin/bash
root@ac9db398dc03:/#
Самый большой риск такой привязки к конкретному образу — отсутствие обновлений безопасности и важных исправлений ошибок. Если вы выберете этот вариант, убедитесь, что у вас есть процедура регулярного обновления этих изображений.
Независимо от того, какое решение вы используете для извлечения изображений, использование последних версий полезно только для быстрого тестирования разработчика, а не для каких-либо производственных сценариев использования. Поведение последних полностью зависит от сопровождающего репозитория, некоторые всегда обновляют его до последнего релиза, некоторые делают его последним стабильным релизом, а некоторые вообще забывают его обновлять. Если вы зависите от последней версии, вы, вероятно, столкнетесь с перебоями при изменении исходных изображений с версии 1.5 на 2.0 с несовместимыми с предыдущими версиями изменениями. Ваше следующее развертывание непреднамеренно будет включать эти изменения, если только вы явно не зависите от тега, который предлагает исправления ошибок и исправления безопасности без серьезных изменений.
20.05.2019