Як автоматично оновлювати контейнери докера, якщо базові зображення оновлюються


205

Скажіть, у мене є тривіальний контейнер на основі ubuntu:latest. Зараз є оновлення безпеки та ubuntu:latestоновляється в док-репо.

  1. Як я можу знати, що мій локальний образ та його контейнери бігають позаду?

  2. Чи є найкраща практика для автоматичного оновлення локальних зображень та контейнерів, щоб слідкувати за оновленнями док-репо, що на практиці надасть вам ті ж самі смаки, що без нагляду оновлення працювати на звичайній машині ubuntu


11
Я шукаю відповідь на це з початку докера. Це навіть трохи складніше. Якщо я встановлю apache (наприклад), і він оновлюється, базове зображення не змінюється, оскільки я встановив його згодом. Я все ще хотів би мати автоматичні оновлення для apache. Я насправді запитав у IRC про це і отримав "слідкуйте за потоком та відновлюйте оновлення" як відповідь ...
Mathias

8
Радий, що я не єдиний, хто цікавиться. Здається, розвиток та відтворюваність важливіші для докерських розробників, ніж розумні механізми оновлення, які ми маємо вже багато років.
hbogert

Проблема в тому, що докер - це лише технологія для контейнерів. Я думаю, що потрібен певний час, щоб екосистема розвивалася навколо цього. Є й інші проблеми, які докер не вирішує, як реєстрація.
Матіас

3
Дякую всім, хто відповів. Вибачте, що не зміг розбити багатство. Незважаючи на те, що остаточного вирішення моєї проблеми не було, все-таки було добре.
Матіас

1
Для @Mathias рішення, яке я щойно додав, має сценарій, який перевірятиме оновлення безпеки для пакетів, встановлених у контейнері після витягування. Він також має окремий сценарій для перевірки базового зображення.
Фмстрат

Відповіді:


8

Один із способів зробити це - керувати цим через ваші системи CI / CD. Після того, як побудовано зображення вашого батька, створіть щось, що сканує ваші git repos для зображень за допомогою цього батьківського. Якщо його знайдено, ви надішлете запит на витяг, щоб перейти на нові версії зображення. Запит на витяг, якщо всі тести пройдуть, буде об’єднано, і у вас з’явиться новий дочірній образ на основі оновленого батьківського. Приклад інструменту, який застосовує такий підхід, можна знайти тут: https://engineering.salesforce.com/open-sourcing-dockerfile-image-update-6400121c1a75 .

Якщо ви не керуєте своїм батьківським зображенням, як це було б у випадку, якщо ви залежаєте від офіційного ubuntuзображення, ви можете написати певний інструментарій, який визначає зміни в батьківському тезі зображень або контрольній сумі (не те саме, теги можуть змінюватися) та викликати відповідно побудови дітей.


Ого, це великий молоток, який сказав: з часу, коли я задав це питання, я також зрозумів, що сервер збірки - це місце для вирішення цієї проблеми. Я радий бачити деякі інструменти. Якщо ви поясните свій підхід у загальних поняттях (а не ваш точний інструмент / реалізація) і включите його у відповідь, я, мабуть, його прийму.
hbogert

Спасибі @hbogert Я відредагував вище, а також включив уявлення про те, що робити, якщо ти маєш справу з публічними зображеннями
Ma3oxuct

123

Ми використовуємо скрипт, який перевіряє, чи запущений контейнер запускається з останнього зображення. Ми також використовуємо upstart init-скрипти для запуску зображення докера.

#!/usr/bin/env bash
set -e
BASE_IMAGE="registry"
REGISTRY="registry.hub.docker.com"
IMAGE="$REGISTRY/$BASE_IMAGE"
CID=$(docker ps | grep $IMAGE | awk '{print $1}')
docker pull $IMAGE

for im in $CID
do
    LATEST=`docker inspect --format "{{.Id}}" $IMAGE`
    RUNNING=`docker inspect --format "{{.Image}}" $im`
    NAME=`docker inspect --format '{{.Name}}' $im | sed "s/\///g"`
    echo "Latest:" $LATEST
    echo "Running:" $RUNNING
    if [ "$RUNNING" != "$LATEST" ];then
        echo "upgrading $NAME"
        stop docker-$NAME
        docker rm -f $NAME
        start docker-$NAME
    else
        echo "$NAME up to date"
    fi
done

І так виглядає ініт

docker run -t -i --name $NAME $im /bin/bash

1
Велике спасибі за цей цінний внесок. Це здається хорошим способом оновлення базового зображення. Залишилося питання, як ви оновлюєте додаток (наприклад, apache), встановлений дистрибутивом у dockerfile? Або ви використовуєте лише готові базові зображення, для яких потрібен лише ваш код програми (наприклад, веб-сайт)?
Матіас

Ми використовуємо пакувальник і маріонетку для налаштування наших зображень. Наші зображення готові до
запуску

