Nexus cd что это
Перейти к содержимому

Nexus cd что это

  • автор:

«Инфраструктура как код» в автоматизации сервисов CI/CD

Привет! Меня зовут Игорь Николаев, я пью за любовь работаю в отделе автоматизации процессов разработки Мир Plat.Form в НСПК. В этой статье я поделюсь тем, как наш отдел решал задачу по автоматизации предоставления различных ресурсов для команд разработки. Эта задача свойственна организациям с большим количеством проектов, инфраструктура которых состоит из распределенных и, возможно, слабо связанных сетевых сегментов.

В статье описан PoC (Proof of concept) решения задачи выделения ресурсов в рамках сервисов CI/CD (Continuous Integration & Continuous Delivery) и предоставления привилегий для пользователей этих сервисов.

Описание

Часто в организациях используются сложные и дорогостоящие IDM — класс систем Identity Management (как в рамках лицензирования, так и внедрения и обслуживания) для управления доступами. Нам хотелось совместить процессы запроса и предоставления ресурсов на сервисах CI/CD и предоставления доступов к этим ресурсам. Хотелось получить максимально прозрачное и простое в поддержке и реализации решение, которое обеспечивает следующий функционал:

  • Создание и управление сущностями сервисов CI/CD
  • Использование удобных для нас инструментов
  • Легкая интеграция с уже развернутыми у нас системами
  • Простота эксплуатации
  • Возможность тиражирования

Про тиражирование стоит сказать подробнее, у нас есть несколько сетевых сегментов с разными сервисами CI/CD, и иногда они имеют минимум сетевой связанности. Система должна с минимальными затратами обслуживать несколько окружений, которые могут отличаться друг от друга.

Что мы выбрали для PoC:

Как подход был выбран IaC (Infrastructure-as-Code) с описанием желаемых состояний в виде yaml файлов.
Python — язык для написания автоматизации (подходящий вариант для прототипа);
Bitbucket — веб-сервис для хостинга проектов и их совместной разработки;
Jenkins — сервис непрерывной интеграции (необходим нам для визуализации выполнения задач).

Как пилотные системы для автоматизации были выбраны:

Active Directory — всем известные службы каталогов (нам понадобятся группы и пользователи);
Bitbucket — часто запрашивают создание проектов, предоставление привилегий;
Nexus 3 OSS (не реклама, нет страницы в Wiki) — корпоративная система хранения артефактов, при появлении проектов создаются персональные репозитории проекта и выдаются привилегии.

Разговор об автоматизации следует начать с описания общей концепции.

В Bitbucket есть две важные сущности: проект(project) и репозиторий (repository), который входит в состав проекта. Для описания доступов в рамках концепта мы решили ограничиться доступами к проекту (более сегментированное предоставление привилегий (на репозиторий) в рамках концепта не потребуется).

У project в Bitbucket есть параметр project key, который понадобится для дальнейших манипуляций, мы взяли его за связующую основу. Именно он и будет являться названием директории в git-репозитории meta. В директории проекта будут размещаться meta-файлы (карты) проекта описанные в формате yaml.

Проектов в Мир Plat.Form много, и у каждого есть своя специфика. Возникает мысль держать в одном месте информацию о группах, инструментах, требуемых проекту, стендах (наборах серверов) и прочего, что имеет отношение к проекту. Для этого отлично подходит git репозиторий.

Какие задачи это решает?

  • В первую очередь, мы получаем стандартный интерфейс описания, который создает однотипные сущности сервисов CI/CD.
  • В любой момент времени мы можем увидеть реальное описание пользователей и их привилегий в рамках проекта.
  • Выполняя автоматизацию по расписанию можно гарантированно получать именно то, что описано в проектных метаданных (защита от «очумелых ручек»).
  • Расширяя описание проекта в виде определенной структуры meta-данных, можно автоматизировать другие сущности.

Структура meta репозитория git:

DEV — наименование сетевого сегмента
project1 — ключ проекта в Bitbucket
project1_meta.yaml — карта проекта
examples — директория примера описания

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

Скрипты автоматизации в рамках концепта будут находиться в проекте в отдельных репозиториях (названия не принципиальны):

  • ad-core-automation
  • bitbucket-core-automation
  • nexus-core-automation
  • jjb-core

О назначении первых трех репозиториев легко догадаться. Последний репозиторий jjb-core — репозиторий в котором мы будем хранить описание Jenkins Job в виде рецептов для Jenkins Job builder (о нем будет рассказано ниже).

