🐳 Обновление патчей безопасности в контейнерах Docker

Контейнеры неизменяемы, что означает, что их не следует исправлять на месте, как это делается для виртуальных машин или физических серверов.

Вместо этого обновление контейнера требует повторного развертывания обновленного контейнера и уничтожения старого.

Проблемы, связанные с исправлением контейнеров

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

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

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

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

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

Давайте рассмотрим обе практики – выполнение правильного цикла DevOps и некоторые потенциальные инструменты для мониторинга!

 

Команды DevOps устанавливают исправления при каждом развертывании

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

Все, что нужно, это убедиться, что ваш конвейер CI/CD перестраивает образ развертывания при каждой сборке.

Ниже я покажу очень простой пример с использованием Jenkins.

 

Автоматическое обновление контейнеров с помощью Jenkins

Давайте создадим простой пример, чтобы увидеть, как это работает.

Если вы еще не знакомы с Jenkins, с этого легко начать.

Сначала мы создадим и запустим контейнер Jenkins, а затем обновим его для работы с Docker.

Создайте следующий Dockerfile в новом каталоге:

# Начните с образа Jenkins

FROM    jenkins/jenkins:lts



# Установите Docker в наш образ

USER    root

RUN     apt update

RUN     apt-get install -y apt-transport-https ca-certificates wget software-properties-common

RUN     wget https://download.docker.com/linux/debian/gpg

RUN     apt-key add gpg

RUN     echo "deb https://download.docker.com/linux/debian stretch stable" > /etc/apt/sources.list.d/docker.list

RUN     apt update

RUN     apt-get install -y docker-ce



# Jenkins запускается под пользователем Jenkins, и ему потребуется 

# доступ к unix-сокету docker, который принадлежит root. 

# Обычно он должен иметь группу docker, но здесь он 

# принадлежит root:root. Мы можем изменить это, но для целей тестирования 

# я просто добавлю пользователя jenkins в группу root.

RUN     usermod -G root -a jenkins



# Switch back to jenkins user

USER    jenkins

Мы должны сделать небольшое изменение, чтобы дать пользователю jenkins доступ к сокету docker (который мы будем монтировать из хост-системы).

Давать групповой root пользователю jenkins – это не то, что я бы хотел делать, но для нашего тестового примера вполне подойдет.

Теперь давайте запустим этот контейнер:

$ docker build . -t jenkins_test

$ mkdir -p ~/jenkins_test

$ docker run 

    -p 8080:8080 

    -p 50000:50000 

    --name jenkins 

    --privileged=true 

    -v /home/nullsweep/jenkins_test:/var/jenkins_home 

    -v /var/run/docker.sock:/var/run/docker.sock 

    jenkins_test

Обратите внимание на несколько вещей, которые мы делаем с этим контейнером, чтобы убедиться, что он может создавать и запускать образы docker:

  • Запуск в привилегированном режиме, чтобы позволить ему запускать контейнеры братьев и сестер
  • Монтирование локального тома для тестовых конфигурационных файлов
  • Монтирование сокета docker, что дает контейнеру jenkins контроль над установкой docker на хосте.

Теперь войдите на localhost:8080 и выполните шаги по настройке Jenkins и создайте пайплайн под названием test.

Мы будем использовать это имя позже для размещения файлов проекта. В пайплайн добавьте простой скрипт в раздел “Pipeline”, тип – “Pipeline script”.

node {

    

    stage('Build image') {

        sh "docker build -t test --pull ."

    }

}

Обратите внимание, что здесь используется команда shell для сборки образа, а не плагин docker.

При использовании плагина можно получить сообщения, связанные с ошибкой Jenkins 31507 java.io.IOException: Cannot retrieve .Id from ‘docker inspect base AS final’.

Замена docker на команду оболочки исправила ситуацию.

# test в приведенном ниже пути - это имя пайплайна, настроенного в Jenkins

$ cd ~/jenkins_test/workspace/test

$ cat Dockerfile

FROM   nullsweep/test:latest

CMD    sh echo "I ran!"

Вернувшись в Jenkins, запустите сборку, нажав “Build Now”, и вы должны увидеть успешный пайлайн.

Пайплайн запускает скрипт оболочки для вызова docker и передает параметр –pull для принудительной перекомпоновки базовых образов.

Теперь у нас есть зачатки пайплайна, который будет отправлять последние исправления для ОС с каждым выпуском кода (при условии, что базовые образы поддерживаются в актуальном состоянии в своих репозиториях).

Никаких больше переносов патчей!

 

Мониторинг с помощью WatchTower

Что делать, если вы не выпускаете код хотя бы раз в месяц?

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

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

 

Обзор WatchTower

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

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

Он имеет достаточное количество опций для мониторинга, удаленного мониторинга, чатопсов и уведомлений.

 

Пример WatchTower

Мы создадим пользовательский базовый образ с файлом версии:

FROM    alpine:latest



RUN     echo "1.0" >> version.txt

CMD     echo "Version: " && cat version.txt

Мы разместим его в публичном репозитории docker под названием watch_base.

$ docker build . -t nullsweep/watch_base

$ docker push nullsweep/watch_base

И мы укажем его в новом образе, который мы хотим развернуть в качестве нашего приложения:

FROM    nullsweep/watch_base



RUN     printf "while [ 1 ] n 

           do n 

               echo 'Version: ' n 

               cat version.txt n 

               sleep 5s n 

           done n" >> version.sh

CMD     source version.sh

 

Этот образ создает скрипт оболочки, который выводитт файл version.txt каждые 5 секунд.

Давайте разместим его в новом публичном репозитории.

$ docker build . -t nullsweep/watch

$ docker push nullsweep/watch
# В первом терминале: скачайте и запустите контейнер для контроля:

$ docker pull nullsweep/watch

$ docker run --name watch nullsweep/watch:latest

Version:

1.0



# Во втором терминале запустите WatchTower:

$ docker pull v2tec/watchtower

$ docker run 

    -d 

    --name watchtower 

    -v /var/run/docker.sock:/var/run/docker.sock 

    v2tec/watchtower -i 5 --debug watch

Система запустит watchtower с парой пользовательских флагов: мониторинг только нашего собственного контейнера и проверка обновлений образа каждые 5 секунд вместо стандартных 5 минут.

В любой момент вы можете просмотреть журналы watchtower, выполнив команду:

$ docker logs watchtower

 

Вернувшись за пределы виртуальной машины, вы можете выполнить два теста:

  • Обновите образ watch_base, чтобы увеличить номер версии, и отправьте его в репозиторий. WatchTower не заметит этого изменения.
  • Пересоберите образ приложения (тот, который я назвал watch выше) и отправьте его в репозиторий. WatchTower вытащит его и перезапустит виртуальную машину с новой версией. Теперь у нас есть исправленный контейнер!

 

Заключение

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

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

Друзья помогите этому контенту стать доступнее в социальных сетях.

Не проходи мимо жмакни по кнопке возможно кому то еще он будет полезен!