1. Введение
В этой статье мы реализуем простой конвейер непрерывной доставки с Jenkins , Marathon и Mesos .
Во-первых, мы дадим общий обзор технологического стека и архитектуры с объяснением того, как все сочетается друг с другом. После этого мы перейдем к практическому пошаговому примеру.
Результатом этого станет полностью автоматизированный конвейер Jenkins, развертывающий наше приложение в нашем кластере Mesos с помощью Marathon.
2. Обзор стека технологий
При работе с контейнерами и микросервисными архитектурами мы сталкиваемся с новыми операционными проблемами, с которыми не справились бы при использовании более традиционных стеков.
Например, при развертывании в кластере нам приходится иметь дело с масштабированием, отказоустойчивостью, сетью и многим другим. Эти сложные проблемы распределенных вычислений можно решить с помощью распределенных ядер и планировщиков, таких как Apache Mesos и Marathon.
2.1. Месос
Проще говоря, Mesos можно рассматривать как единственный сервер, на котором будут запускаться наши приложения. На самом деле у нас есть кластер, но именно эта абстракция делает его таким полезным.
2.2. Марафон
Marathon — это фреймворк, который используется для развертывания наших приложений в Mesos, решая сложные для нас проблемы (проверка работоспособности, автоматическое масштабирование, отказоустойчивость, мониторинг и т. д.).
3. Настройка и установка
В этой статье предполагается, что у вас уже есть Jenkins, Mesos и Marathon. Если это не так, обратитесь к официальной документации по каждому из них, чтобы узнать, как их настроить. Без этого вы не сможете выполнить ни один из шагов в руководстве.
4. Наша система доставки
Мы создадим следующий конвейер Jenkins:
В этом подходе нет ничего особенно сложного — он синоним потока большинства современных конвейеров компакт-дисков. В нашем случае сборка будет означать размещение приложения в контейнере, а развертывание будет означать использование Marathon для его планирования в кластере Mesos.
5. Тестирование и сборка нашего приложения
Первым шагом является сборка и тестирование нашего приложения. Для простоты приложение, с которым мы будем работать, — это приложение Spring Boot. Из-за этого наш результирующий артефакт будет исполняемой банкой. У него не будет никаких внешних зависимостей, кроме JRE, что делает его очень простым в исполнении.
5.1. Создание нашей работы
Первое, что мы хотим сделать, это создать нашу работу Дженкинса. Давайте выберем «Новый элемент» на левой панели навигации, затем выберите создание проекта фристайла, назвав его « marathon-mesos-demo
» :
5.2. Интеграция с Git
Затем давайте настроим его для клонирования репозитория Github , содержащего наше приложение:
Для простоты наш репозиторий является общедоступным, что означает, что мы можем клонировать через https .
Если бы это было не так, и мы клонировали через SSH, был бы дополнительный шаг для настройки пользователя SSH и закрытого ключа, выходящий за рамки этой статьи.
5.3. Настройка триггеров сборки
Затем давайте настроим несколько триггеров сборки, чтобы наша задача каждую минуту опрашивала git на наличие новых коммитов:
5.4. Генерация нашего скрипта сборки
Теперь мы можем указать нашей работе выполнять сценарий оболочки при его запуске. Поскольку мы работаем с простым проектом Spring Boot Maven, все, что нам нужно сделать, это запустить команду « mvn clean install
». Это запустит все тесты и создаст исполняемый файл jar :
5.5. Создание нашего проекта
Теперь мы настроили начало нашего конвейера, давайте запустим его вручную, нажав «Build Now» в задании. Как только работа будет завершена, мы можем подтвердить, что она прошла, помеченная синим цветом.
6. Контейнеризация нашего приложения
Давайте перейдем к следующему этапу нашего конвейера, который включает упаковку и публикацию нашего приложения с помощью Docker. Нам нужно использовать Docker, поскольку Marathon управляет именно контейнерами. Это не лишено смысла, так как в контейнере может работать практически все. Такому инструменту, как Marathon, проще работать с абстракцией, предоставляемой ими.
6.1. Создание Dockerfile
Во-первых, давайте создадим Dockerfile в корне проекта. По сути, Dockerfile — это файл, содержащий инструкции для Docker Deamon о том, как создать образ:
FROM openjdk:8-jre-alpine
ADD target/mesos-marathon-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8082
ENTRYPOINT ["java","-jar","/app.jar"]
Образ, который мы создаем, прост — все, что он содержит, — это исполняемый файл jar и команда оболочки, которая выполнит его при запуске контейнера. Мы также должны убедиться, что мы открываем порт, который будет прослушивать наше приложение, в данном случае «8082».
6.2. Публикация изображения
Теперь, когда мы можем создать наш образ, давайте создадим простой скрипт bash, который создаст и опубликует его в нашем частном репозитории Docker Hub , и поместит его в корень нашего проекта:
#!/usr/bin/env bash
set -e
docker login -u foreach -p $DOCKER_PASSWORD
docker build -t foreach/mesos-marathon-demo:$BUILD_NUMBER .
docker push foreach/mesos-marathon-demo:$BUILD_NUMBER
Возможно, вам потребуется отправить образ в общедоступный или частный реестр докеров.
Переменная среды $BUILD_NUMBER
заполняется Jenkins и увеличивается с каждой сборкой. Несмотря на некоторую хрупкость, это быстрый способ увеличить номер версии каждой сборки. $DOCKER_PASSWORD
также заполняется Jenkins, и в этом случае мы будем использовать плагин EnvInject , чтобы сохранить его в секрете.
Хотя мы могли бы хранить этот сценарий непосредственно в Jenkins, лучше оставить его в системе управления версиями, так как затем его можно будет контролировать и проверять вместе с остальной частью нашего проекта.
6.3. Сборка и публикация на Jenkins
Теперь давайте изменим наше задание Jenkins, чтобы оно запускало «Dockerise.sh» после сборки jar:
А затем давайте запустим нашу работу, чтобы подтвердить еще раз, подтверждая, что все работает, когда он становится синим.
7. Развертывание нашего образа
Наш конвейер почти готов. Остался только один этап — использование Marathon для развертывания нашего приложения в нашем кластере Mesos.
Jenkins поставляется с плагином « Развертывание с Marathon ». Это действует как оболочка для Marathon API, упрощая работу по сравнению с традиционными сценариями оболочки. Вы можете установить его через менеджер плагинов.
7.1. Создание нашего файла Marathon.Json
Прежде чем мы сможем использовать плагин Marathon, нам нужно создать файл «marathon.json» и сохранить его в корне нашего проекта. Это потому, что плагин зависит от него.
Этот файл: «marathon.json» содержит определение приложения Mesos . Это описание долго работающей службы (приложения), которую мы хотим запустить. В конечном итоге подключаемый модуль Jenkins Marathon отправит содержимое файла в конечную точку Marathon /v2/apps
. Затем Marathon, в свою очередь, запланирует выполнение определенного приложения на Mesos:
{
"id": "mesos-marathon-demo",
"container": {
"type": "DOCKER",
"docker": {
"image": "",
"network": "BRIDGE",
"portMappings": [
{ "containerPort": 8082, "hostPort": 0 }
]
}
}
}
Это самая простая конфигурация, которую мы можем дать для контейнерного приложения.
Свойство: « portMappings
» должно быть установлено правильно, чтобы сделать наше приложение доступным с нашего ведомого устройства Mesos. По сути, это означает сопоставление порта контейнера 8082
со случайным портом на хосте (подчиненном устройстве mesos), чтобы мы могли общаться с нашим приложением из внешнего мира. После развертывания нашего приложения Marathon сообщит нам, какой порт используется.
7.2. Добавление шага сборки развертывания Marathon
Давайте добавим к нашей работе действие после сборки Marathon Deployment:
Обратите внимание, что мы сообщаем плагину, где запущен Marathon, в данном случае «localhost:8081». Мы также сообщаем ему образ, который хотим развернуть. Это то, на что заменяется пустое поле «изображение» в нашем файле.
Теперь, когда мы создали последний этап нашего конвейера, давайте запустим нашу работу еще раз и подтвердим, что она все еще проходит, на этот раз с дополнительным шагом, на котором наше приложение отправляется в Marathon.
7.3. Проверка нашего развертывания в Marathon
Теперь, когда он развернут, давайте посмотрим на пользовательский интерфейс Marathon:
Как мы видим, наше приложение теперь отображается в пользовательском интерфейсе. Чтобы получить к нему доступ, нам просто нужно проверить, какой хост и порт ему назначены:
В этом случае порт 31143 был выделен случайным образом на локальном хосте, который будет внутренне сопоставлен с портом 8082 в нашем контейнере, как настроено в определении приложения. Затем мы можем посетить этот URL-адрес в нашем браузере, чтобы убедиться, что приложение обслуживается правильно.
8. Заключение
В этой статье мы создали простой конвейер непрерывной доставки с использованием Jenkins, Marathon и Mesos. Всякий раз, когда мы вносим изменения в наш код, он будет запущен в среде через несколько минут.
В последующих статьях этой серии будут рассмотрены более сложные темы Marathon, такие как проверка работоспособности приложений, масштабирование, аварийное переключение. Также могут быть рассмотрены другие варианты использования Mesos, такие как пакетная обработка.
Исходный код нашего приложения доступен на GitHub ; это проект Maven, который должен работать как есть.