Автоматизация Microsoft AD

Active Directory используется во многих организациях. Большое количество рабочих процессов организаций начинаются именно с него. У нас в Мир Plat.Form все сотрудники имеют учетные записи в AD и включены в различные группы.

За AD отвечает подразделение инфраструктуры. Для наших нужд была выделена техническая учетная запись (ТУЗ), которой делегировано управление одним из Organization unit (OU). Именно в нем с помощью простой автоматизации мы будем создавать группы и наполнять их пользователями.

Часть содержимого project1_meta.yaml, которая отвечает за AD:

--- READY: True # Защита от "дурака", если не True, то автоматизация проигнорирует весь файл TEAM: # Описание состава команды (роли) USER_LOCATION: ldap # local or ldap ROLES: owner: - owner1 developer: - developer1 - developer2 qa: - qa1 - qa2 GLOBAL_PRIVILEGES: &global_privileges # Базовый набор привилегий для каждой роли в команде owner: [read, write, delete] developer: [read, write] qa: [read]

READY — булево значение и позволяет, в случае необходимости, выключить автоматизацию обработки данного мета файла
TEAM — секция, описывающая сущность проекта
ROLES — произвольные названия ролей на проекте, отображающие суть
GLOBAL_PRIVELEGES — секция описывает, какая роль будет обладать какими привилегиями
Пример мета репозитория

В рамках предоставления прав для окружения разработки, чтобы не усложнять пример, остановимся на 3х основных ролях: owner, developer, qa (в целом, количество и наименование ролей является произвольным). Для дальнейшей автоматизации эти роли позволят покрыть большую часть повседневных потребностей (у нас сразу появились роль tech, для ТУЗ, но для примера обойдемся без нее).

В рамках OU проекта будем автоматически, на основании meta-файлов проекта, создавать необходимые SG (Security group) и наполнять их пользователями.

На схеме структура выглядит так:

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

Скрипт автоматизации получился очень простой. Он позволяет отслеживать изменения в составе групп (добавление/удаление пользователей) и создавать OU/SG.

Для запуска потребуется установить зависимости из requirements.txt (ldap3, PyYAML).

Автоматизация Sonatype Nexus3 OSS

Что такое Nexus? Nexus — это менеджер репозиториев, позволяющий обслуживать разные типы и форматы репозиториев через единый интерфейс (Maven, Docker, NPM и другие).

На момент написания статьи версия была OSS 3.25.1-04

Почему именно Nexus?

Есть community версия, которая обладает богатым функционалом, достаточным для выполнения большинства задач, связанных с хранением артефактов и проксирования внешних репозиториев.

Процесс хранения артефактов является важным при проектировании конвейера тестирования и развертывания.

Что потребуется автоматизировать?

Blobstore
Все двоичные файлы, загружаемые через proxy репозитории (мы не предоставляем прямого доступа к интернет репозиториям, используем исключительно прокисрование через nexus), опубликованные в hosted (локальные репозитории) репозитории хранятся в хранилищах Blob-объектов, связанном с репозиторием. В базовом развертывании Nexus, с одним узлом, обычно связаны с локальным каталогом на файловой системе, как правило, а каталоге sonatype-work.
Nexus версии >= 3.19 поддерживает два типа хранилищ File и S3.

Как мы видим, по умолчанию нам уже доступно хранилище default. Из информации выше мы можем понять, что данный blob находится на диске и ему доступен весь объем дискового раздела, на котором находится директория sonatype-work.

Проблематика

В целом, все логично, но есть минимум две проблемы, о которых следует задуматься:

  1. В случае, если все репозитории будут привязаны к одному blob, у нас могут появиться проблемы с тем, что хранилище может побиться.
  2. Если мы предполагаем, что наш Nexus будет использоваться несколькими командами разработки, то стоит сразу задуматься о том, что в некоторых ситуациях чрезмерная генерация артефактов может забить весь раздел и проблема будет не только у команды, которая генерирует большой объем артефактов, но и у других команд.

Простое решение

Первое, что приходит в голову — это создание отдельных blob stores. Очевидно, это не решает проблему расположения на одном дисковом разделе. Подходящим решением является «нарезать» разделы для каждого проекта. Забегая вперед, это решит еще и вопрос мониторинга и отправки уведомлений ответственным за проект. Удобное решение второго пункта описанных проблем.
По первому пункту наиболее правильным решением является создание отдельных blob store для каждого репозитория.

UI создания Blob stores:

Nexus позволяет настроить Soft quota, штука сомнительная. Она уведомляет о том, что с местом что-то не так, но не производит каких-либо действий. При правильном применении шагов, описанных выше, удается добиться большего функционала (Появляется простой способ отслеживания объема и обращений к диску, а переполнение не создает неприятности «соседям»).

В поле path мы можем указать раздел, который примонтирован, например, как nfs.
Что позволяет держать раздел непосредственно на сетевом хранилище. Это может снизить скорость, но дает ряд преимуществ с точки зрения простоты.

Nexus у нас запускается в Docker, для этого используется compose файл. Для подключения новых точек монтирования, простым решением будет добавить в compose файле монтирование родительского каталога точек монтирования.

version: "3" services: nexus3: container_name: nexus3 image: sonatype/nexus3:3.27.0 ports: - 8443:8443 - 50011:50011 # project1-docker-releases - 20012:50012 # project2-docker-releases volumes: - /nexus/sonatyep-work:/nexus-data - /mnt-blobs:/mnt-blobs - /etc/timezione:/etc/timezone - /etc/localtime:/etc/localtime logging: driver: "json-file" options: max-size: "10m" max-file: "10"

Repositories
Nexus позволяет создавать репозитории почти всех распространенных форматов. Если идти в сторону идеального хранения, то целесообразно для каждого проекта создавать минимум release и snapshot репозиторий, хотя идеальный вариант может содержать еще и release-candidat репозиторий. Это позволит настроить удобный механизм чистки репозиториев.

Определенно, release репозиторий должен во многих случаях иметь максимальную глубину хранения, как требование, в релизах не должно оказаться «мусора». Напротив, с репозиториями snapshot мы должны иметь возможность очищать без опасений в любое удобное время и без рисков.

Ко всем форматам репозиториев доступ осуществляется по 80 и/или 443 портам, за исключением docker. Репозиторий Docker, для доступа к нему, должен иметь персональный порт. Это приводит к некоторым сложностям. Каждый раз публикуя новый порт, мы должны добавлять его публикацию в compose файле.

LDAP
Nexus имеет возможность реализации подключения к LDAP и использования его в качестве аутентификации пользователей. В нашем случае мы используем группы пользователей для предоставления прав.

Roles
Для удобства роли создаются под проект, лучше идти от минимума, и для себя мы выбрали три роли для каждого проекта:
qa — обладают правами достаточными для read
developers — read, write
owners — read, write, delete
Группы из AD матчатся в локальные группы Nexus.

API
Начиная с версии Nexus OSS 3.19 появилось весьма удобное API для управления Nexus, это значимое нововведение, которое многие пользователи ждали позволит нам управлять Nexus и приводить его в нужное состояние.

На момент написания статьи API, по большей части, в статусе beta, но не смотря на это, работает без больших проблем и позволяет автоматизировать почти все необходимое.

Часть содержимого project1_meta.yaml, которая отвечает за nexus:

RESURCES: # Ресурсы, обслуживаемые автоматизацией nexus: repository: # Сущности # Maven - name: test-maven-releases locationType: hosted repoType: maven - name: test-maven-proxy locationType: proxy blobStoreName: test remoteUrl: http://test.ru repoType: maven # Docker - name: test-docker-releases locationType: hosted repoType: docker - name: test-docker-proxy locationType: proxy blobStoreName: test-blob remoteUrl: http://test.ru repoType: docker - name: test-docker-group blobStoreName: test-blob locationType: group httpPort: 10555 repoType: docker memberNames: - test-docker-releases - test-docker-proxy # Npm - name: test-npm-proxy locationType: proxy remoteUrl: http://test.ru repoType: npm blob: - name: test-blob path: test-blob privileges: 

На основании такого файла система автоматизации создает все обслуживаемые сущности. В наших командах принято, что teamlead отвечает за наполнение файла проекта, однако, создать его может любой желающий. После создания pull request следует согласование вовлеченными в процесс участниками, после мерджа с master веткой, отрабатывает автоматизация.

Стоит отметить, мы стремимся сделать процесс максимально простым для пользователя, что влечет к использованию шаблонов конфигураций, которые описаны в виде примитивных моделей. Система позволяет переопределить умолчания в случае возникновения необходимости в описании карты проекта.

Пример кода модели для maven hosted repository:

def maven_model_hosted(params): model = < 'name': params.get('name'), 'online': params.get('online', True), 'storage': < 'blobStoreName': params.get('blobStoreName', params['name']), 'strictContentTypeValidation': params.get('strictContentTypeValidation', True), 'writePolicy': params.get('writePolicy', 'ALLOW') >, 'cleanup': < 'policyNames': params.get('policyNames', []) >, 'maven': < 'versionPolicy': params.get('versionPolicy', 'MIXED'), 'layoutPolicy': params.get('layoutPolicy', 'PERMISSIVE') >> return model

Данный подход позволяет сократить описание создаваемой сущности до минимума.
Идеологически, все что может использовать значения по умолчанию должно их использовать, но при необходимости может быть заменено в файле карты проекта.

Автоматизация Atlassian Bitbucket

Для концепта достаточно будет автоматизировать создание проекта и предоставление привилегий к нему.

Часть содержимого project1_meta.yaml, которая отвечает за Bitbucket:

. bitbucket: name: project1-bitbucket-project # Это не project key! # project_key получается из имени файла description: "Описание проекта в свободной форме" privileges:  

Это все, что потребуется при заведении нового проекта. Project key будет взят из названия yaml файла (в данном примере — project1).

Как это выглядит в UI:

Jenkins Job Builder

JJB является python утилитой для описания сущностей jenkins в виде yaml манифестов, которые преобразуются в понятные jenkins API запросы. Это позволяет великолепно решать задачу управления большим количеством однотипных задач.

Jenkins в данном контексте является интерфейсом для отображения успешности выполняемых задач автоматизации и контроля над ними. Сами задачи на первом этапе планируем выполнять по расписанию, например, каждый час. Это позволит избавиться большой части неконтролируемых ручных изменений и будет каждый час приводить систему к описанному состоянию.

Структура репозитория jjb-core:

Каждая директория содержит описание Jenkins job состоящее из двух файлов.

Yaml файл описывает шаблон jenkins job имеет следующее наполнение:

--- - job: # Создаем директорию CORE name: CORE project-type: folder - job: # Создаем поддиректорию ad-core-automation в CORE name: CORE/ad-core-automation project-type: folder # Описание темплэйта - job-template: name: 'CORE/ad-core-automation/-' project-type: pipeline job_description: Упралвение OU и SG для # Defaults GIT_BRANCH: master GIT_CRED_ID: jenkins-ad-integration triggers: - timed: 'H(0-59) * * * *' parameters: - string: name: GIT_BRANCH default: '' description: Git ref (branch/tag/SHA) - string: name: GIT_CRED_IDjenkins default: '' description: Jenkins credentials ID for BitBucket - string: name: META_LOCATION default: 'DEV//_meta.yaml' description: Meta file location if CORE/meta repository dsl: !include-raw-escape: ./ad-core-automation.groovy - project: name: ad-core project_key: - project1 - project2 - project3 jobs: - 'CORE/ad-core-automation/-' 

Файл groovy — это простой jenkinsfile:

def meta_location = params.META_LOCATION def git_cred_id = params.GIT_CRED_ID def git_branch = params.GIT_BRANCH pipeline < agent < label 'common-centos' >stages < stage('Clone git repos') < steps < echo 'Clone meta' dir('meta') < git credentialsId: "$", url: 'git@github.com:Mir-Platform/meta-example.git' > echo 'Clone ad-core-automation' dir('auto') < git credentialsId: "$", branch: git_branch, url: 'git@github.com:Mir-Platform/ad-core-automation.git' > > > stage('Install and run') < steps < echo 'Install requirements' withDockerContainer('python:3.8.2-slim') < withEnv(["HOME=$"]) < sh 'pip install --user --upgrade -r auto/requirements.txt' sleep(5) echo 'Run automation' withCredentials([usernamePassword(credentialsId: 'ad_tech', passwordVariable: 'ad_pass', usernameVariable: 'ad_user')]) < dir('auto') < sh "./run.py -u $ad_user -p $ad_pass -f ../meta/$" > > > > > > > > 

Все это описывает создание следующей структуры Jenkins:

Общий алгоритм работы автоматизации:

  • Инициатор создает в репозитории meta новую директорию с картой проекта и создает pull-request в мастер ветку(1).
  • Pull-request попадает на проверку согласующих (2)
  • В случае, если проект новый, пока в ручном режиме инженер прописывает Bitbucket project key для JJB (данное действие нужно произвести единожды)
  • Автоматизация после внесения изменений в шаблоны JJB генерирует описанные job для проекта(4, 5).
  • Jenkins запускает автоматизацию AD(6), которая создает необходимые сущности в виде OU и SG в AD. В случае, если все сущности уже созданы, приводит состав пользователей к описанному (удаляет/добавляет)
  • Jenkins запускает автоматизацию Bitbucket(4), если проекта нет в Bitbucket, то создает его и предоставляет доступ для групп команды проекта. Если проект уже существует, то добавляет к нему группы AD с необходимыми привилегиями.
  • Jenkins запускает автоматизацию для Nexus(7). Создаются описанные сущности Nexus и к ним предоставляется доступ на основе групп AD

Результат и развитие

Результатом данного концепта стало появление базовой автоматизации описанных процессов. Интерфейс взаимодействия в виде yaml карт проектов оказался весьма удобен, появились запросы на улучшения. Главными показателями успешности стали простота и скорость предоставления необходимых проектам ресурсов. Показатель скорости улучшился в разы по сравнению с ручным подходом. Все стало однотипным, понятным и повторяемым. Избавились от ручных ошибок.

На текущий момент описанный PoC перешел в стадию промышленной эксплуатации и претерпел значительные доработки. Мы переписали core систему автоматизации, к которой в виде плагинов подключаются модули для автоматизации новых сервисов. Появились тесты.
Всего автоматизацией обслуживается около 50 проектов и подключаются новые. Планируем тиражирование в другие сетевые сегменты.

  • Блог компании Мир Plat.Form (НСПК)
  • IT-инфраструктура
  • DevOps

CI/CD в Git: 5 советов по организации репозиториев Git с поддержкой непрерывной интеграции

Фотография Сары Гофф-Дюпон

Git и непрерывная поставка образуют одно из потрясающих сочетаний, которые иногда встречаются в мире ПО, — подобно маслу и варенью на бутерброде. Две технологии, великолепные сами по себе, отлично дополняют друг друга. Поэтому я хочу поделиться несколькими советами, которые позволяют обеспечить идеальное взаимодействие сборок Bamboo с хранилищами Bitbucket. Главным образом эти компоненты взаимодействуют на тех этапах непрерывной поставки, где происходят сборка и тестирование, поэтому в статье речь будет идти больше о непрерывной интеграции, чем о непрерывной поставке.

1. Храните большие файлы за пределами репозитория

Очень часто приходится слышать о Git такое утверждение: не следует помещать в репозиторий большие файлы: бинарные и мультимедийные файлы, архивные артефакты и т. д. Это связано с тем, что после добавления файла он всегда будет присутствовать в истории репозитория, а значит, при каждом клонировании репозитория огромный файл будет клонироваться вместе с ним.

Извлечь файл из истории репозитория не так просто: это как операция лоботомии на базе кода. Такой хирургический способ извлечения файлов меняет всю историю репозитория, поэтому вы теряете четкую картину того, какие изменения были сделаны и когда. Достаточно причин, чтобы «избегать больших файлов» стало вашим правилом. И поэтому.

Для непрерывной интеграции принципиально важно хранить крупные файлы вне репозиториев Git

При каждой сборке серверу непрерывной интеграции необходимо клонировать репозиторий в рабочий каталог сборки. Если в вашем репозитории слишком много крупных артефактов, этот процесс замедляется, а значит, разработчикам приходится дольше ждать результатов сборки.

Ладно, пусть так. Но что если ваша сборка зависит от бинарных файлов из других проектов или от крупных артефактов? Это очень распространенная ситуация, и, вероятно, она будет существовать всегда. Отсюда вопрос: как мы можем эффективно с этим справиться?

См. решение
Разработка и эксплуатация программного обеспечения с помощью Open DevOps
Связанные материалы
Подробнее о магистральной разработке

Для хранения артефактов, которые создаются вашей командой или командами, взаимодействующими с вами, можно использовать внешнюю систему хранения, например Artifactory (у которой есть аддон для Bamboo), Nexus или Archiva. Нужные файлы можно загружать в каталог сборки в начале процесса сборки — как и сторонние библиотеки, которые вы загружаете через Maven или Gradle.

Профессиональный совет. Если артефакты часто меняются, избегайте соблазна синхронизировать большие файлы с сервером сборки каждую ночь, так чтобы во время сборки они перемещались только в пределах диска. В этом случае в промежутках между ночными синхронизациями сборка будет выполняться с устаревшими версиями артефактов. Кроме того, эти файлы все равно будут нужны разработчикам для сборки на локальных рабочих станциях. Таким образом, самое разумное, что можно предпринять, — просто сделать загрузку артефактов частью сборки.