@Mathias, дивіться мою відредаговану відповідь У мене є крихітний докер- інструмент, який я використовую для оновлення пакетів Linux (на даний момент debian / ubuntu) у всіх запущених контейнерах.
iTech

3
Якщо зображення має те саме ім’я, що і контейнер (наприклад redis), LATEST=`docker inspect --format "{{.Id}}" $IMAGE`отримає інформацію про контейнер. Додати, --type imageщоб виправити це.
Патрік Фішер

1
Дякуємо за ваш пост Я змінив його, щоб обернути всю річ у циклі, щоб отримати зображення з докера: for IMAGE in $(docker ps --format {{.Image}} -q | sort -u)
Арман

25

«Докерним способом» буде використання автоматизованих побудов док-хаб . Функція Посилання сховища відновить ваш контейнер, коли контейнер, що перебуває вище, буде відновлений, а функція Webhooks надішле вам сповіщення.

Схоже, веб-камери обмежені викликами HTTP POST. Вам потрібно буде налаштувати службу, щоб знайти їх, або, можливо, скористатися однією з пошт для надсилання електронних служб там.

Я не розглядав це, але у новій універсальній контрольній площині Docker може бути функція виявлення оновлених контейнерів та повторне розгортання.


Мені довелося створити веб-крок до сервісу AMQP: github.com/goliatone/rabbithook
goliatone

На жаль, тригери вище за течією більше не доступні: github.com/docker/hub-feedback/isissue/1717 .
Жульєн Частанг

22

Ви можете скористатися сторожовою вежею, щоб спостерігати за оновленнями зображення, з якого контейнер створюється, і автоматично витягніть оновлення та перезавантажте контейнер, використовуючи оновлене зображення. Однак це не вирішує проблему відновлення власних користувальницьких зображень, коли є зміна зображення, що базується на потоці, на якому він заснований. Ви можете розглянути це як проблему з двох частин: (1) знати, коли оновлено зображення вище за течією, і (2) зробити реконструкцію фактичного зображення. (1) можна вирішити досить легко, але (2) багато що залежить від локального середовища / практики побудови, тому створити узагальнене рішення для цього, ймовірно, набагато складніше.

Якщо ви можете використовувати автоматизовані збірки Docker Hub , всю проблему можна вирішити відносно чисто, використовуючи функцію посилань на сховища , яка дозволяє автоматично запускати відновлення при оновленому сховищі (можливо, вище за течією). Ви також можете налаштувати веб- кукію, щоб повідомляти вас про автоматичну збірку. Якщо ви хочете отримати сповіщення електронною поштою чи SMS, ви можете підключити веб-крок до IFTTT Maker . Я вважав, що інтерфейс користувача IFTTT є дещо заплутаним, але ви налаштуєте веб-крок Docker для публікації на https://maker.ifttt.com/trigger/docker_xyz_image_built / with / key / your_key.

