В новой статье рассмотрим основы CI/CD и познакомимся Jenkins. Вы узнаете, где применяется Jenkins и какие проблемы помогает решить, поймёте логику архитектурных решений и особенности структуры каталогов. А ещё научитесь устанавливать Jenkins и производить базовую конфигурацию.
За основу статьи взят первый урок нашего практического курса «CI/CD с Jenkins».
![](https://habrastorage.org/getpro/habr/upload_files/c92/06d/e02/c9206de02955b02e64df3a4caab6ac7b.jpg)
CI/CD: что это такое и зачем нужно
Скорость разработки продуктов — одно из главных конкурентных преимуществ в разработке ПО. Поэтому на смену старым моделям программирования пришла новая концепция CI/CD.
CI (Continuous Integration) — непрерывная интеграция. Разработчики, применяющие данный паттерн, могут проверять основную ветку репозитория каждый раз, когда что-то замержили в неё. Не просто запускать локальные проверки, а в рамках CI-пайплайна выполнять автоматические тесты, unit-тесты и др.
CD, (Continuous Delivery) — непрерывная поставка. На этой стадии происходит автоматическое развертывание на стенды и тестовые окружения. Ещё CD расшифровывают как Continuous Deployment — непрерывное развёртывание. Это более продвинутый путь, на шаг дольше, чем непрерывная поставка. При таком подходе каждое изменение, которое мы коммитим в основную ветку репозитория, автоматически проходит все этапы CI и CD и затем попадает на продакшн.
![](https://habrastorage.org/getpro/habr/upload_files/49c/56f/1fe/49c56f1fe6d9fdff4718047e10d97de2.jpg)
Continuous Deployment Pipeline — высший пилотаж, который редко встречается на практике, потому что всегда есть определённые ограничения. Эти ограничения могут быть как в самом пайплайне, так и в бизнес-процессах с точки зрения безопасности. Но, однозначно, Continuous Deployment Pipeline — то, к чему нужно стремиться.
Цели CI/CD:
обеспечение последовательного и автоматизированного способа сборки, упаковки и тестирования;
автоматизация развёртывания в разных окружениях;
сведение к минимуму ошибок и проблем.
Добиться этих целей помогают четыре принципа, на которых основана концепция CI/CD. Первый принцип — разделение активности. Каждый из участников процесса делит ответственность за жизненные циклы продукта. Проектируется бизнес-логика, выбираются сквозные функции, проводятся тесты, организуется доставка кода из одного окружения в другое.
Второй принцип — снижение рисков. Чтобы баги не доходили до продакшена, контролируется корректность бизнес-логики, проверяется пользовательский опыт на стендах, улучшается процесс хранения и обработки данных. Чем раньше мы обнаружим риск, тем быстрее идентифицируем проблему и тем меньше средств потратим на её решение.
Третий принцип — сокращение цикла обратной связи. В рамках CI/CD мы стремимся увеличить скорость внесения изменений и согласования правок.
Четвертый принцип — реализация среды. У разработчиков должно быть общее пространство для работы с основной веткой или со вспомогательными ветками. Это пространство должно быть отказоустойчивым и удобным для работы.
Основные этапы CI/CD выглядят так:
![](https://habrastorage.org/getpro/habr/upload_files/b0f/b75/97e/b0fb7597e7c54a1fc316335def2d8bf5.png)
Планирование основывается на пользовательском опыте и бизнес-функционале. Обычно за этот этап отвечают люди из анализа: они переводят требования с языка бизнеса на язык, понятный разработчикам и администраторам. Затем начинается этап работы с кодом — разработчики пишут код, проводят тестирования в ручном режиме и добавляют изменения в основную ветку репозитория.
После того, как изменения попадают в репозиторий, система контроля версии инициирует сборку и тестирование проекта. Тестирование может быть как ручным, так и автоматическим — зависит от того, как работает команда. Далее всё уходит сначала на релиз, а затем на развёртывание. На этапе развёртывания уже протестированная версия приложения отправляется на продакшн и становится доступна пользователям.
Когда продукт попадает к пользователям, мы продолжаем следить за ним — этап поддержки и мониторинга. Мы контролируем, как пользователь идёт по бизнес-процессу, корректно ли работают интеграции. Если на стадии мониторинга мы обнаруживаем ошибку, возвращаемся к самому началу — к планированию. Аналитики разбирают, что пошло не так и предлагают новое решение, разработчики пишут код, и снова начинается процесс сборки.
Как и у любой методологии, у CI/CD есть свои плюсы и минусы:
Плюсы |
Минусы |
Минимальное время от запроса клиента до запуска в использование — мы быстрее доставляем новые фичи |
Сложность обеспечения взаимодействия — и DevOps-инженеры, и разработчики должны понимать, что было сделано и зачем |
Возможность проверки вариантов — можем моментально проверять изменения и при необходимости откатывать назад |
Требования к опыту — нужен опыт настройки CI/CD, который почти всегда добывается с болью |
Качество результата — можем быстро обнаружить и пофиксить ошибки |
Реализовать принципы CI/CD, свести к минимуму ошибки интеграции, а также ускорить релизы и повысить их качество помогает Jenkins.
Что такое Jenkins
Jenkins – не просто инструмент CI/CD. Это Framework, потому что он:
Гибок и расширяем. Jenkins — опенсорсный проект с множеством внешних расширений.
Минимален из коробки. У Jenkins есть контроллер. Вы можете подключить к нему несколько слоев и уже на этом сетапе собрать минимальный пайплайн, который позволит автоматизировать работу по обновлению сервисов.
Требует настройки. Jenkins — один из кубиков, с помощью которого можно построить большую систему автоматизации. Но прежде чем сделать что-то, его придётся настроить.
Jenkins — это Java-приложение. У него есть контроллер или Master Mode — управляющий центр, который занимается планированием задач. Он запускает задачи согласно установленному расписанию на слэйвах, которые вы к нему прикрепили. Помимо этого контроллер хранит логи наших задач. Вся история хранится только на Master Mode, поэтому важно помнить о настройке правильной ротации логов.
Слэйвы или агенты — это то, что непосредственно выполняет сами задания.
Коротко их взаимодействие можно описать так: контроллер запускает задачу и говорит агенту выполнить её, агент выполняет задачу и возвращает результат контроллеру. Контроллер получает результат и сохраняет его в build-логе.
![](https://habrastorage.org/getpro/habr/upload_files/de0/63e/7b7/de063e7b7e296e2f8bc62581d40476ff.png)
Установка Jenkins
Разберём, как установить Jenkins, как настроить параметры JVM и почему это важно. Дополнительно познакомимся с Jenkins Home: что это за зверь и с чем его едят. Все действия будем выполнять на Ubuntu.
Перед установкой Jenkins нужно установить Java — без этого никак. Мы проверяем, есть ли на нашем виртуальном энвайронменте Java:
root@vs01:~# java --version
По умолчанию из коробки Java нет:
![](https://habrastorage.org/getpro/habr/upload_files/7f8/e54/7a8/7f8e547a86a3fef626c818b254626747.png)
Рекомендуется использовать Java 11, потому что у неё более продвинутый Garbage Collector. Поставим её:
root@vs01:~# apt install openjdk-11-jre-headless
![](https://habrastorage.org/getpro/habr/upload_files/be2/29b/2b6/be229b2b6a2440c40a6653e7c21cecff.png)
Проверим, что Java установилась:
root@vs01:~# java --version
![](https://habrastorage.org/getpro/habr/upload_files/2c8/9ed/d06/2c89edd06074270d50bf499dc75f6f26.png)
Теперь нужно сконфигурировать файл limit.com. Но в Linux всё — файл, поэтому нужно установить фан-лимит, чтобы снять ограничения и позволить Jenkins генерировать файлы, дампы и др. Если не сделать этого, в каких-то случаях мы не сможем получить данные и понять, что же с Jenkins пошло не так.
Редактируем лимиты на Ubuntu:
root@vs01:~# vi/etс/security/limits.conf
![](https://habrastorage.org/getpro/habr/upload_files/c7d/3a5/873/c7d3a5873d19ce0ef0127ad8797095f8.png)
И добавляем секцию управления и устанавливаем права на различные лимиты: хардовые, софтовые, size-файлы и др:
![](https://habrastorage.org/getpro/habr/upload_files/a2a/380/ef5/a2a380ef5548c36c51313ee2f5e086ce.png)
Дальше нужно установить фаервол на Ubuntu:
root@vs01:~# apt-get install ufw
![](https://habrastorage.org/getpro/habr/upload_files/e69/eed/41c/e69eed41cf8180096205764decff3afa.png)
Обязательно разрешаем OpenSSH-порт, потому что больше не сможем подключиться к этой машине:
root@vs01:~# ufw allow OpenSSH
![](https://habrastorage.org/getpro/habr/upload_files/256/67f/8c7/25667f8c772e9db74e6ad9334c00dc45.png)
8080 — порт, по которому работает Jenkins.
root@vs01:~# ufw allow 8080
![](https://habrastorage.org/getpro/habr/upload_files/ada/6c3/b77/ada6c3b777e472fe03dc921dda7a175c.png)
Проверяем Jenkins репозиторий, потому что по умолчанию его нет в стоке Ubuntu:
root@vs01:~# wget -q -o – http://pkg.jenkins.io/Debian-stable/jenjins.io.key|sudo gpg --dearmor -o /usr/share/keyrings/Jenkins.gpg
После того, как скопировали ключи, устанавливаем Jenkins в sources list:
![](https://habrastorage.org/getpro/habr/upload_files/449/7ea/661/4497ea6614d42a1a49db45ebfa4dd6a5.png)
Важно для Ubuntu делать apt-get update:
root@vs01:~# apt-get update -y
![](https://habrastorage.org/getpro/habr/upload_files/0f6/aa0/bd0/0f6aa0bd0e69465cf3e63f2f014c21ae.png)
Теперь можем поставить Jenkins:
root@vs01:~# apt-get install Jenkins -y
![](https://habrastorage.org/getpro/habr/upload_files/537/ef7/2c0/537ef72c02d3a6a11050f416fe9fdb7a.png)
Установка проходит довольно быстро. Если посмотреть верхнеуровнево, то Jenkins — это war-файл. И вы можете не устанавливать его в систему через system, а просто скачать war-файл и запускать через war.
Мы можем посмотреть статус Jenkins App:
root@vs01:~# systemctl status jenkins
![](https://habrastorage.org/getpro/habr/upload_files/5d1/a52/e77/5d1a52e77d3e2c0b94f83a4e35b4920b.png)
Он активный, но нам этого недостаточно. Jenkins — это Java, а Java очень требовательно относится к памяти. Поэтому дальше поговорим про Garbage Collector — службу, которая очищает память от неиспользованных объектов.
Мы немного «подтюним» Java-машину и добавим опции в файл etc systemd/system/jenkins.service:
root@vs01:~# vi /lib/systemd/system/Jenkins.service
Найдём Java OPTS:
![](https://habrastorage.org/getpro/habr/upload_files/717/52a/484/71752a4846ce435f0297747010b0f0c9.png)
Добавим больше опций:
![](https://habrastorage.org/getpro/habr/upload_files/86a/ba5/fda/86aba5fdaf7ba73cbe7d593ff74b6a82.png)
Обратите внимание, что в настройках мы указываем Xmx512m и Xms512 — размер оперативной памяти, который выделяем Java-машине для работы. Вообще размер зависит от количества доступной памяти в операционной системе и корректируется в соответствии с ней. По рекомендациям Cloud Business и личному опыту, нужно ставить не больше 16 гигабайт на hip size. Но при этом важно не забывать, что у вас есть Meta Space и система, которые тоже занимают память. Если у вас на машине 20 гигабайт памяти, смело можно ставить 16. Если у вас всего 18 гигабайт памяти, и вы выделяете 16 гигабайт под Jenkins и Java, не удивляйтесь, когда машина начнёт работать плохо, а в какой-то момент просто умрёт.
Здесь выставляем Garbage Collector — UseG1GC:
![](https://habrastorage.org/getpro/habr/upload_files/991/07e/004/99107e004034824fbda806dde543af78.png)
И добавляем снятие автоматического дампа при out of memory:
![](https://habrastorage.org/getpro/habr/upload_files/b6d/422/11a/b6d42211aa0c31dd79f3436d1b335618.png)
Это полезная опция, когда Jenkins падает. Конечно, падения все равно будут случаться — мы не всегда можем рассчитать нагрузку и определить, сколько потребуется памяти для работы. Но параметр поможет понять, что произошло.
Также в Garbage Collector выставляем лог — /var/lib/jenkins/gc.log:
![](https://habrastorage.org/getpro/habr/upload_files/353/484/1c5/3534841c5bb780bf178c2eace2d9d1a3.png)
Сохраняем.
Нужно перезагрузить Jenkins, но перед этим сделать daemon-reload:
root@vs01:~# systemctl daemon-reload
root@vs01:~# systemctl restart Jenkins
Проверим:
root@vs01:~# systemctl status Jenkins
![](https://habrastorage.org/getpro/habr/upload_files/557/223/6fb/5572236fbb3f5771899bd270b8e87844.png)
oot@vs01:~# cat /proc/http://Jenkins.s043218.edu.slurm.io^C
root@vs01:~# cat /proc/67043/cmdline
Видим, что Java настроена как раз под те опции, что мы ей передали, и запускается Jenkins war:
![](https://habrastorage.org/getpro/habr/upload_files/532/22f/4e5/53222f4e55f7804af8384dbfc08e9693.png)
Теперь откроем веб-интерфейс http://jenkins.s043218.edu.slurm.io. Он предлагает разблокировать Jenkins:
![](https://habrastorage.org/getpro/habr/upload_files/f49/da9/de4/f49da9de42b00c6dd07d852fcd824bd4.png)
То есть первоначальная установка предполагает, что вы введете некий мастер-пароль. Jenkins сам подсказывает, где этот мастер-пароль можно найти — var/lib/jenkins/secret/initialAdminPassword. Давайте пойдём туда и посмотрим:
root@vs01:~# cd var/lib/jenkins/
![](https://habrastorage.org/getpro/habr/upload_files/efb/deb/446/efbdeb4468c9eb418ef4a8992a557052.png)
root@vs01:/var/lib/jenkins/# cd secrets/
root@vs01:/var/lib/jenkins/secrets# ls -al
![](https://habrastorage.org/getpro/habr/upload_files/f36/53e/f0c/f3653ef0c79b2c25f09c791b492d74bb.png)
Initial password — пароль, который вы можете использовать один раз при первой установке Jenkins. После вы переключитесь на внутреннюю базу авторизации.
![](https://habrastorage.org/getpro/habr/upload_files/463/ade/14b/463ade14b2836983becfa864861c255e.png)
![](https://habrastorage.org/getpro/habr/upload_files/e48/2a9/a5f/e482a9a5f2a9a4740a44d21dc8dcc542.png)
Следующий шаг — установить Suggested-плагины или самостоятельно выбрать плагины, которые хотите поставить.
![](https://habrastorage.org/getpro/habr/upload_files/90c/49d/69d/90c49d69d7404b96f58d531423249c2c.png)
Список плагинов, которые используются в Suggested, достаточно правильный, поэтому рекомендуется просто поставить эти плагины автоматом.
![](https://habrastorage.org/getpro/habr/upload_files/e1f/7cb/d86/e1f7cbd86de6982c413ccfd7d1f57c04.png)
А пока Jenkins делает плагины, посмотрим на Home-директорию:
root@vs01:/var/lib/jenkins/secrets# cd ..
root@vs01:/var/lib/jenkins# ls -la
У Jenkins нет выделенной базы, как у некоторых систем. В качестве базы данных он использует директорию Jenkins Home, которая есть в каталоге файловой системы того сервера, на который выставили контролер. Здесь хранятся: конфиги, плагины, задания, которые мы делаем и всё, что связано с ними и т.д.
![](https://habrastorage.org/getpro/habr/upload_files/62d/b37/9cb/62db379cbd0cdacc0ff37949ad3a6218.png)
Вернёмся к Jenkins — он уже поставил домен и предлагает нам настроить первого пользователя. Заполним поля:
![](https://habrastorage.org/getpro/habr/upload_files/6f0/9c3/d78/6f09c3d78c73fa2cf3e022b20af5ddfe.png)
Далее Jenkins предлагает настроить URL:
![](https://habrastorage.org/getpro/habr/upload_files/799/154/e39/799154e39a66644f0f4f3d5f58893002.png)
Этот параметр достаточно важный, потому что его параметр будут использовать различные слэйвы для автоматического коннекта к мастеру.
![](https://habrastorage.org/getpro/habr/upload_files/91e/33a/68e/91e33a68e31f8f82cbbe85f2658501f9.png)
Итак, мы поставили Jenkins. Пока нет никаких заданий, но мы можем немного пройтись по Manage Jenkins:
![](https://habrastorage.org/getpro/habr/upload_files/e01/b4a/643/e01b4a64354bdbe1739cbbe720d843c4.png)
Из наиболее интересного здесь:
System information — хранит всю основную информацию (Java Home, версия Java, версия Ubuntu и т.д.).
System log — то, куда нужно смотреть, если непонятно, почему не подключается агент или не работает скрип.
Load statistics — показывает, сколько экзекьюторов всего онлайн.
На этом всё. В рамках первого урока мы повторили цели CI/CD, узнали, что такое Jenkins и рассмотрели область его применения. Ещё попробовали самостоятельно установить Jenkins на Ubuntu-сервер и познакомились с содержимым Jenkins Home. В следующих уроках подробно разберём администрирование Jenkins, научимся настраивать интеграции, создавать конфигурации Jenkins As a Code и многое другое.
vdp
Выглядит как реклама своего курса.
Описали уже множество раз расписанный этап.
А почему не показали более простой способ из докера?
И что с двухфакторной аутентификацией — ну хоть какие-то современные фишки добавьте.
Про плугины пол-слова — это ужасно вредная статья!
saboteur_kiev
Более простой это не из докера.
Более простой - это создать юзера дженкинс, скачать jenkins.jar и запустить.
ВСЕ.
Что же касается
Это немного бредово звучит.
Есть РАЗНЫЕ продукты, у разных продуктов может быть свой жизненный цикл. И стремиться во всех продуктах именно к Continuous Deployment, будет то, что MS пытается сделать с Windows. Нравится? Думаю не очень.
Areso
Слушайте, всегда можно найти крайности.
Во-первых, есть тестовые среды, куда CD имеет смысл. Там же и тесты гонять
Во-вторых, есть бета-программы. Они есть и у ОС, и у IDE, и у тому подобного. Где пользователи готовы и получают самое свежое, но нестабильное.
В-третьих, есть плавные запуски новых фич и новых продуктов.
Короче, CD не плохо, плохо - безответственный подход с любым процессом разработки и релиза.