Если в вашей сети нет внешней системы хранения, проще всего будет воспользоваться поддержкой больших файлов в Git (LFS).

Git LSF — это расширение, которое хранит в репозитории указатели на большие файлы, а не сами файлы. Сами файлы хранятся на удаленном сервере. Вы можете себе представить, насколько это сокращает время клонирования.

Git LSF

Скорее всего, у вас уже есть доступ к Git LFS: эту технологию поддерживает и Bitbucket, и Github.

2. Используйте поверхностные клоны для CI

При каждом выполнении сборки сервер сборки клонирует репозиторий в текущий рабочий каталог. Как я уже говорила, когда Git клонирует репозиторий, он по умолчанию клонирует всю историю репозитория. Поэтому, естественно, со временем эта операция будет выполняться все дольше.

При использовании поверхностного клонирования копироваться будет только текущее состояние вашего репозитория. Поэтому такой подход может быть весьма полезен для сокращения времени сборки, особенно при работе с большими и/или старыми репозиториями.

Снимок экрана репозиториев Git

Но допустим, что ваша сборка требует полной истории репозитория. Например, на одном из этапов сборки обновляется номер версии в файле POM (или аналогичном файле) или вы выполняете слияние двух веток при каждой сборке. В перечисленных случаях требуется, чтобы Bamboo отправил изменения обратно в репозиторий.

Благодаря Git простые изменения файлов (например, обновление номера версии) можно отправлять при отсутствии полной истории. Однако для выполнения слияния по-прежнему требуется история репозитория, поскольку системе Git необходимо найти общего предка двух веток. Это будет проблемой, если в вашей сборке используется поверхностное клонирование. И это подводит нас к совету № 3.

3. Кэшируйте репозиторий на агентах сборки

Это также значительно ускоряет операцию клонирования (фактически Bamboo поступает так по умолчанию).

Обратите внимание, что кэширование репозитория дает преимущество только при использовании агентов, которые от сборки к сборке не меняются. Если при каждом запуске сборки вы создаете и уничтожаете агенты сборки в EC2 или другом облачном ресурсе, кэширование репозитория не будет иметь смысла, поскольку работа идет с пустым каталогом сборки, и каждый раз потребуется создавать полную копию репозитория.

Если рассмотреть поверхностное клонирование с кэшированием репозитория и добавить к этому выбор между постоянными или облачными агентами, получится интересная сетка факторов. Вот небольшая матрица, которая поможет вам выработать стратегию.

Снимок экрана: постоянные агенты и облачные агенты

4. Продумывайте выбор триггеров

Это (почти) само собой разумеется: использование CI на всех активных ветках — хорошая идея. Но стоит ли запускать все сборки на всех ветках при любом коммите? Пожалуй, нет. И вот почему.

Возьмем, для примера, Atlassian. У нас более 800 разработчиков, каждый из которых отправляет изменения в репозиторий несколько раз в день (в основном изменения отправляются в собственные функциональные ветки). А это очень много сборок. И если отсутствует мгновенное и бесконечное масштабирование агентов сборки, это приводит к длительному ожиданию в очереди.

Один из наших внутренних серверов Bamboo содержит 935 различных планов сборки. Мы подключили 141 агент сборки к этому серверу и внедрили такие рекомендации, как передача артефактов и параллельное выполнение тестов, чтобы сделать каждую сборку максимально эффективной. Тем не менее сборка после каждой операции push приводила к тому, что работа застревала.

Можно было просто настроить еще один экземпляр Bamboo с дополнительными 100+ агентами, но мы притормозили и задались вопросом, действительно ли это необходимо. Ответ в итоге был отрицательным.

Таким образом мы даем разработчикам возможность запускать сборку принадлежащих им веток нажатием кнопки, а не выполняем сборку автоматически каждый раз. Это хороший способ обеспечить баланс между тщательным тестированием и экономией ресурсов: появляются большие возможности для экономии, поскольку именно в ветках происходит большая часть изменений.

Многим разработчикам нравится дополнительный контроль, который им обеспечивает сборка, запускаемая после нажатия кнопки. По их мнению, это естественным образом вписывается в рабочий процесс. Другие предпочитают не думать о том, когда запускать сборку, и использовать автоматические триггеры. Эффективно использовать можно любой из этих подходов. Важно то, что ветки в принципе нужно тестировать, а перед их слиянием с основным потоком кода необходимо убедиться, что сборка не содержит ошибок.

