Правильное управление версиями образов Docker

В продолжение вопроса 4-летней давности Версии образов Docker и управление жизненным циклом, потому что, ИМХО, это не касалось управления версиями образов Docker должным образом:

I don't find this answer to be adequate, as there can be successive versions of the same tag. We need a way to be able to lock down dependencies onto a particular version of a tag.

а также,

the answer is to not use latest.

«Решение», которое я нашел в Интернете, тоже сбивает с толку. Например.,

  • Здесь это намекнул не использовать latest, а "решение" намекнул пометить дважды. Я подчеркиваю «намекнул», потому что нет твердой рекомендации (для меня).
  • А здесь это даже показывает, что нам нужно сделать docker pushдважды на том же изображении.

Итак, как правильно управлять версиями образов Docker (как локально, так и при отправке/публикации в Docker Hub)?

ИСПРАВЛЯТЬ:

Пока есть два ответа. Спасибо за это.

  • Оба используют короткий идентификатор версии git.
  • И оба пропускают часть ответа/публикации.

Поскольку мне делать нужно отправить/опубликовать мой образ докера в репозиторий Docker, а из здесь это намекнул, что неиспользование latest создаст проблемы при извлечении последней версии, если вы используете определенные теги идентификатора. Более того, использование короткого идентификатора версии git может быть хорошим решением для внутреннего использования, но при публикации образа докера для публичного использования это может быть не лучшим решением.

Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Kubernetes - это портативная, расширяемая платформа с открытым исходным кодом для управления контейнерными рабочими нагрузками и сервисами, которая...
Как создать PHP Image с нуля
Как создать PHP Image с нуля
Сегодня мы создадим PHP Image from Scratch для того, чтобы легко развернуть базовые PHP-приложения. Пожалуйста, имейте в виду, что это разработка для...
27
0
33 990
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Для приложения на основе докера я помечаю их коротким хешем коммита git. Таким образом, вы можете сразу определить код, который находится в контейнере. Я не уверен, как бы я поступил с образом докера, созданным для использования в качестве базового образа.

Для меня все дело в том, чтобы сказать, какая версия (моего) программного обеспечения вошла в образ Docker. Я рекомендую использовать что-то вроде короткий идентификатор версии git. Я не использую latest, так как это не имеет полезного контекста.

Создайте образ Docker с версией Git в качестве тега. stable-package-name ниже — это просто название вашего приложения, например «HelloWorld» или что угодно:

REV_TAG=$(git log -1 --pretty=format:%h)
docker build -t <stable-package-name>:$REV_TAG .

Позже я отправляю то, что пометил, в удаленный репозиторий:

# nominate the tagged image for deployment
docker tag <stable-package-name>:$REV_TAG <repository-name>:$REV_TAG

# push docker image to remote repository
docker push <repository-name>

Спасибо. Значит, вам не нужно отправлять/публикации в докер-хаб?

xpt 20.05.2019 00:44

Нет, не знаешь. То, как вы используете образы Docker, зависит от среды, в которой вы будете их развертывать. Например, AWS предлагает репозиторий Docker (ECR), который позволяет отправлять образы Docker, поэтому в этом случае нет зависимости от Docker Hub. Используя AWS ECR, вы можете развертывать образы на вычислительных узлах с помощью инструмента оркестровки, такого как Kubernetes, или собственного ECS (Elastic Container Service) AWS.

Slawomir 20.05.2019 00:56

О, извините, я спрашивал, потому что в вашем ответе отсутствует часть отправки/публикации, так как мне делать нужно отправить/опубликовать образ докера в репозиторий Docker. ОП обновлен.

xpt 20.05.2019 01:25

Я обновил ответ; после того, как вы пометили сборку версией, вы можете отправить ее в удаленный репозиторий, например в Docker Hub.

Slawomir 20.05.2019 01:39
Ответ принят как подходящий

