Статьи

Недопустимый отказ Дженкинса в скоплении Docker Swarm

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

Настройка среды

Начнем с создания кластера Docker Swarm. Я предполагаю, что у вас уже есть хотя бы базовые знания о том, как работает Docker Swarm Mode. Если вы этого не сделаете, я предлагаю вам прочитать статью « Введение в Docker Swarm» (тур по Docker 1.12) или получить Docker Swarm .

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

1
2
3
4
5
git clone https://github.com/vfarcic/cloud-provisioning.git
 
cd cloud-provisioning
 
scripts/dm-swarm.sh

Мы клонировали cloud-provisioning хранилище и выполнили скрипт scripts / dm-swarm.sh, который создал производственный кластер.

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

1
2
3
eval $(docker-machine env swarm-1)
 
docker node ls

Вывод команды node ls выглядит следующим образом (для краткости идентификаторы удалены).

1
2
3
4
HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
swarm-2   Ready   Active        Reachable
swarm-1   Ready   Active        Leader
swarm-3   Ready   Active        Reachable

Теперь, когда производственный кластер запущен, мы можем создать сервис Jenkins.

Дженкинс Сервис

Традиционно мы запускаем Jenkins на своем собственном сервере. Даже если бы мы решили использовать ресурсы сервера совместно с другими приложениями, развертывание все равно будет статичным. Мы запустили экземпляр Jenkins (без или без Docker) и надеемся, что он никогда не потерпит неудачу. Проблема этого подхода заключается в том, что каждое приложение рано или поздно выходит из строя. Либо процесс остановится, либо весь узел умрет. В любом случае, Jenkins, как и любое другое приложение, в какой-то момент перестанет работать.

Проблема в том, что Jenkins становятся критически важным приложением во многих организациях. Если мы перенесем выполнение или, точнее говоря, запуск всей автоматизации в Jenkins, мы создадим сильную зависимость. Если Jenkins не работает, наш код не создается, он не тестируется и не развертывается. Конечно, когда это не удастся, вы можете поднять его снова. Если сервер, на котором он работает, перестает работать, вы можете развернуть его где-нибудь еще. Время простоя, если предположить, что это происходит в рабочее время, не будет продолжительным. Час, может, два или даже больше времени пройдет с того момента, как он перестает работать, кто-то узнает, уведомляет кого-то другого, что кто-то перезапускает приложение или предоставляет новый сервер. Это долго? Это зависит от размера вашей организации. Чем больше людей зависит от чего-то, тем больше стоимость, когда что-то не работает. Даже если такое время простоя и его стоимость не являются критическими, у нас уже есть все знания и инструменты, чтобы этого избежать. Все, что нам нужно сделать, это создать еще один сервис и позволить Swarm позаботиться обо всем остальном.

Давайте создадим сервис Дженкинс.

01
02
03
04
05
06
07
08
09
10
11
mkdir -p docker/jenkins
 
docker service create --name jenkins \
    -p 8082:8080 \
    -p 50000:50000 \
    -e JENKINS_OPTS="--prefix=/jenkins" \
    --mount "type=bind,source=$PWD/docker/jenkins,target=/var/jenkins_home" \
    --reserve-memory 300m \
    jenkins:2.7.4-alpine
 
docker service ps jenkins

Дженкинс сохраняет свое состояние в файловой системе. Поэтому мы начали с создания каталога ( mkdir ) на хосте. Он будет использоваться как дом Дженкинса. Поскольку мы находимся в одной из подкаталогов пользователя нашего хоста, каталог docker/jenkins монтируется на всех машинах, которые мы создали.

Далее мы создали сервис. Он выставляет внутренний порт 8080 как 8082 а также порт 50000 . Первый используется для доступа к пользовательскому интерфейсу Jenkins, а второй — для связи между мастером и агентом. Мы также определили префикс URL как /jenkins и смонтировали домашний каталог Jenkins. Наконец, мы зарезервировали 300m памяти.

После загрузки изображения выходные данные команды service ps выглядят следующим образом (для краткости идентификаторы удалены).

1
2
NAME      IMAGE                NODE    DESIRED STATE CURRENT STATE          ERROR
jenkins.1 jenkins:2.7.4-alpine swarm-1 Running       Running 52 seconds ago
CD-среда-Дженкинса только

Производственный кластер с сервисом Jenkins

Jenkins 2 изменил процесс установки. В то время как предыдущие версии позволяли нам запускать его без какой-либо обязательной конфигурации, новая Jenkins заставляет нас выполнить некоторые шаги вручную. К сожалению, на момент написания этой статьи не было хорошего API, который бы помог нам автоматизировать процесс. Хотя есть некоторые «хитрости», которые мы могли бы использовать, преимущества недостаточно велики по сравнению с дополнительной сложностью, которую они вносят. В конце концов, мы настроим Jenkins только один раз, поэтому нет особого стимула для автоматизации процесса (по крайней мере, до создания API конфигурации).

Давайте откроем интерфейс.

1
open http://$(docker-machine ip swarm-1):8082/jenkins

Первое, что вы заметите, это то, что вам необходимо ввести пароль администратора . Довольно много корпоративных пользователей требовали усиления безопасности. В результате к Jenkins невозможно получить доступ без инициализации сеанса. Если вы новичок в Jenkins или, по крайней мере, версии 2, вы можете спросить, какой пароль. Он выводится в журналы (в нашем случае stdout ), а также в файл secrets/initialAdminPassword который будет удален в конце процесса установки.

Давайте посмотрим содержимое файла secrets/initialAdminPassword .

1
cat docker/jenkins/secrets/initialAdminPassword

Вывод будет длинной строкой, представляющей временный пароль. Скопируйте его, вернитесь в пользовательский интерфейс, вставьте его в поле пароля администратора и нажмите кнопку « Продолжить» .

Дженкинс-настройка-пароль

Разблокировать экран дженкинс

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

Пожалуйста, нажмите кнопку Установить предложенные плагины .

После того, как плагины загружены и установлены, у нас появляется экран, который позволяет нам создать первого пользователя-администратора. Пожалуйста, используйте admin как имя пользователя и пароль . Заполните бесплатно, чтобы заполнить остальные поля с любым значением. Когда вы закончите, нажмите кнопку Сохранить и Готово .

Дженкинс-настройка-админ-пользователь

Экран «Создать первого администратора»

Дженкинс готов. Пока осталось только нажать кнопку « Пуск с использованием Jenkins» .

Теперь мы можем проверить, работает ли аварийное переключение Jenkins.

Jenkins Failover

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

1
2
3
4
5
NODE=$(docker service ps -f desired-state=running jenkins | tail +2 | awk '{print $4}')
 
eval $(docker-machine env $NODE)
 
docker rm -f $(docker ps -qa -f "ancestor=jenkins:2.7.4-alpine")

Мы перечислили процессы Jenkins и применили фильтр, который будет возвращать только тот, в котором running требуемое состояние ( docker service ps -f desired-state=running jenkins ). Вывод был передан в команду tail, которая удалила заголовок ( tail +2 ), а затем снова был передан в команду awk , ограничивающую вывод четвертым столбцом ( awk '{print $4}' ), который содержит узел процесс запущен. Окончательный результат был сохранен в переменной NODE .

Позже мы использовали команду eval для создания переменных среды, которые будут использоваться нашим клиентом Docker для работы с удаленным ядром. Наконец, мы удалили контейнер с помощью комбинации команд ps и rm .

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

Давайте подтвердим, что сервис действительно работает.

1
docker service ps jenkins

Если Swarm решил повторно запустить Jenkins на другом узле, это может занять несколько секунд, пока изображение не будет извлечено. Через некоторое время вывод команды service ps должен выглядеть следующим образом.

1
2
3
NAME           IMAGE           NODE     DESIRED STATE  CURRENT STATE                   ERROR
jenkins.1      jenkins:alpine  swarm-3  Running        Running less than a second ago
 \_ jenkins.1  jenkins:alpine  swarm-1  Shutdown       Failed 5 seconds ago            "task: non-zero exit (137)"

Мы можем сделать окончательное подтверждение, открыв интерфейс.

1
open http://$(docker-machine ip swarm-1):8082/jenkins

Поскольку Jenkins не допускает неаутентифицированных пользователей, вам придется авторизоваться. Пожалуйста, используйте admin как пользователя и пароль .

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

Нам удалось сделать отказоустойчивым Jenkins, но нам не удалось заставить его работать без простоев. Из-за своей архитектуры мастер Дженкинса не может быть масштабирован. В результате, когда мы смоделировали сбой путем удаления контейнера, не было второго экземпляра для поглощения трафика. Несмотря на то, что Swarm переназначил это на другом узле, было некоторое время простоя. В течение короткого периода услуга была недоступна. Хотя это не идеальная ситуация, нам удалось сократить время простоя до минимума. Мы сделали его отказоустойчивым, но не смогли запустить его без простоев. Учитывая его архитектуру, мы сделали все, что могли.

Если вам понравилась эта статья, вас может заинтересовать book. В отличие от предыдущего заголовка серии ( ), в котором подробно рассматриваются некоторые из последних практик и инструментов DevOps, эта книга полностью посвящена Docker Swarm *, а также процессам и инструменты, которые могут нам понадобиться для ** создания, тестирования, развертывания и мониторинга служб, работающих в кластере.

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

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