Основы CI/CD. Знакомство с Jenkins

Kate

Administrator
Команда форума

CI/CD: что это такое и зачем нужно​

Скорость разработки продуктов — одно из главных конкурентных преимуществ в разработке ПО. Поэтому на смену старым моделям программирования пришла новая концепция CI/CD.

CI (Continuous Integration) — непрерывная интеграция. Разработчики, применяющие данный паттерн, могут проверять основную ветку репозитория каждый раз, когда что-то замержили в неё. Не просто запускать локальные проверки, а в рамках CI-пайплайна выполнять автоматические тесты, unit-тесты и др.

CD, (Continuous Delivery) — непрерывная поставка. На этой стадии происходит автоматическое развертывание на стенды и тестовые окружения. Ещё CD расшифровывают как Continuous Deployment — непрерывное развёртывание. Это более продвинутый путь, на шаг дольше, чем непрерывная поставка. При таком подходе каждое изменение, которое мы коммитим в основную ветку репозитория, автоматически проходит все этапы CI и CD и затем попадает на продакшн.


Continuous Deployment Pipeline — высший пилотаж, который редко встречается на практике, потому что всегда есть определённые ограничения. Эти ограничения могут быть как в самом пайплайне, так и в бизнес-процессах с точки зрения безопасности. Но, однозначно, Continuous Deployment Pipeline — то, к чему нужно стремиться.

Цели CI/CD:

  • обеспечение последовательного и автоматизированного способа сборки, упаковки и тестирования;
  • автоматизация развёртывания в разных окружениях;
  • сведение к минимуму ошибок и проблем.
Добиться этих целей помогают четыре принципа, на которых основана концепция CI/CD. Первый принцип — разделение активности. Каждый из участников процесса делит ответственность за жизненные циклы продукта. Проектируется бизнес-логика, выбираются сквозные функции, проводятся тесты, организуется доставка кода из одного окружения в другое.

Второй принцип — снижение рисков. Чтобы баги не доходили до продакшена, контролируется корректность бизнес-логики, проверяется пользовательский опыт на стендах, улучшается процесс хранения и обработки данных. Чем раньше мы обнаружим риск, тем быстрее идентифицируем проблему и тем меньше средств потратим на её решение.

Третий принцип — сокращение цикла обратной связи. В рамках CI/CD мы стремимся увеличить скорость внесения изменений и согласования правок.

Четвертый принцип — реализация среды. У разработчиков должно быть общее пространство для работы с основной веткой или со вспомогательными ветками. Это пространство должно быть отказоустойчивым и удобным для работы.

Основные этапы CI/CD выглядят так:

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-логе.

de063e7b7e296e2f8bc62581d40476ff.png

Установка Jenkins​

Разберём, как установить Jenkins, как настроить параметры JVM и почему это важно. Дополнительно познакомимся с Jenkins Home: что это за зверь и с чем его едят. Все действия будем выполнять на Ubuntu.

Перед установкой Jenkins нужно установить Java — без этого никак. Мы проверяем, есть ли на нашем виртуальном энвайронменте Java:

root@vs01:~# java --version
По умолчанию из коробки Java нет:

7f8e547a86a3fef626c818b254626747.png

Рекомендуется использовать Java 11, потому что у неё более продвинутый Garbage Collector. Поставим её:

root@vs01:~# apt install openjdk-11-jre-headless
be229b2b6a2440c40a6653e7c21cecff.png

Проверим, что Java установилась:

root@vs01:~# java --version
2c89edd06074270d50bf499dc75f6f26.png

Теперь нужно сконфигурировать файл limit.com. Но в Linux всё — файл, поэтому нужно установить фан-лимит, чтобы снять ограничения и позволить Jenkins генерировать файлы, дампы и др. Если не сделать этого, в каких-то случаях мы не сможем получить данные и понять, что же с Jenkins пошло не так.

Редактируем лимиты на Ubuntu:

root@vs01:~# vi/etс/security/limits.conf
c7d3a5873d19ce0ef0127ad8797095f8.png

И добавляем секцию управления и устанавливаем права на различные лимиты: хардовые, софтовые, size-файлы и др:

a2a380ef5548c36c51313ee2f5e086ce.png

Дальше нужно установить фаервол на Ubuntu:

root@vs01:~# apt-get install ufw
e69eed41cf8180096205764decff3afa.png

Обязательно разрешаем OpenSSH-порт, потому что больше не сможем подключиться к этой машине:

root@vs01:~# ufw allow OpenSSH


25667f8c772e9db74e6ad9334c00dc45.png

8080 — порт, по которому работает Jenkins.

root@vs01:~# ufw allow 8080
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:

4497ea6614d42a1a49db45ebfa4dd6a5.png

Важно для Ubuntu делать apt-get update:

root@vs01:~# apt-get update -y
0f6aa0bd0e69465cf3e63f2f014c21ae.png

Теперь можем поставить Jenkins:

root@vs01:~# apt-get install Jenkins -y
537ef72c02d3a6a11050f416fe9fdb7a.png

Установка проходит довольно быстро. Если посмотреть верхнеуровнево, то Jenkins — это war-файл. И вы можете не устанавливать его в систему через system, а просто скачать war-файл и запускать через war.

Мы можем посмотреть статус Jenkins App:

root@vs01:~# systemctl status jenkins
5d1a52e77d3e2c0b94f83a4e35b4920b.png

Он активный, но нам этого недостаточно. Jenkins — это Java, а Java очень требовательно относится к памяти. Поэтому дальше поговорим про Garbage Collector — службу, которая очищает память от неиспользованных объектов.

Мы немного «подтюним» Java-машину и добавим опции в файл etc systemd/system/jenkins.service:

root@vs01:~# vi /lib/systemd/system/Jenkins.service
Найдём Java OPTS:

71752a4846ce435f0297747010b0f0c9.png

Добавим больше опций:

86aba5fdaf7ba73cbe7d593ff74b6a82.png

Обратите внимание, что в настройках мы указываем Xmx512m и Xms512 — размер оперативной памяти, который выделяем Java-машине для работы. Вообще размер зависит от количества доступной памяти в операционной системе и корректируется в соответствии с ней. По рекомендациям Cloud Business и личному опыту, нужно ставить не больше 16 гигабайт на hip size. Но при этом важно не забывать, что у вас есть Meta Space и система, которые тоже занимают память. Если у вас на машине 20 гигабайт памяти, смело можно ставить 16. Если у вас всего 18 гигабайт памяти, и вы выделяете 16 гигабайт под Jenkins и Java, не удивляйтесь, когда машина начнёт работать плохо, а в какой-то момент просто умрёт.

Здесь выставляем Garbage Collector — UseG1GC:

99107e004034824fbda806dde543af78.png

И добавляем снятие автоматического дампа при out of memory:

b6d42211aa0c31dd79f3436d1b335618.png

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

Также в Garbage Collector выставляем лог — /var/lib/jenkins/gc.log:

3534841c5bb780bf178c2eace2d9d1a3.png

Сохраняем.

Нужно перезагрузить Jenkins, но перед этим сделать daemon-reload:

root@vs01:~# systemctl daemon-reload
root@vs01:~# systemctl restart Jenkins
Проверим:

root@vs01:~# systemctl status Jenkins
5572236fbb3f5771899bd270b8e87844.png
oot@vs01:~# cat /proc/http://Jenkins.s043218.edu.slurm.io^C
root@vs01:~# cat /proc/67043/cmdline
Видим, что Java настроена как раз под те опции, что мы ей передали, и запускается Jenkins war:

53222f4e55f7804af8384dbfc08e9693.png

Теперь откроем веб-интерфейс http://jenkins.s043218.edu.slurm.io. Он предлагает разблокировать Jenkins:

f49da9de42b00c6dd07d852fcd824bd4.png

То есть первоначальная установка предполагает, что вы введете некий мастер-пароль. Jenkins сам подсказывает, где этот мастер-пароль можно найти — var/lib/jenkins/secret/initialAdminPassword. Давайте пойдём туда и посмотрим:

root@vs01:~# cd var/lib/jenkins/
efbdeb4468c9eb418ef4a8992a557052.png
root@vs01:/var/lib/jenkins/# cd secrets/
root@vs01:/var/lib/jenkins/secrets# ls -al
f3653ef0c79b2c25f09c791b492d74bb.png

Initial password — пароль, который вы можете использовать один раз при первой установке Jenkins. После вы переключитесь на внутреннюю базу авторизации.

463ade14b2836983becfa864861c255e.png
e482a9a5f2a9a4740a44d21dc8dcc542.png

Следующий шаг — установить Suggested-плагины или самостоятельно выбрать плагины, которые хотите поставить.

90c49d69d7404b96f58d531423249c2c.png

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

e1f7cbd86de6982c413ccfd7d1f57c04.png

А пока Jenkins делает плагины, посмотрим на Home-директорию:

root@vs01:/var/lib/jenkins/secrets# cd ..
root@vs01:/var/lib/jenkins# ls -la
У Jenkins нет выделенной базы, как у некоторых систем. В качестве базы данных он использует директорию Jenkins Home, которая есть в каталоге файловой системы того сервера, на который выставили контролер. Здесь хранятся: конфиги, плагины, задания, которые мы делаем и всё, что связано с ними и т.д.

62db379cbd0cdacc0ff37949ad3a6218.png

Вернёмся к Jenkins — он уже поставил домен и предлагает нам настроить первого пользователя. Заполним поля:

6f09c3d78c73fa2cf3e022b20af5ddfe.png

Далее Jenkins предлагает настроить URL:

799154e39a66644f0f4f3d5f58893002.png

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

91e33a68e31f8f82cbbe85f2658501f9.png

Итак, мы поставили Jenkins. Пока нет никаких заданий, но мы можем немного пройтись по Manage Jenkins:

e01b4a64354bdbe1739cbbe720d843c4.png

Из наиболее интересного здесь:

  • System information — хранит всю основную информацию (Java Home, версия Java, версия Ubuntu и т.д.).
  • System log — то, куда нужно смотреть, если непонятно, почему не подключается агент или не работает скрип.
  • Load statistics — показывает, сколько экзекьюторов всего онлайн.
На этом всё. В рамках первого урока мы повторили цели CI/CD, узнали, что такое Jenkins и рассмотрели область его применения. Ещё попробовали самостоятельно установить Jenkins на Ubuntu-сервер и познакомились с содержимым Jenkins Home. В следующих уроках подробно разберём администрирование Jenkins, научимся настраивать интеграции, создавать конфигурации Jenkins As a Code и многое другое.

 
Сверху