
Практика CI/CD широко распространена в современном мире и представить ручной деплой у FAANG с их бесчисленными ежедневными изменениями просто невозможно. То же будет справедливо и для продуктовых компаний: десятки ручных деплоев в день вытянуть можно, но это потребует колоссальных ресурсов.
Освоить эту практику можно дома, в среде, где что-то сломать не страшно, ведь всегда можно начать все с самого начала. В этом гайде рассмотрим как развернуть и настроить Jenkins в Docker, как создать агента для сборки, а еще запушим образ в приватный Nexus.
Предпосылки и подготовительные работы
На этом этапе у вас уже должен быть установлен Docker for Windows, с настройкой под Linux-контейнеры и включен WSL 2 в Windows Features. Либо Linux/macOS с установленным Docker. Гайдов как это настроить достаточно много и найти их не сложно, поэтому первичная настройка Docker и WSL в этой статье описана не будет. У меня установлен Docker for Windows версии 4.10.1 и установлена WSL Ubuntu 20.04 LTS.
Отдельным абзацем отмечу, что из контейнера с Jenkins потребуется доступ к Docker daemon в котором запущен этот Jenkins контейнер. Нужно это, чтобы Jenkins мог создавать контейнеры в которых будет происходить сборка образов, так как весь процесс будет работать на одной машине. Работать это будет следующим образом: Jenkins ловит триггер по которому начинается сборка и обращается к Docker daemon в котором он сам запущен и рядом создает еще один контейнер в котором собирает Docker образ — по завершению сборки такой контейнер удалится. Для этого в настройках Docker включите следующую функцию:

Важно: это небезопасный подход к использованию Docker и делать такие настройки в корпоративных сетях не стоит, даже если это сэкономит вам деньги на использовании сервера — это снижает безопасность и фактически дает злоумышленнику удаленно выполнить код в вашем Docker daemon. В промышленной среде используйте Docker установленный на отдельном хосте с соответствующими настройками безопасности. На домашнем компьютере оставлять эту настройку включенной также не стоит: наигрались — выключите.
Для самых продвинутых
Все основные образы, контейнеры и тома я определили в docker-compose.yml, возможно он упростит запуск тестового стенда и вам, но некоторые настройки внутри Jenkins и Nexus все же придется взять из следующих шагов:
docker-compose.yml
services: jenkins: image: jenkins/jenkins:lts-jdk11 ports: - "8080:8080" - "50000:50000" volumes: - jenkins_home:/var/jenkins_home - /var/run/docker.sock:/var/run/docker.sock user: root networks: - cicd_network nexus: image: sonatype/nexus3 ports: - "8081:8081" - "8083:8083" volumes: - nexus_data:/nexus-data networks: - cicd_network volumes: jenkins_home: external: true name: jenkins_home nexus_data: external: true name: nexus_data networks: cicd_network: driver: bridge
Создадим тома
Для начала выполните в PowerShell следующие команды для создания томов:
docker volume create --name jenkins_home docker volume create --name nexus_data
Эти тома будут хранить данные от контейнеров чтобы при повторном запуске не приходилось заново настраивать Jenkins и Nexus. Контейнеры способны сами создать необходимые тома, но я предпочитаю делать это заранее для пользования docker-compose.
Запуск и настройка Jenkins
Сначала запустим Jenkins и проинициализируем его. Для этого в PowerShell выполните следующую команду:
docker run -d ` --name jenkins ` --user root ` -p 8080:8080 ` -p 50000:50000 ` -v jenkins_home:/var/jenkins_home ` -v /var/run/docker.sock:/var/run/docker.sock ` jenkins/jenkins:lts-jdk11
Особо внимательные наверняка заметили, что контейнер выполняется с правами root пользователя и монтирует Unix socket. Увы это вынужденная мера чтобы контейнер смог обратиться к Docker daemon. Подробнее об этом описано в статье Docker Tips : about /var/run/docker.sock
Далее Docker попытается скачать образ jenkins/jenkins:lts-jdk11 и запустить контейнер. Если в предыдущей команде не получилось скачать образ, то выполните в PowerShell следующую команду:
docker pull jenkins/jenkins:lts-jdk11
Если все получилось, то в консоль будет выведен Id контейнера, а по адресу localhost:8080 вы увидите окно с инициализацией Jenkins:

Как вы догадались, пароль можно посмотреть по указанному выше пути, а еще зайти в консоль вывода контейнера и найти следующие строки:
Jenkins initial setup is required. An admin user has been created and a password generated. Please use the following password to proceed to installation: ac8c9a1e554e4f448d46f5cdcc94477d This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
Далее выберите «Install suggested plugins» и дождитесь окончания установки. Увы, но на этом этапе мастер установки не даст выбрать плагины для работы с Docker — что иронично, интернет для их скачивания в контейнере есть, а вот поискать плагины заранее нельзя. Хотя это обходится с помощью Dockerfile для запуска Jenkins контейнера — примет вот тут.
Когда настройка завершится, будет предложено создать пользователя. Как закончите, зайдите в настройки Jenkins и перейдите в Plugin manager — там нужно установить 3 плагина:
-
Blue Ocean — у меня версия 1.25.5
-
Docker Pipeline — у меня версия 1.29
-
Docker plugin — у меня версия 1.2.9
Необходимые зависимости подтянутся во время установки, а по её окончанию перезапустите контейнер. Операцию можно считать успешной если после всех действий слева на главном экране появилась кнопка «Open Blue Ocean» и по её нажатию открывается окно плагина.
Теперь попробуем подключиться к Docker daemon. Для этого снова перейдите в настройки и выберите «Manage Nodes and Clouds», затем «Configure Clouds» и «Add a new cloud» — «Docker».
Тут нажмите на «Docker Cloud details» — появится несколько полей и их нужно заполнить следующими значениями:
-
Name — «docker»
-
Docker host URI — «tcp://host.docker.internal:2375» — еще можно попробовать «unix://var/run/docker.sock» и «tcp://172.17.0.1:2375», но у меня сработал только первый
-
Отметьте чекбоксы «Enabled» и «Expose DOCKER_HOST»
Теперь в этой же секции нажмите «Test connection». Вы поймете что подключится удалось когда слева от кнопки появится версия API:

Далее настроим агентов сборки. Для этого нажмите на «Docker Agent templates» и «Add Docker Template», а поля заполнити следующими значениями:
-
Labels и Name — «docker-agent»
-
Docker Image — «benhall/dind-jenkins-agent:v2» — если поискать, то можно найти и другие образы для использования в качестве агента сборки
-
Connect method — «Connect with SSH»
-
SSH key — «Inject SSH key»
-
User — «root»
Остальные поля оставьте как есть и нажмите «Save». На этом базовые настройки Jenkins можно считать завершенными, но мы вернемся к ним на этапе написания пайплайнов.
А теперь займемся Nexus
В целом запуск Nexus мало отличается от запуска Jenkins, так что я просто добавлю сюда PowerShell команду:
docker run -d ` --name nexus ` -p 8081:8081 ` -p 8083:8083 ` -v nexus_data:/nexus-data ` sonatype/nexus3:latest
Разумееется, если на предыдущем этапе снова не получилось скачать образ, то выполните следующую PowerShell команду:
docker pull sonatype/nexus3:latest
Запуск контейнера с Nexus занимает больше времени чем запуск Jenkins — увы красивых картинок с надписью «Подождите» не будет. Тем не мене, как только контейнер запустится, он будет доступен по localhost:8081, а localhost:8083 мы будет использовать для доступа к репозиторию образов Docker. Но сперва завершим настройку Nexus ведь при первом запуске он запросит пароль, который лежит в этом файле в томе nexus_data:

Дальше на главной странице Nexus нажмите «Sign in» и для логина admin укажите пароль из этого файла. Далее появится мастер настройки, просто следуйте по его шагам. В мастере будет пункт «Configure Anonymous Access», для себя я выбрал «Configure Anonymous Access».
Теперь по правилам хорошего тона нужно завести учетную запись для Jenkins — по ней он будет авторизоваться в приватном Docker репозитории и пушить образы, но никто не запрещает в домашней версии использовать учетную запись admin.
Для создания пользователя перейдите в настройки Nexus и выберите раздел Users. Затем нажмите «Create local user» и заполните все преложенные поля — для себя я везде ввел «jenkins». Из коробки в Nexus всего 2 преднастроенные роли, так что тут выберите nx-admin.
Теперь создадим репозиторий. Для этого в настройках выберите раздел Repositories и нажмите Create repository. В пресетах выберите «docker (hosted)», имя укажите любое на ваш вкус. На этой же странице отметьте чекбок HTTP и укажите порт 8083 — так по адресу localhost:8083 будет доступен этот репозиторий.
Стоит отметить, что прямо сейчас этот репозиторий работать не будет. Точнее будет, но Docker не сможет в нем авторизоваться. Это решается правкой Realms в одноименной секции настроек. Просто перетащите «Docker Bearer Token Realm» в правый столбец и сохраните изменения — из коробки этот Realm отключен и не зная об этом придется потратить много времени на поиск решения. Теперь Jenkins сможет авторизоваться в Nexus, а у вас успешно выполнится следующая PowerShell команда:
docker login 127.0.0.1:8083 -u jenkins -p jenkins >> Login Succeeded <<
Переходим к созданию pipeline
Для примера я сделаю пайплайн с типом «Freestyle project» — где просто попытаемся силами Jenkins собрать и запушить Docker образ в Nexus. Этот pipeline будет запускаться по кнопке, хотя можно поэксперементировать и добавить «Multibranch Pipeline», но об этом в другой раз.
Для начала на главной странице Jenkins нажмите «New item» и выберите «Freestyle project», я указал в названии «cicd_test_freestyle». В настройках pipeline нужно будет отметить чекбокс «Restrict where this project can be run» и в поле «Label expression» указать наименование агента для билда — по гайду это «docker-agent», но если вы назвали его как-то иначе, то тут будет выпадающий список с подсказками.
Далее на вкладке «Source Code Management» выберем Git укажем репозиторий из которого будем собирать Docker образ. Я для тестов использовал простенький репозиторий https://github.com/karthi4india/jenkins/ в котором буквально 2 файла: Dockerfile и http сервер.
Для аутентификации в GitHub, если репозиторий приватный, можно сначала зайти в Blue Ocean и оттуда попытаться сделать pipeline — там будет ссылка на GitHub для создания токена с нужными разрешениями. Если этот токен потом вставить в Blue Ocean, то он его запомнит, но Jenkins его не увидит и придется создать Credentials, где логин это ваш логин GitHub, а пароль — это токен.
Далее на вкладке Build в поле Cloud выберем облако «docker», которое настроили в самом начале, а в поле Image добавим 2 записи:
127.0.0.1:8083/cicd_test_freestyle:latest 127.0.0.1:8083/cicd_test_freestyle:${BUILD_NUMBER}
А еще на этой же вкладке нужно будет нажать Advanced и указать там адрес репозитория и Credentials для подключения к нему. Для меня это репозиторий 127.0.0.1:8083

Также ниже будет еще одно поле Registry Credentials, там просто укажите Credentials для Nexus. Описывать создание Credentials нет смысла, если их не хватило, то рядом всегда есть кнопка Add, а там все просто.
Так после билда в Nexus будет 2 образа: один с номером билда и второй с тегом latest, а еще сохранятся предыдущие билды:

Теперь сохраните изменения и переходите в созданный проект — он будет на главной странице Jenkins и слева нажмите «Build now». Всплывет подсказка, что билд запланирован и ниже появится агент на котором будет происходить сборка. Агент может появиться не сразу и наверняка появится сообщение «‘Jenkins’ doesn’t have label ‘docker-agent’», но через несколько секунд оно пропадет и начнется сборка Docker образа:

Самое время нажать на номер билда слева и перейти в Console Output. Если все настроили правильно, то в конце логов будет ждать приятная надпись «Docker Build Done Finished: SUCCESS», а в Nexus появятся 2 Docker образа.
Как итог
CICD на домашнем ПК собрать можно, он будет работать, билдить образы и в целом с этим очень интересно поиграться в такой песочнице. Сюда можно и нужно добавить Multibranch Pipeline для сборки по разным веткам, можно добавить и Kubernetes чтобы собранный Docker образ деплоился в daemon, но об этом уже в другой статье.
ссылка на оригинал статьи https://habr.com/ru/post/677142/
Добавить комментарий