От любой системы, которую внедряем в проект, мы ждём стабильной работы. Jenkins не исключение. Когда мы выбираем его в качестве инструмента CI/CD, он начинает напрямую влиять на time to market приложения и, соответственно, на деньги, которые может заработать компания. В случае сбоя Jenkins мы получаем влияние не только на команду разработки, но и на бизнес. Чтобы минимизировать риски, необходимо правильно настроить инструмент. В статье рассказываем о best practice, которые должен знать каждый администратор Jenkins.
Статья основана на нашем вебинаре «Как сделать Jenkins стабильным и сэкономить время, деньги и нервы». На нём Кирилл Борисов, Infrastructure Engineer технологического центра Deutsche Bank, разбирал самые распространенные ошибки администрирования Jenkins, и рассказывал, как избежать проблем на ранних этапах.
Медленный и «не отвечающий» Jenkins
Большая часть претензий к Jenkins заключается в том, что он медленный. А иногда перестает отвечать на вопросы, когда вы пытаетесь залогиниться.
Основные факторы, влияющие на работу Jenkins:
Garbage Collection. Поскольку Jenkins — это Java Application, его производительность во многом зависит от правильно настроенного Garbage Collection.
Polling. В Jenkins есть возможность запуска пайплайна по триггеру. Пайплайн опрашивает систему контроля версий по заданному интервалу и, если находит изменения в коде, запускает пайплайн. Триггер, настроенный на большом количестве пайплайнов, сильно влияет на производительность Jenkins. Оптимально здесь использовать webhook — вы можете настроить его на события по push в основную ветку или создать URL, на который будете отправлять запросы и по этому событию будут запускать Java.
Конфигурация и неправильные JVM-аргументы. Необходимо следовать best practice по по настройке Jenkins и быть внимательным, потому что на разных версиях Java аргументы выглядят по разному.
Некорректные pipeline. Избегайте использования мастер ноды для исполнения пайплайнов. Её работа состоит в менеджменте ваших заданий, для всего остального есть агенты. Не забывайте, что весь groovy-код, который вы пишете в пайплайнах, они исполняют на мастере в любом случае. Старайтесь использовать утилиты в командной строке — URL или GG. Такие команды выполняются непосредственно на агентах и никак не влияют мастер.
Медленная файловая система. У Jenkins нет выделенной базы данных. Конфигурация, история, описание задач — всё лежит на диске в JENKINS_HOME директории. Поэтому рекомендуется использовать более быстрые диски. Или использовать сетевое файловое хранилище NFS версии 3.0 или 4.1.
Плагины — то, что должно упростить работу с Jenkins, но с чем нужно быть осторожнее. Совет Капитана: используйте плагины только в том случае, когда без них совсем не обойтись. Если вы можете работать без них, отдайте предпочтение groovy-коду.
Мониторинг и метрики
Первое, о чём стоит задуматься после установки Jenkins, — это мониторинг. Его нужно настроить, чтобы вы понимали, как приложение чувствует себя здесь и сейчас, а не узнавали о сбоях из отзывов пользователей или от разработчиков.
При настройке мониторинга важно учитывать, что существуют два типа метрик. Первый тип — макрометрики: Application Response Time, CPU Utilization, Memory Usage. Они на верхнем показывают, что происходит, но не позволяют провести глубокое исследование. Понять, как чувствует себя Jenkins, помогут на микрометрики: Object Creation Rate, GC Latency, GC Throughput, Thread Count&State и Open File Descriptor.
Для отслеживания метрик вы можете использовать:
Jenkins Metrics — Jenkins metric Plugin;
Zabbix Integration — Интеграция с Zabbix;
Monitoring Plugin — Jenkins native monitoring plugin;
Jenkins Prometheus — Jenkins Prometheus integration;
Grafana Dashboard — Jenkins Grafana dashboard.
Сборка мусора — что это и почему важно для Jenkins?
Для работы любого приложения требуется память. Однако память компьютера ограничена, поэтому важно очищать её о старых неиспользуемых данных. Так выглядит структура памяти Java:
У нас есть Native Memory — вся доступная память в системе.
Heap Size, которую в русскоязычном комьюнити прозвали «куча», — часть Native Memory. Это общее пространство для потоков приложения, где Java хранит все свои объекты. Размер этой области настраивается с помощью параметров в Xms на минимальные размеры, в Xmx на максимальные.
Stack — место для хранения локальных переменных. Для каждого потока выделяется свой Stack.
Metaspace — метаданные. В этой части хранятся данные метакласса и статистические переменные. Важно помнить, что это пространство является общим для всех, поскольку Metaspace входит NativeMemory. Верхний предел объема памяти, используемый для Metaspace, можно выставить с помощью флага max metaspace size.
Что же такое мусор? Мусором считается объект, который больше не может быть достигнут по ссылке из какого-либо объекта, поскольку такой объект больше не используется в приложении. Соответственно, сборка мусора — процесс автоматического управления памятью, который выполняется специальным компонентом Garbage Collector.
Как работает Garbage Collector:
Для сборки мусора он используется процесс Mark&Sweep, который состоит из нескольких этапов. Первый этап — Mark. Garbage Collector сканирует все объекты и помечает живые — те, которые все еще используются в памяти. Далее программа останавливается — этот этап называется Stop the world. Затем идёт этап очистки — Sweeping. Объекты, которые не были отмечены на предыдущем шаге, удаляются из памяти. И последний этап — Compaction. На нем объекты, пережившие очистку перемещаются в единый непрерывный блок памяти. Это уменьшает фрагментацию Heap и позволяет быстрее размещать новые объекты.
Как не стать заложником проблемы Out Of Memory и низкой пропускной способности
Не стоит игнорировать рекомендации, которые Jenkins предлагает для Java. Вот основные из них:
Минимальный размер Heap — -Xms = 2Gb, для production 4GB.
Максимальный размер Heap — -Xmx = 16 Gb. Часто возникает вопрос: почему именно 16, можем ли мы взять больше? Технически можем. Но стоит помнить, что при увеличении размера Heap, мы увеличиваем размер Metaspace. Плюс, чем больше максимальный размер Heap, тем дольше Garbage Collector чистит память.
Тип Garbage Collection — -G1GC (по умолчанию ParallelGC). Не забывайте выставлять G1, потому что он помогает Jenkins: работает параллельно с приложением и используется, когда время отклика важнее пропускной способности.
Включение логирования GC. Не забывайте включать логирование Garbage Collector, чтобы понимать, что с ним происходит.
Опция HeapDumpOnOutOfMemoryError. Для автоматического снятия Dump при Out Of Memory.
Другие рекомендации:
Prepare Jenkins — подготовка Jenkins;
JVM Troubleshooting — поиск проблем с JVM;
GC Running — кейс с тюнингом GC.
Saw-tooth pattern — паттерн saw-tooth.
Контроль изменений
Еще одна проблема, с которой можно столкнуться при больших инсталляциях, — контроль изменений. Когда у вас один большой Jenkins, который используется несколькими командами, зачастую возникают сложности в коммуникациях. Например, одна команда обновила плагин, не дождавшись подтверждения другой. Или команда информационной безопасности заблокировала порт на порты на firewall.
Рекомендации:
Не делайте больше одного изменения за единицу времени. Тогда в случае возникшей проблемы вы всегда будете знать, что конкретно ее спровоцировало.
Наладьте коммуникацию между командами. Создайте подобие чейнджлога, а если у вас большой Jenkins — отдельную Wiki-страничку.
Используйте плагины, помогающие понять, какое изменение вызвало поломку. Плагин Audit Trail фиксирует все изменения Jenkins, которые совершают пользователи. Плагин Job Configuration Historyсохраняет изменения прошлых конфигураций пайплайнов и показывает, кто и что менял.
Резервное копирование
Еще одна проблема, с которой не хочется сталкиваться, — отсутствие бэкапов или их наличие в поврежденном виде. Важно не просто делать резервные копии, но и тестировать их на корректность.
Для создания резервных копий вы можете использовать:
Backup Up — backup best practice;
Thin Backup — плагин;
Backup Plugin — плагин.
Обязательно проверяйте вашу резервную копию один-два раза в месяц в зависимости от критичности инстанса.
Горизонтальное масштабирование
И основная проблема: как понять, что Jenkins нужно масштабировать и нужно ли масштабировать мастер. Чтобы решите её, ответьте на два вопроса:
Есть ли у вас ресурсы для обслуживания нескольких контроллеров? Не забывайте, что Jenkins требует обновлений плагинов и ядра, регулярного резервного копирования.
Какие проекты важны для вашей команды? Если есть проекты, более критичные, чем остальные, выделите их в отдельные мастера, чтобы свести к минимуму влияние отключенного Jenkins-мастера.
Рекомендации:
Старайтесь не использовать Freestyle задания. Если в какой-то момент у вас умрет мастер, все Freestyle задания перестанут выполняться. В то же время декларативные или скриптовые пайплайны продолжат выполняться даже при потере соединения агента с контроллером.
Подумайте, насколько для вас важен быстрый запуск вашего экземпляра Jenkins. Чем больше заданий настроено, тем больше времени потребуется для загрузки Jenkins после обновления или сбоя.
Используйте папки для организации заданий. Они ограничат количество заданий, которые необходимо отобразить сразу при запуске, поэтому старт контроллера будет быстрее.
Следите метриками мониторингов файловой системы и дисковой подсистемы. Если понимаете, что диск не справляется с текущим количеством пайплайнов и джобов, настроенных на мастере, подумайте о его масштабировании.
Избегайте больших мастеров. Старайтесь дробить Jenkins по сегментам.
Не забывайте про правило «не больше 16Gb Heap». Чем больше памяти вы выделяете для Heap, тем дольше Garbage Collector придётся работать, и тем дольше процесс Stop The World.
Коротко о главном
Что вы можете сделать прямо сейчас:
Настроить ротацию джобов. На практике про это часто забывают, из-за чего получают огромное количество файлов на Jenkins Home. Обычно хватает двух-трёх недель хранения. Если же вам нужно хранить дольше, например, чтобы доказать, что какой-то пайплайн исполнялся год, рассмотрите вариант выгрузки ваших логов заданий в артефакт для долгосрочного хранения. Это отличный способ избежать переполнения мастера и сохранить все ваши задания.
Избегать использования больших мастеров. Разделяйте Jenkins по сегментам, выбирайте JDK, а не JRE, потому что JDK предоставляет вам больше инструментов для работы с памятью и её траблшутинга. Если есть возможность использовать SSD-диски, старайтесь работать с NFC версии 3, 3.3, 4.1.
Включить логирование Garbage Collector. В случае возникновения проблем вы всегда сможете понять, что происходит.
Не забывайте про Heap Size. По умолчанию в Java нет никаких опций — установите их. Это позволит вашему Jenkins работать более стабильно.
Следите за показателями макро- микрометрик. Вы должны понимать, как ведёт себя система, а не ждать, когда же придёт злой пользователь.
Используйте best practice для написания пайплайнов. Pipeline Code — best practices от Jenkins, Top 10 — Top 10 Best Practice, Best Practice Overview
И главная рекомендация — где возможно используйте bash-скрипты вместо groovy-методов, потому что они исполняются не на мастер ноде, а на агентах.
Для тех, кто хочет углубить знания в Jenkins
Кирилл Борисов — не только спикер наших вебинаров, но и автор курса «CI/CD с Jenkins». В нём он делится личным опытом работы с Jenkins, разбирает конкретные кейсы, а ещё помогает не совершить распространённых ошибок.
На курсе вы научитесь автоматизировать процесс интеграции и поставки, сможете ускорить цикл разработки и пройдёте путь от настройки первого плагина до Jenkins as code и внедрения в Kubernetes.
Посмотреть программу и записаться: https://slurm.club/3TotHtG
Комментарии (9)
dburmistrov
19.10.2022 09:33+5Ядро дженкинса с плагинами паковать в war или имидж. Конфигурацию - в jcasc. Джобы - в Jenkinsfile/job-dsl/jjb/jte. Артефакты и логи - во внешнее хранилищие. На историю билдов не полагаться.
Если следовать этим требованиям, то бэкап не нужен. Новый инстанс поднимается с нуля за минуты.onix74
19.10.2022 09:51А я бы почитал статью на эту тему. Не планируете?
dburmistrov
19.10.2022 13:45Увы, талантами техписателя не обладаю. Да и без меня эти темы раскрыты в достаточной мере. Разве что по jenkins-job-builder статей мало. Не слишком он популярен.
onix74
19.10.2022 09:48+1Это какой-то корявый перевод или просто слабая статья?
Необходимо следовать best practice по по настройке Jenkins
А ссылок нет?
Старайтесь использовать утилиты в командной строке — URL или GG
Это что за утилиты, можно подробнее?
Избегайте использования мастер ноды для исполнения пайплайнов
...
весь groovy-код, который вы пишете в пайплайнах, они исполняют на мастере в любом случае
...
Если вы можете работать без них, отдайте предпочтение groovy-коду.
И тем самым возложить всё на мастер-ноду, использование которой рекомендуется избегать?
Если есть возможность использовать SSD-диски, старайтесь работать с NFC версии 3, 3.3, 4.1.
А если у меня HDD, то я могу работать с NFC v2 и ниже или мне нужно использовать NFC v5 и выше?
silabeer
19.10.2022 13:46А ссылок нет?
Prepare Jenkins — подготовка Jenkins
Это что за утилиты, можно подробнее?
curl и wget, например вместо HttpURLConnection
И тем самым возложить всё на мастер-ноду, использование которой рекомендуется избегать?
Как показала практика, иногда оптимальнее использовать свой groovy код, чем плагин
А если у меня HDD, то я могу работать с NFC v2 и ниже или мне нужно использовать NFC v5 и выше?
Ребята из cloudbees рекомендуют использовать NFC 4.1 и выше
onix74
19.10.2022 14:02Т.е. вопросы не были услышаны?
Подготовка Jenkins и best practice — не одно и то же, с моей точки зрения. Первое — это то, что нужно сделать, чтобы запустить, инструкция по разворачиванию сервиса. Второе — это рекомендации, выявленные в процессе эксплуатации, которые могут легко расходиться с рекомендациями по установке.
Если пишете про "утилиты в командной строке", то пишите примеры утилит, а не невнятное "URL и GG" (Что такое GG?)
Про groovy. Противоречий в ваших советах не видите? Избегайте использовать мастер-ноду, но используйте groovy, который всегда выполняется на мастер-ноде...
Про диск тоже не поняли, видимо. У вас сказано, что " Если есть возможность использовать SSD-диски, старайтесь работать с NFC версии 3, 3.3, 4.1.". А если нет возможности использовать SSD? Как вообще связаны версии NFS (а не NFC, всё-таки, видимо) и тип диска. Ну а если вы реально NFC имели ввиду, то я тогда вообще ничего не понимаю.amakhrov
20.10.2022 20:26Совет использовать груви-код был в контексте использования плагинов, которые тоже на груви и тоже будут выполняться на мастер ноде. Разница здесь между чужим глючным груви кодом (плагин) и своим глючным груви кодом (в котором проще копаться и починить)
BoldDwarf
19.10.2022 16:48Немного про то, что Дженкинс требует регулярного обновления плагинов и ядра.
Как человек, который лично видел что конкретно может сделать подобное обновление я бы посоветовал следующее.
Обновляйте Дженкинс и в особенности его плагины только если вы абсолютно уверены что это действительно вам нужно.
И даже если вами это действительно нужно, то никогда не делайте это на проде без предварительной и качественной проверки в тестовом окружении.
dyadyaSerezha
Что значит, проверяйте? Как?