Якщо вам потрібно створити локально, ви можете, принаймні, вирішити проблему отримання сповіщень, коли зображення вгору за течією оновлюється, створивши манекенне репо в Docker Hub, пов’язане з вашими репортажами, що цікавлять вас. Єдиною метою фіктивного репо було б запустити веб-каре, коли воно буде перебудовано (що означає, що один із пов'язаних репостів був оновлений). Якщо ви можете отримати цю веб-кукію, ви можете навіть використати її, щоб викликати перебудову на вашій стороні.


1
Вартова башта використовує докер-розетку. З точки зору безпеки, яка надає кореневий доступ до хост-машини.
JoeG

1
Крім того, сторожова вежа, здається, не може оновити зображення з приватних сховищ, окрім Docker Hub. Бампер для нас, хто використовує Azure.
Томас Ейд

1
Ви можете використовувати приватні реєстри з використанням змінних REPO_USERі REPO_PASSсередовища. Подивіться readme.md з Вартової вежі для отримання додаткової інформації: github.com/v2tec/watchtower#usage
Алехандро Нортес

2
Слова попередження, сторожова вежа відмовилася від її обслуговуючого персоналу, а зображення в DockerHub навіть не відповідає сучасній картині в github.
XanderStrike

Здається, РЕПО сторожової вежі було перенесено на contentrrr / watchtower . І є кілька проблем із пов'язаними автоматизованими побудовами на Dockerhub, на що вказує ця відповідь на подібне запитання .
chrki

10

У мене було те саме питання, і я вважав, що це може бути вирішено просто unattended-upgradeщоденним телефоном .

Я маю намір мати це як автоматичне та швидке рішення, щоб забезпечити безпеку та оновлення виробничого контейнера, тому що мені може знадобитися колись оновити свої зображення та розгорнути новий образ докера з останніми оновленнями безпеки.

Можливо також автоматизувати створення та розгортання зображень за допомогою гачків Github

Я створив базове зображення докера, яке автоматично перевіряє та встановлює оновлення безпеки щодня (може працювати безпосередньо docker run itech/docker-unattended-upgrade).

Я також натрапив на інший підхід, щоб перевірити, чи потребує контейнер оновлення.

Моя повна реалізація:

Докерфайл

FROM ubuntu:14.04   

RUN apt-get update \
&& apt-get install -y supervisor unattended-upgrades \
&& rm -rf /var/lib/apt/lists/*

COPY install /install
RUN chmod 755 install
RUN /install

COPY start /start
RUN chmod 755 /start

Сценарії помічників

встановити

#!/bin/bash
set -e

cat > /etc/supervisor/conf.d/cron.conf <<EOF
[program:cron]
priority=20
directory=/tmp
command=/usr/sbin/cron -f
user=root
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
EOF

rm -rf /var/lib/apt/lists/*

ENTRYPOINT ["/start"]

почати

#!/bin/bash

set -e

echo "Adding crontab for unattended-upgrade ..."
echo "0 0 * * * root /usr/bin/unattended-upgrade" >> /etc/crontab

# can also use @daily syntax or use /etc/cron.daily

echo "Starting supervisord ..."
exec /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf

Редагувати

Я розробив невеликий докерний запуск інструменту, який працює як контейнер докера і може використовуватися для оновлення пакетів у всіх або вибраних запущених контейнерах, він також може бути використаний для запуску будь-яких довільних команд.

Можна легко перевірити за допомогою наступної команди:

docker run --rm -v /var/run/docker.sock:/tmp/docker.sock itech/docker-run exec

яка за замовчуванням виконує dateкоманду у всіх запущених контейнерах та відображатиме результати. Якщо ви перейдете updateзамість execнього, він буде apt-get updateвиконаний з наступним apt-get upgrade -yу всіх запущених контейнерах


моє посилання на без нагляду оновлення полягало лише в тому, щоб показати аналогію в не-докерському середовищі. Моя мета полягає в тому, щоб вирішити це докерським способом (якщо такий існує oc.) Додатковий процес у контейнері перемагає мету docker imo. Це виправляє проблему затримки між оновленням їхнього зображення вгору за течією та вами, користувачем, фактично переносячи його на ваш поточний контейнер. Хоча це може тривати до 1 дня і без догляду за оновленнями, тому .. Також посилання на github є незадовільним, оскільки механізм оновлення сильно залежить від хост-операційної системи.
hbogert

"Докерний шлях" не заважає запускати інші процеси в тому ж контейнері, якщо вони тісно пов'язані між собою і не створюватимуть вузького місця, що може бути масштабованим. І саме цей випадок використання є хорошим прикладом, коли ви можете мати контейнер з іншим запущеним процесом. (наприклад, див. зображення для gitlab, оскільки він виконує декілька обов'язкових процесів в одному контейнері).
iTech

Я б не назвав механізм оновлення, тісно пов'язаний з основною функцією зображення. Це рішення, як надання кожному додатку на звичайній машині власний механізм оновлення, а не навантаження на менеджера пакунків. Хоча це рішення, воно не відповідає на моє запитання, яке полягає в автоматичному оновленні локальних зображень, а потім контейнери повинні бути повторно використані. За допомогою оновлення в самих контейнерах ми знову вводимо багато стану, про який ми поняття не маємо, що суперечить докерному шляху (знову imho).
hbogert

1
Можливо, вам знадобиться щось більш високого рівня, ніж докер, такий, Kubernetesякий корисний для великого розгортання інфраструктури, але Google все ще перебуває під значним розвитком. На даний момент ви можете автоматизувати це за допомогою засобу забезпечення типу "Ansible" досить простим способом.
iTech

Ваш цитований "інший підхід" може бути тим, що я шукав. Ваш власний внесок виглядає життєздатною альтернативою "жирових контейнерів". Я обов'язково роздивлюсь і те й інше, дякую за вашу відповідь.
Матіас

7

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

docker pull image:tag
docker-compose -f docker-compose.yml -f production.yml up -d --build

Команди можуть бути введені в сценарій разом з усім іншим, необхідним для завершення оновлення, хоча правильний контейнер не потребує нічого додаткового.


1: гаразд, але тоді мені доведеться переглянути всі мої локальні зображення, отримати їх базові зображення, витягнути їх. Потім відновіть зображення, основні зображення яких змінилися. Потім зупиніть контейнери, зображення яких змінено, і відтворіть контейнери з 'запуском докера' та необхідними параметрами. Це здається надмірно посібником. Але якщо це статус-кво, то я прийму відповідь.
hbogert

Будь ласка, зачекайте, перш ніж приймати. Можливо, там щось є. Я використовую докер вже 6 місяців, але не був в курсі останніх подій.
seanmcl

Якось внутрішньо, Докер здатний порівнювати зображення для того, щоб виконати свої можливості кешування. Можливо, ви можете знайти спосіб використовувати ТОЩО. Іншими словами, перевірте, чи змінилися основні зображення (аж до основи), а потім запустити процес відновлення. На жаль, кешування вам не допоможе в цьому випадку: все зображення буде перебудовано, оскільки базове зображення змінилося.
Том Паркін

5

Управління залежністю для зображень Докера - справжня проблема. Я є частиною команди, яка створила інструмент MicroBadger , щоб допомогти у цьому, відстежуючи зображення контейнерів та перевіряючи метадані. Однією з його особливостей є те, що ви можете налаштувати веб-камери сповіщень, які викликаються, коли зображення, яке вас цікавить (наприклад, базове зображення), змінюється.


5

Тут є багато відповідей, але жодна з них не відповідала моїм потребам. Я хотів реальної відповіді на питання №1 запитувача. Як дізнатися, коли зображення оновлюється на hub.docker.com?

Наведений нижче сценарій можна запускати щодня. Під час першого запуску він отримує базову лінію тегів та дат оновлення з реєстру HUB та зберігає їх локально. Відтоді кожен раз, коли він запускається, він перевіряє реєстр на наявність нових тегів та оновлення дат. Оскільки це змінюється щоразу, коли існує нове зображення, воно повідомляє нам, чи змінилося базове зображення. Ось сценарій:

#!/bin/bash

DATAPATH='/data/docker/updater/data'

if [ ! -d "${DATAPATH}" ]; then
        mkdir "${DATAPATH}";
fi
IMAGES=$(docker ps --format "{{.Image}}")
for IMAGE in $IMAGES; do
        ORIGIMAGE=${IMAGE}
        if [[ "$IMAGE" != *\/* ]]; then
                IMAGE=library/${IMAGE}
        fi
        IMAGE=${IMAGE%%:*}
        echo "Checking ${IMAGE}"
        PARSED=${IMAGE//\//.}
        if [ ! -f "${DATAPATH}/${PARSED}" ]; then
                # File doesn't exist yet, make baseline
                echo "Setting baseline for ${IMAGE}"
                curl -s "https://registry.hub.docker.com/v2/repositories/${IMAGE}/tags/" > "${DATAPATH}/${PARSED}"
        else
                # File does exist, do a compare
                NEW=$(curl -s "https://registry.hub.docker.com/v2/repositories/${IMAGE}/tags/")
                OLD=$(cat "${DATAPATH}/${PARSED}")
                if [[ "${VAR1}" == "${VAR2}" ]]; then
                        echo "Image ${IMAGE} is up to date";
                else
                        echo ${NEW} > "${DATAPATH}/${PARSED}"
                        echo "Image ${IMAGE} needs to be updated";
                        H=`hostname`
                        ssh -i /data/keys/<KEYFILE> <USER>@<REMOTEHOST>.com "{ echo \"MAIL FROM: root@${H}\"; echo \"RCPT TO: <USER>@<EMAILHOST>.com\"; echo \"DATA\"; echo \"Subject: ${H} - ${IMAGE} needs update\"; echo \"\"; echo -e \"\n${IMAGE} needs update.\n\ndocker pull ${ORIGIMAGE}\"; echo \"\"; echo \".\"; echo \"quit\"; sleep 1; } | telnet <SMTPHOST> 25"
                fi

        fi
done;

Ви хочете змінити DATAPATHзмінну вгорі та змінити команду сповіщення електронною поштою в кінці відповідно до ваших потреб. Для мене це SSH на сервер в іншій мережі, де знаходиться мій SMTP. Але ви також могли легко використовувати mailкоманду.

Тепер ви також хочете перевірити наявність оновлених пакетів усередині контейнерів. Це насправді, ймовірно, ефективніше, ніж робити "тягнення", коли ваші контейнери працюють. Ось сценарій для усунення цього:

#!/bin/bash


function needsUpdates() {
        RESULT=$(docker exec ${1} bash -c ' \
                if [[ -f /etc/apt/sources.list ]]; then \
                grep security /etc/apt/sources.list > /tmp/security.list; \
                apt-get update > /dev/null; \
                apt-get upgrade -oDir::Etc::Sourcelist=/tmp/security.list -s; \
                fi; \
                ')
        RESULT=$(echo $RESULT)
        GOODRESULT="Reading package lists... Building dependency tree... Reading state information... Calculating upgrade... 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded."
        if [[ "${RESULT}" != "" ]] && [[ "${RESULT}" != "${GOODRESULT}" ]]; then
                return 0
        else
                return 1
        fi
}

function sendEmail() {
        echo "Container ${1} needs security updates";
        H=`hostname`
        ssh -i /data/keys/<KEYFILE> <USRER>@<REMOTEHOST>.com "{ echo \"MAIL FROM: root@${H}\"; echo \"RCPT TO: <USER>@<EMAILHOST>.com\"; echo \"DATA\"; echo \"Subject: ${H} - ${1} container needs security update\"; echo \"\"; echo -e \"\n${1} container needs update.\n\n\"; echo -e \"docker exec ${1} bash -c 'grep security /etc/apt/sources.list > /tmp/security.list; apt-get update > /dev/null; apt-get upgrade -oDir::Etc::Sourcelist=/tmp/security.list -s'\n\n\"; echo \"Remove the -s to run the update\"; echo \"\"; echo \".\"; echo \"quit\"; sleep 1; } | telnet <SMTPHOST> 25"
}

CONTAINERS=$(docker ps --format "{{.Names}}")
for CONTAINER in $CONTAINERS; do
        echo "Checking ${CONTAINER}"
        if needsUpdates $CONTAINER; then
                sendEmail $CONTAINER
        fi
done

1
mkdir у першому сценарії, ймовірно, повинен бути: mkdir -p Крім того, перший скрипт порівнює VAR1 з VAR2, припустимо, що слід порівняти СТАРИЙ з НОВИМ. Якщо правда, це означає, що цей скрипт насправді не буде робити те, що хоче ОП, ПІДНЯТЬ, що його вперше запустили під час встановлення. Тобто, насправді нічого не визначається щодо того, що встановлено, лише якщо результати відрізняються від попередніх циклів ...
JoeG

5

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

Наскільки я можу сказати, популярні базові зображення, такі як офіційний Debian або Java, оновлюють свої теги, щоб забезпечити виправлення безпеки, тому теги не є незмінними (якщо ви хочете отримати більш гарантію того, що вам потрібно використовувати посилання [image: @digest ], доступний у більш пізніх версіях Docker). Тому, якщо ви збиралися створити своє зображення docker build --pull, то ваша програма повинна отримати найновіший і найкращий тег базового зображення, на який ви посилаєтесь.

Оскільки змінні теги можуть бути заплутаними, найкраще збільшувати номер версії вашої програми щоразу, коли ви робите це, щоб, принаймні, на вашій стороні речі були чистішими.

Тому я не впевнений, що сценарій, запропонований в одній з попередніх відповідей, справляється з цим завданням, оскільки він не відновлює зображення програми - він просто оновлює тег базового зображення, а потім перезавантажує контейнер, але новий контейнер все ще посилається старий хеш базового зображення

Я б не виступав за запуск завдань типу cron в контейнерах (або будь-яких інших процесах, якщо це дійсно не потрібно), оскільки це суперечить мантрі виконання лише одного процесу в контейнері (є різні аргументи, чому це краще, тому я ' м. сюди не збиратись).


4

Я не замислююся над усім питанням, хочете ви чи не хочете без нагляду оновлень у виробництві (я думаю, що ні). Я просто залишаю це для довідки, якщо хтось вважає це корисним. Оновіть усі зображення докера до останньої версії, виконавши наступну команду у своєму терміналі:

# docker images | awk '(NR>1) && ($2!~/none/) {print $1":"$2}' | xargs -L1 docker pull


1
Команда корисна для оновлення всіх зображень, але вона не змінює нічого, що працює у виробництві. Контейнери все ще випливають із старих зображень, які тепер не позначені тегами.
Ні

Правда. І ось ще одна для книг ... Використовуйте # docker system prune -a --volumes -fдля очищення старих (звисаючих) зображень, томів тощо
Meferdati

4

ОНОВЛЕННЯ: Використовуйте Dependabot - https://dependabot.com/docker/

BLUF: пошук правильної точки вставки для моніторингу змін контейнера є проблемою. Було б чудово, якби DockerHub вирішив це. (Посилання на репозиторії були згадані, але зауважте, налаштовуючи їх на DockerHub - " Запускайте збірку в цьому сховищі кожного разу, коли базове зображення оновлюється на Docker Hub. Працює лише для неофіційних зображень." )

Намагаючись вирішити це, я побачив декілька рекомендацій щодо веб-кнопок, тому хотів детальніше розглянути декілька застосованих рішень.

  1. Використовуйте microbadger.com для відстеження змін у контейнері та використовуйте його функцію веб-купівлі сповіщень для запуску дії. Я налаштував це на zapier.com (але ви можете скористатися будь-яким настроюваним сервісом webhook), щоб створити нову проблему в моєму сховищі github, яке використовує Alpine як базове зображення.

    • Плюси: Ви можете переглянути зміни, про які повідомляв microbadger в Github, перш ніж вживати заходів.
    • Мінуси: Microbadger не дозволяє відстежувати конкретний тег. Схоже, він відстежує лише "останнє".
  2. Відстежуйте RSS-канал на предмет git-зобов'язань до контейнера вище. колишній https://github.com/gliderlabs/docker-alpine/commits/rootfs/library-3.8/x86_64 . Я використовував zapier.com для моніторингу цього каналу та для запуску автоматичної збірки свого контейнера в Travis-CI, коли що-небудь робиться. Це трохи екстремально, але ви можете змінити тригер, щоб зробити інші речі, як відкрити проблему у вашому сховищі git для ручного втручання.

    • Плюси: Ближче до автоматизованого трубопроводу. Збірка Travis-CI просто перевіряє, чи є у вашого контейнера проблеми з тим, що було пов’язано з сховищем базових зображень. Це залежить від вас, якщо ваша служба CI вживатиме будь-які подальші дії.
    • Мінуси: Відстеження каналу фіксації не є ідеальним. Багато речей присвячується сховищу, що не впливає на збірку базового зображення. Не враховує жодних проблем із частотою / кількістю комітетів та будь-яким придушенням API.

3

Примітка моєї відповіді:

  1. Контейнери запускаються з тегами.
  2. Один і той же тег може бути вказаний на інший UUID-образ зображення, наскільки ми хочемо / вважаємо за потрібне.
  3. Оновлення, зроблені для зображення, можуть бути введені в новий шар зображення

Підхід

  1. Створіть усі контейнери в першу чергу за допомогою сценарію оновлення патча безпеки
  2. Побудуйте автоматизований процес для наступного
    • Запустіть наявний образ у новий контейнер із сценарієм патчу безпеки як командою
    • Внесіть зміни до зображення як
      • існуючий тег -> з наступним перезавантаженням контейнерів один за одним
      • новий тег версії -> замініть кілька контейнерів на новий тег -> перевірити -> перемістити всі контейнери на новий тег

Крім того, базове зображення можна модернізувати / контейнер із цілком новим базовим зображенням можна будувати через рівні проміжки часу, оскільки обслуговуючий персонал вважає за потрібне

Переваги

  1. Ми зберігаємо стару версію зображення при створенні нового виправленого зображення безпеки, отже, при необхідності ми можемо відкатати попереднє запущене зображення
  2. Ми зберігаємо кеш-пам'ять докера, отже, менше передачі мережі (лише змінений шар потрапляє на провід)
  3. Процес оновлення можна перевірити поетапно, перш ніж переходити до prod
  4. Це може бути контрольованим процесом, отже, виправлення виправлень безпеки лише тоді, коли це необхідно / вважається важливим.

У виробничому середовищі, хоча вони є оновленнями безпеки, я сумніваюся, що ви хочете мати оновлення без нагляду! Якщо необхідні оновлення без нагляду, процес можна запускати через рівні проміжки часу (у відповідних випадках) як завдання cron.
Фані

1
Моя передумова полягає в тому, що оновлення безпеки повинні надходити з зображень верхнього / базового рівня.
hbogert

@hbogert Я скоріше скажу, що між теорією та практикою існує чітка лінія розмежування. Коли речі втіляться в життя, з’явиться багато зовнішніх аспектів, які потрібно враховувати, наприклад: вартість (не тільки вартість долара, але і час), пов'язана з реалізацією.
Фані

3

Вище відповіді також є правильними

Є два підходи

  1. Використовуйте веб-гачки
  2. Запускайте сценарій кожну конкретну хвилину, щоб отримати свіжі зображення докерських зображень

Я просто ділюсь сценарієм, можливо, він буде корисним для вас! Ви можете використовувати його з cronjob, я успішно спробував на OSX

#!/bin/bash
##You can use below commented line for setting cron tab for running cron job and to store its O/P in one .txt file  
#* * * * * /usr/bin/sudo -u admin -i bash -c /Users/Swapnil/Documents/checkimg.sh > /Users/Swapnil/Documents/cron_output.log 2>&1
# Example for the Docker Hub V2 API
# Returns all images and tags associated with a Docker Hub organization account.
# Requires 'jq': https://stedolan.github.io/jq/

# set username, password, and organization
# Filepath where your docker-compose file is present
FILEPATH="/Users/Swapnil/Documents/lamp-alpine"
# Your Docker hub user name
UNAME="ur username"
# Your Docker hub user password
UPASS="ur pwd"
# e.g organisation_name/image_name:image_tag
ORG="ur org name"
IMGNAME="ur img name"
IMGTAG="ur img tag"
# Container name
CONTNAME="ur container name"
# Expected built mins
BUILDMINS="5"
#Generally cronjob frequency
CHECKTIME="5"
NETWORKNAME="${IMGNAME}_private-network"
#After Image pulling, need to bring up all docker services?
DO_DOCKER_COMPOSE_UP=true
# -------
echo "Eecuting Script @ date and time in YmdHMS: $(date +%Y%m%d%H%M%S)"
set -e
PIDFILE=/Users/Swapnil/Documents/$IMGNAME/forever.pid
if [ -f $PIDFILE ]
then
  PID=$(cat $PIDFILE)
  ps -p $PID > /dev/null 2>&1
  if [ $? -eq 0 ]
  then
    echo "Process already running"
    exit 1
  else
    ## Process not found assume not running
    echo $$
    echo $$ > $PIDFILE
    if [ $? -ne 0 ]
    then
      echo "Could not create PID file"
      exit 1
    fi
  fi
else
  echo $$ > $PIDFILE
  if [ $? -ne 0 ]
  then
    echo "Could not create PID file"
    exit 1
  fi
fi

# Check Docker is running or not; If not runing then exit
if docker info|grep Containers ; then
    echo "Docker is running"
else
    echo "Docker is not running"
    rm $PIDFILE
    exit 1
fi

# Check Container is running or not; and set variable
CONT_INFO=$(docker ps -f "name=$CONTNAME" --format "{{.Names}}")
if [ "$CONT_INFO" = "$CONTNAME" ]; then
    echo "Container is running"
    IS_CONTAINER_RUNNING=true
else
    echo "Container is not running"
    IS_CONTAINER_RUNNING=false
fi


# get token
echo "Retrieving token ..."
TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${UNAME}'", "password": "'${UPASS}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)

# get list of repositories
echo "Retrieving repository list ..."
REPO_LIST=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/${ORG}/?page_size=100 | jq -r '.results|.[]|.name')

# output images & tags
echo "Images and tags for organization: ${ORG}"
echo
for i in ${REPO_LIST}
do
  echo "${i}:"
  # tags
  IMAGE_TAGS=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/${ORG}/${i}/tags/?page_size=100 | jq -r '.results|.[]|.name')
  for j in ${IMAGE_TAGS}
  do
    echo "  - ${j}"
  done
  #echo
done

# Check Perticular image is the latest or not
#imm=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/${ORG}/${IMGNAME}/tags/?page_size=100)
echo "-----------------"
echo "Last built date details about Image ${IMGNAME} : ${IMGTAG} for organization: ${ORG}"
IMAGE_UPDATED_DATE=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/${ORG}/${IMGNAME}/tags/?page_size=100 | jq -r '.results|.[]|select(.name | contains("'${IMGTAG}'")).last_updated')
echo "On Docker Hub IMAGE_UPDATED_DATE---$IMAGE_UPDATED_DATE"
echo "-----------------"

IMAGE_CREATED_DATE=$(docker image inspect ${ORG}/${IMGNAME}:${IMGTAG} | jq -r '.[]|.Created')
echo "Locally IMAGE_CREATED_DATE---$IMAGE_CREATED_DATE"

updatedDate=$(date -jf '%Y-%m-%dT%H:%M' "${IMAGE_UPDATED_DATE:0:16}" +%Y%m%d%H%M%S) 
createdDate=$(date -jf '%Y-%m-%dT%H:%M' "${IMAGE_CREATED_DATE:0:16}" +%Y%m%d%H%M%S)
currentDate=$(date +%Y%m%d%H%M%S)

start_date=$(date -jf "%Y%m%d%H%M%S" "$currentDate" "+%s")
end_date=$(date -jf "%Y%m%d%H%M%S" "$updatedDate" "+%s")
updiffMins=$(( ($start_date - $end_date) / (60) ))
if [[ "$updiffMins" -lt $(($CHECKTIME+1)) ]]; then
        if [ ! -d "${FILEPATH}" ]; then
            mkdir "${FILEPATH}";
        fi
        cd "${FILEPATH}"
        pwd
        echo "updatedDate---$updatedDate" > "ScriptOutput_${currentDate}.txt"
        echo "createdDate---$createdDate" >> "ScriptOutput_${currentDate}.txt"
        echo "currentDate---$currentDate" >> "ScriptOutput_${currentDate}.txt"
        echo "Found after regular checking time -> Docker hub's latest updated image is new; Diff ${updiffMins} mins" >> "ScriptOutput_${currentDate}.txt"
        echo "Script is checking for latest updates after every ${CHECKTIME} mins" >> "ScriptOutput_${currentDate}.txt"
        echo "Fetching all new"
        echo "---------------------------"
        if $IS_CONTAINER_RUNNING ; then
            echo "Container is running"         
        else
            docker-compose down
            echo "Container stopped and removed; Network removed" >> "ScriptOutput_${currentDate}.txt"
        fi
        echo "Image_Created_Date=$currentDate" > ".env"
        echo "ORG=$ORG" >> ".env"
        echo "IMGNAME=$IMGNAME" >> ".env"
        echo "IMGTAG=$IMGTAG" >> ".env"
        echo "CONTNAME=$CONTNAME" >> ".env"
        echo "NETWORKNAME=$NETWORKNAME" >> ".env"
        docker-compose build --no-cache
        echo "Docker Compose built" >> "ScriptOutput_${currentDate}.txt"
        if $DO_DOCKER_COMPOSE_UP ; then
            docker-compose up -d
            echo "Docker services are up now, checked in" >> "ScriptOutput_${currentDate}.txt"  
        else
            echo "Docker services are down, checked in" >> "ScriptOutput_${currentDate}.txt"
        fi
elif [[ "$updatedDate" -gt "$createdDate" ]]; then 
    echo "Updated is latest"
    start_date=$(date -jf "%Y%m%d%H%M%S" "$updatedDate" "+%s")
    end_date=$(date -jf "%Y%m%d%H%M%S" "$createdDate" "+%s")
    diffMins=$(( ($start_date - $end_date) / (60) ))
    if [[ "$BUILDMINS" -lt "$diffMins" ]]; then
        if [ ! -d "${FILEPATH}" ]; then
            mkdir "${FILEPATH}";
        fi
        cd "${FILEPATH}"
        pwd
        echo "updatedDate---$updatedDate" > "ScriptOutput_${currentDate}.txt"
        echo "createdDate---$createdDate" >> "ScriptOutput_${currentDate}.txt"
        echo "currentDate---$currentDate" >> "ScriptOutput_${currentDate}.txt"
        echo "Found after comparing times -> Docker hub's latest updated image is new; Diff ${diffMins} mins" >> "ScriptOutput_${currentDate}.txt"
        echo "Actual image built time is less i.e. ${diffMins} mins than MAX expexted BUILD TIME i.e. ${BUILDMINS} mins" >> "ScriptOutput_${currentDate}.txt"
        echo "Fetching all new" >> "ScriptOutput_${currentDate}.txt"
        echo "-----------------------------"
        if $IS_CONTAINER_RUNNING ; then
            echo "Container is running"         
        else
            docker-compose down
            echo "Container stopped and removed; Network removed" >> "ScriptOutput_${currentDate}.txt"
        fi
        echo "Image_Created_Date=$currentDate" > ".env"
        echo "ORG=$ORG" >> ".env"
        echo "IMGNAME=$IMGNAME" >> ".env"
        echo "IMGTAG=$IMGTAG" >> ".env"
        echo "CONTNAME=$CONTNAME" >> ".env"
        echo "NETWORKNAME=$NETWORKNAME" >> ".env"
        docker-compose build --no-cache
        echo "Docker Compose built" >> "ScriptOutput_${currentDate}.txt"
        if $DO_DOCKER_COMPOSE_UP ; then
            docker-compose up -d
            echo "Docker services are up now" >> "ScriptOutput_${currentDate}.txt"  
        else
            echo "Docker services are down" >> "ScriptOutput_${currentDate}.txt"
        fi
    elif [[ "$BUILDMINS" -gt "$diffMins" ]]; then
        echo "Docker hub's latest updated image is NOT new; Diff ${diffMins} mins"
        echo "Docker images not fetched"
    else
        echo "Docker hub's latest updated image is NOT new; Diff ${diffMins} mins"
        echo "Docker images not fetched"
    fi
elif [[ "$createdDate" -gt "$updatedDate" ]]; then 
    echo "Created is latest"
    start_date=$(date -jf "%Y%m%d%H%M%S" "$createdDate" "+%s")
    end_date=$(date -jf "%Y%m%d%H%M%S" "$updatedDate" "+%s")
    echo "Docker hub has older docker image than local; Older than $(( ($start_date - $end_date) / (60) ))mins"
fi
echo 
echo "------------end---------------"
rm $PIDFILE

Ось мій файл док-композиції

version:  "3.2"
services:
  lamp-alpine:
    build:
      context: .
    container_name: "${CONTNAME}"
    image: "${ORG}/${IMGNAME}:${IMGTAG}"
    ports:
      - "127.0.0.1:80:80"
    networks:
      - private-network 

networks:
  private-network:
    driver: bridge

3

Ось найпростіший спосіб автоматичного оновлення контейнера докера

Поставте роботу через $ crontab -e:

0 * * * * sh ~/.docker/cron.sh

Створіть редактор ~/.dockerз файлом cron.sh:

#!/bin/sh
if grep -Fqe "Image is up to date" << EOF
`docker pull ubuntu:latest`
EOF
then
    echo "no update, just do cleaning"
    docker system prune --force
else
    echo "newest exist, recompose!"
    cd /path/to/your/compose/file
    docker-compose down --volumes
    docker-compose up -d
fi

0

ви спробували це: https://github.com/v2tec/watchtower . це простий інструмент, який працює в докер-контейнері, спостерігаючи за іншими контейнерами, якщо їх базове зображення змінилося, воно буде витягуватися і перевстановлюватися.


-1

Просте і велике рішення пастух


iiuc, це не допомагає в загальному сенсі, оскільки це поєднується з Swarm і лише перезапускається вгору за течією, тоді як ми хочемо реагувати, перебудовуватися тощо на зміни вгору, а не просто перезапускати.
hbogert

Це звучить як щось, що вам слід зробити в конвеєрі CI
user672009
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.