пиктограмма непрерывных триггеров

Однако важнейшие ветки, такие как главная ветка и ветки стабильного выпуска, — это отдельная история. Сборки там запускаются автоматически: либо путем опроса репозитория на предмет изменений, либо путем отправки push-уведомления из Bitbucket в Bamboo. Поскольку мы используем ветки разработки для всей незавершенной работы, единственными коммитами в главную ветку (теоретически) должны быть слияния веток разработки. К тому же это строки кода, из которых мы делаем релизы и создаем ветки разработки. Поэтому очень важно своевременно получать результаты тестов по каждому слиянию.

5. Прекратите опросы, используйте подключения

Опрос репозитория каждые несколько минут для обнаружения изменений — не слишком затратная операция для Bamboo. Но когда вы масштабируете проект до сотен сборок на тысячи веток, задействуя десятки репозиториев, сложность стремительно нарастает. Вместо того чтобы нагружать Bamboo всеми этими опросами, можно сделать так, чтобы из Bitbucket поступали сигналы об отправке изменений и необходимости сборки.

Обычно это делается путем добавления скрипта hook в репозиторий, но интеграция между Bitbucket и Bamboo выполняет настройку внутренних параметров автоматически. После того как эти два продукта будут связаны на серверном уровне, триггеры сборки, инициируемые из репозитория, будут Просто работать™ без лишней настройки. Каких-либо скриптов hook или специальной конфигурации не потребуется.

Снимок экрана: настройка Bitbucket

Независимо от используемых инструментов триггеры, инициируемые из репозитория, имеют преимущество: они автоматически исчезают, когда целевая ветка становится неактивной. Иными словами, вам не придется расходовать ресурсы процессора системы CI на опрос сотен заброшенных веток или напрасно тратить собственное время, вручную отключая сборку веток! (Хотя стоит отметить, что Bamboo можно просто настроить на игнорирование веток после X дней бездействия, если вы все же предпочитаете способ опроса.)

Ключом к использованию Git с CI является.

…просто внимательность. Когда непрерывная интеграция осуществлялась с помощью централизованной системы управления версиями, все прекрасно работало? С Git некоторые моменты будут работать не так идеально. Поэтому на первом этапе необходимо проверить свои исходные предположения. Для клиентов Atlassian вторым этапом является интеграция Bamboo с Bitbucket. Ознакомьтесь с нашей документацией, чтобы узнать подробнее, и удачной вам разработки!

Sarah Goff-Dupont

Sarah Goff-Dupont

Сара — в прошлом инженер по контролю качества, а теперь автор статей. Ее труды публикуют в журнале Harvard Business Review, Huffington Post и других отраслевых изданиях. Она живет в Миннесоте и работает удаленно. Свою работу она просто обожает. Свободное от работы время она проводит, читая, катаясь на сноуборде, готовя и забавляясь со своими детьми.

Публикация Java приложения в личный Nexus

Nexus это хранилище артефактов. Артефакт это ваше приложение, например jar-ник. Чаще всего в Nexus сохраняют библиотеки, чтобы другие разработчики могли их подключить в виде зависимости к своему приложению.

Самым большим и открытым Nexus является Maven Central. Он публичный, то есть любой может взять оттуда зависимость. Но что если вам не нужна публичность. Например, мы хотим сделать библиотеку, которой будут пользоваться только наши коллеги с работы, или ваши только вы и ваша команда. Тогда вам нужен Sonatype Nexus.

Nexus Sonatype позволит вам создать свой приватный, ну либо публичный Nexus с авторизацией. Также его можно использовать, как прокси перед Maven Central.

Я не буду рассказывать, как установить свой Nexus. Я расскажу, что добавить в ваше приложение, чтобы деплоить в Nexus.

Спонсор поста

Настраиваем settings.xml

Скорее всего у вас есть логин и пароль аккаунта в Nexus. Эти данные нужно указать в файле .m2/settings.xml . Если этого файла нет в папке .m2 создайте его.

   nexus-server nexus-login nexus-password   

Настраиваем приложение

Теперь переходим к pom.xml приложения.

В секцию properties добавляем версии плагинов и URL нексуса.

 . http://ip_you_nexus:nexus_port 2.8.2 1.6.8 . 

Добавляем в pom.xml url на репозитории в нексусе: снепшотный и релизный.

  nexus-server $/repository/maven-releases/  nexus-server $/repository/maven-snapshots/  