Docker вообще не придает семантического значения значениям тегов. Тег может быть любым строковым значением, и теги можно использовать повторно. Единственное специальное значение тега заключается в том, что если вы просто произносите imagename в команде docker pull или docker run, это автоматически интерпретируется как imagename:latest.

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

Я бы порекомендовал:

  1. Дайте сборке каждый уникальный идентификатор, что-то вроде идентификатора фиксации системы управления версиями или метки времени.
  2. Если и когда вы выпускаете официальные выпуски, также помечайте сборки этого выпуска номером выпуска. (В более общем случае, если текущая фиксация системы управления версиями помечена, пометьте образ Docker тегом системы управления версиями.)
  3. Если это полезно для вашего рабочего процесса разработки, также пометьте сборки, которые являются кончиками ветвей, с их именем ветки.
  4. Учитывая его известность, вероятно, полезно пометить что-то как latest (возможно, самый последний выпуск).
  5. Избегайте использования latest и других тегов, которые вы ожидаете изменить при ссылке на встроенные образы (в командах docker run, строках Dockerfile FROM, спецификациях модуля Kubernetes, ...).

Эта комбинация вещей может означать, что одно и то же изображение помечено imagename:g1234567, :1.2.3, :master и :latest, и вашей системе CI потребуется выполнить четыре docker pushes. Вы, вероятно, ожидаете, что первые два изображения будут довольно постоянными, но последние два будут регулярно меняться. Затем вы можете запустить что-то вроде imagename:1.2.3 с некоторой уверенностью.

(Один особый случай, который приходит на ум, — это программный пакет, который редко меняется, и поэтому может потребоваться пересборка, если есть исправления или обновления безопасности. Обычно для этого используется один и тот же тег: например, ubuntu:18.04 обновляется каждый раз. неделя или две)

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

xpt 20.05.2019 03:53

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

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


Для сопровождающих репозиториев вот несколько распространенных реализаций:

Вариант А: В идеале сопровождающие репозитория следуют той или иной форме немного. Этот номер версии должен соответствовать версии упакованного программного обеспечения, часто с дополнительным номером исправления для версии образа. Важно отметить, что изображения, помеченные таким образом, должны включать теги не только для версии 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.

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

Вариант Д: Я не сторонник размещения хэшей версий Git в качестве тегов изображений, поскольку они не передают никаких подробностей без обращения к репозиторию Git. Не у каждого пользователя может быть такой доступ или навык для понимания этого справочника. И, глядя на два разных хэша, я без внешней проверки не могу понять, какой из них новее или совместим с моим приложением. Они также предполагают, что единственным важным номером версии является Git, и игнорируют тот факт, что одна и та же версия Git может использоваться для создания нескольких образов из разных родительских образов, разных архитектур или просто нескольких файлов Dockerfile/multistage target в одном и том же репозитории Git. Вместо этого мне нравится использовать схема этикетки и, в конечном итоге, аннотации спецификации изображения, как только мы получим инструменты для аннотаций изображений, чтобы отслеживать такие детали, как версии Git. Это помещает версию Git в метаданные, которые вы можете запрашивать для проверки изображения, оставляя при этом сам тег информативным для пользователя.


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

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

Второй вариант — перестать зависеть от изменяемых тегов. Вместо этого вы можете использовать закрепление изображения, которое ссылается на уникальную ссылку реестра 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 с несовместимыми с предыдущими версиями изменениями. Ваше следующее развертывание непреднамеренно будет включать эти изменения, если только вы явно не зависите от тега, который предлагает исправления ошибок и исправления безопасности без серьезных изменений.

Большое спасибо за максимально исчерпывающий ответ. Я бы принял это, если бы это ответило на мою конкретную путаницу / вопрос в OP. Но все равно спасибо и голосую!

xpt 20.05.2019 03:48

Я помечаю хэш коммита git и отметку времени сборки (объединенные)

Это просто потому, что я хочу признать, что иногда на сервере сборки что-то меняется, что означает, что один и тот же код может быть скомпилирован по-разному. Например. переключение сервера сборки для компиляции с Java 13 вместо Java 11.

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