Поиск по сайту:

Как обновить контейнеры Docker, чтобы применить обновления образа


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

Получение новых изображений

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

Вот пример контейнера с изображением nginx:latest:

# Pull new image
docker pull nginx:latest

# Delete old container by name
docker rm example-nginx

# Start a new container
docker run -d -p 80:80 --name example-nginx nginx:latest

В Docker отсутствует встроенный способ обнаружения обновлений образа и замены запущенных контейнеров. Результатом является запутанный ручной процесс замены. Его можно упростить, используя Docker Compose для запуска ваших контейнеров вместо простой команды docker run.

Замена контейнеров с помощью Docker Compose

Docker Compose позволяет создавать декларативные представления стеков контейнеров с помощью файла docker-compose.yml. Стек запускается командой docker-compose up с использованием конфигурации, содержащейся в файле. Это заменяет длинный список флагов, обычно присваиваемых docker run.

В Docker Compose есть встроенная команда pull, которая извлекает обновленные версии всех образов в вашем стеке. Это по-прежнему двухэтапная процедура, так как после этого вы должны снова вручную запустить docker-compose up.

# Pull all images in the stack
docker-compose pull

# Restart the stack
# If a new image version has been pulled, containers 
# using the old tag will be replaced with new instances.
docker-compose up -d

Docker Compose предлагает более простой и запоминающийся интерфейс, в котором вам не нужно вводить имена изображений или запоминать флаги, которые вы передали в docker run. Две команды можно легко сократить до одного псевдонима оболочки:

alias composePullUp="docker-compose pull && docker-compose up -d"

Управление тегами изображений

Вам нужно указать правильный тег, когда вы загружаете изображения вручную. Docker Compose сделает это за вас и выберет теги, указанные в вашем docker-compose.yml.

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

Например, при извлечении новой версии node:14 вы получите последнюю версию исправления Node.js 14. При извлечении node:latest будет предоставлена самая последняя версия Node. js, в настоящее время 16. Если бы старый контейнер использовал этот образ, процесс извлечения и замены вызвал бы изменение основной версии для двоичного файла Node внутри контейнера.

Восстановление изображений

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

Сначала пересоберите образ:

docker build --pull -t my-image:latest .

Затем замените ваши контейнеры:

# Delete old container by name
docker rm my-container

# Start a new container
docker run -d --name my-container my-image:latest

Флаг --pull, заданный для docker build, указывает Docker на извлечение базового образа, на который есть ссылка в вашем Dockerfile. Без этого флага Docker повторно использовал бы существующую ссылку на тег, если образ уже присутствовал в системе.

Пользователи Docker Compose могут добиться тех же результатов с помощью соответствующих команд docker-compose:

docker-compose build --pull

docker-compose up -d

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

Программное обеспечение внутри контейнеров

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

Запуск apt-get update && apt get upgrade -y по расписанию (или аналогам вашего менеджера пакетов) является стандартной практикой при администрировании Linux-сервера без операционной системы. Эти команды обычно не запускаются в контейнере Docker, хотя они могут быть включены как часть Dockerfile для получения самых последних исправлений безопасности во время сборки образа.

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

Автоматизация обновлений контейнеров

Вы можете автоматизировать процесс проверки обновленных тегов изображений и перезапуска контейнеров с помощью сторонних проектов. Watchtower — популярный выбор, который отслеживает запущенные контейнеры и заменяет их при изменении их образа Docker Hub.

Сама Watchtower развернута как контейнер:

docker run -d -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower

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

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

Сторожевая башня по умолчанию работает только с Docker Hub. Вы можете использовать его с частными реестрами образов, указав учетные данные в файле конфигурации.

Создайте файл JSON со следующим содержимым:

{
    "auths": {
        "example.com": {
            "auth": "credentials"
        }
    }
}

Замените example.com на путь к вашему реестру.

Затем создайте строку учетных данных из имени пользователя и пароля реестра:

echo -n 'username:password' | base64

Вставьте полученную строку в кодировке Base64 в файл конфигурации, заменив текст-заполнитель credentials.

Смонтируйте файл конфигурации в свой контейнер Watchtower, чтобы разрешить доступ к вашему реестру:

docker run -d 
    -v config.json:/config.json
    -v /var/run/docker.sock:/var/run/docker.sock 
    containrrr/watchtower

Заключение

В Docker отсутствует какой-либо механизм для обнаружения и применения обновлений восходящего образа к запущенным контейнерам. Вы можете использовать команды Docker CLI последовательно, docker-compose в качестве абстракции более высокого уровня или сторонний инструмент, такой как Watchtower, для замены ваших контейнеров при выпуске новых версий образов.

В зависимости от ваших обстоятельств вы можете вообще не чувствовать необходимости обновлять контейнеры таким образом. Если ваша команда использует конвейеры непрерывной интеграции для создания образа Docker при каждом коммите, возможно, вы уже создаете и развертываете обновленные образы несколько раз в день. В этом случае убедитесь, что вы используете флаг --pull с docker build, чтобы в ваши образы были включены исправления основной ветки разработки.