Обратите внимание на строки 3 и 7, id репозиториев должен совпадать с id в секции server файла .m2/settings.xml .

Мы заменим maven-deploy-plugin на nexus-staging-maven-plugin . После этого мы сможем деплоить в наш нексус командой mvn deploy .

   org.apache.maven.plugins maven-deploy-plugin $ true   org.sonatype.plugins nexus-staging-maven-plugin $  default-deploy deploy deploy    maven-snapshots $/nexus/ true    

Если вам нужно также сохранять исходники и JavaDoc, то добавьте эти плагины:

 org.apache.maven.plugins maven-source-plugin  attach-sources jar     org.apache.maven.plugins maven-javadoc-plugin 2.9.1 $/bin/javadoc   attach-javadocs jar    

Вот и все, теперь вы можете задеплоить артефакт в нексус обычной Maven командой:

mvn clean deploy

Вы можете настроить автоматическую сборку и доставку в Nexus с помощью Gitlab CI, подробнее об этом я писал в статье: Настройка Gitlab CI/CD для Java приложения ��

Масштабируем Scrum с помощью Nexus

В этой статье мы кратко расскажем про Nexus – подход для масштабирования Scrum, предложенный создателем Scrum Кеном Швабером. Мы также проиллюстрируем ключевые идеи этого подхода на примере реального большого продукта, который разрабатывают более 200 человек, используя Scrum и Nexus.

Две проблемы

Agile и Scrum становятся все более востребованными для больших компаний и больших продуктов. Есть несколько известных подходов к тому, как «масштабировать Agile», то есть организовывать работу нескольких Agile-команд над одним большим продуктом, – SAFe, LeSS, Nexus и другие. У каждого подхода есть свои особенности и свои преимущества.

Что касается Nexus - он отражает практический опыт масштабирования создателя Scrum Кена Швабера и его сподвижников из организации Scrum.org. Этот опыт в частности говорит о том, что при разработке большого продукта существуют две самые болезненные проблемы:

Зависимости. Они приводят к тому, что команды ожидают или даже блокируют друг друга, ломают чужой код, замедляя друг друга и т.д.
Интеграция. По отдельности команды могут создавать работающий код, но продукт в целом может при этом быть не работоспособным.

Важно отметить, что эти 2 проблемы в принципе отсутствуют, если над продуктом работает только одна команда. Проблемы возникают именно при масштабировании. Однако фреймворк Scrum, определенный в Руководстве по Scrum, практически ничего не говорит о таких «масштабированных» ситуациях.

Идея Nexus очень проста: нужно дополнить Scrum несколькими простыми элементами, помогающими прежде всего решить две упомянутые проблемы. Эти дополнительные элементы описаны в Nexus Guide – кратком бесплатном руководстве, доступном на сайте Scrum.org.
Давайте теперь рассмотрим обе проблемы на реальном примере.

Проблема №1
Зависимости-киллеры.

На картинке ниже Вы можете видеть набор функциональных модулей реального большого продукта для retail-домена, который разрабатывает распределенная интернациональная команда, состоящая из более чем 200 человек. Размер каждого эллипса зависит от оценки трудоемкости требований в данном модуле: чем больше трудоемкость – тем больше эллипс. Два эллипса пересекаются, если между соответствующими модулями есть зависимости: связанные требования, общий код, и др.

Как видно из картинки, команде, работающей, например, над компонентом Order Management, необходимо как минимум координировать свою работу с командами, работающими над 7 другими связанными компонентами. И это не считая так называемых внешних зависимостей, связанных со специалистами, находящимися вне продуктовой команды. В нашем реальном кейсе такие зависимости неоднократно приводили (особенно в начале разработки) к простою команд, вынужденной работе над низкоприоритетным фичами, недостижению целей Спринта и другим негативным последствиям.

Nexus и Scaled Professional Scrum помогают справиться с этими проблемами за счет ряда практик, в частности:
Правильный выбор структуры команд, Бэклога продукта и архитектурных решений, позволяющий минимизировать зависимости
Расширение практики Product Backlog refinement, которая из необязательной активности в Scrum становится обязательным событием с фокусом на минимизацию зависимостей и кросс-командное взаимодествие
Обнаружение, визуализация и минимизация зависимостей во время планирования спринта

Прочитать про это подробнее можно в Nexus Guide и на страничке Scrum.org/Nexus. Познакомиться с этим на практике лучше всего на тренинге Scaled Professional Scrum with Nexus.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *