Как сделать Jenkins стабильным и сэкономить время, деньги и нервы

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

От любой системы, которую внедряем в проект, мы ждём стабильной работы. 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

Источник: https://habr.com/ru/company/southbridge/blog/694144/


Интересные статьи

Интересные статьи

В данной статье мы рассмотрим систему аутентификации пользователей и внешних систем в личном кабинете через сервер аутентификации Blitz Identity Provider. Согласно требованиям проекта, который мы...
Автор этого туториала сосредоточился на анимации. Он использовал хуки библиотеки React, её Context API, а также TypeScript и LESS. В конце вы найдёте ссылки на игру, её код и демо анимаций. Подробност...
Новое это давно забытое старое... История о том как случайно получилось найти супер способ передать параметры в независимый javascript виджет. GET параметры? Нет кое-что получше.
В наши дни понятие «DevOps» у всех на слуху. Это — организационный подход, широко используемый для ускорения разработки и развёртывания приложений. Организации внедряют у себя практики De...
Эта статья посвящена одному из способов сделать в 1с-Битрикс форму в всплывающем окне. Достоинства метода: - можно использовать любые формы 1с-Битрикс, которые выводятся компонентом. Например, добавле...