Continuous Delivery with Jenkins: Lessons Learned

Preview:

Citation preview

CD with Jenkins

Lessons Learned

About meArchitect @

/aatarasoff

/aatarasoff

habrahabr.ru/aatarasoff

developerblog.info

Что такое Jenkins?

ПО для сборки артефактов?

Continuous Integration

Много людей - один артефакт

Синхронизация изменений, тестирование, code review

Цель - артефакт

Monolith Microservices

Continuous Integration Delivery

Continuous Delivery

Артефактов много

Не нужна синхронизация изменений

Цель - деплой в бой

Continuous Delivery Tools

Jenkins

GoCD

Team City

CircleCI

etc.

Почему Jenkins?

OpenSource

Экспертиза

Огромное количество интеграций

Pipeline Plugin

Lessons Learned

1. Линейный Pipeline

Линейная доставка

Независимые потоки доставки

Нет менеджмента зависимостей

Каждый артефакт готов работать в неполном окружении

Feature Toggle

Pipeline plugin

Декларативное описание процесса (Groovy DSL)

Очень просто сконфигурировать

Визуализация процесса

//checkout and definition stage node('build') { // Mark the code checkout 'stage' stage 'Checkout' git credentialsId: 'jenkins-git', url: "${git_url}/${repo}.git"

// Mark build 'stage' stage 'Build'

sh ('./gradlew clean dockerBuild final') }

//next steps

//checkout and definition stage node('build') { // Mark the code checkout 'stage' stage 'Checkout' git credentialsId: 'jenkins-git', url: "${git_url}/${repo}.git"

// Mark build 'stage' stage 'Build'

sh ('./gradlew clean dockerBuild final') }

//next steps

//checkout and definition stage node('build') { // Mark the code checkout 'stage' stage 'Checkout' git credentialsId: 'jenkins-git', url: "${git_url}/${repo}.git"

// Mark build 'stage' stage 'Build'

sh ('./gradlew clean dockerBuild final') }

//next steps

//checkout and definition stage node('build') { // Mark the code checkout 'stage' stage 'Checkout' git credentialsId: 'jenkins-git', url: "${git_url}/${repo}.git"

// Mark build 'stage' stage 'Build'

sh ('./gradlew clean dockerBuild final') }

//next steps

//checkout and definition stage node('build') { // Mark the code checkout 'stage' stage 'Checkout' git credentialsId: 'jenkins-git', url: "${git_url}/${repo}.git"

// Mark build 'stage' stage 'Build'

sh ('./gradlew clean dockerBuild final') }

//next steps

//checkout and definition stage node('build') { // Mark the code checkout 'stage' stage 'Checkout' git credentialsId: 'jenkins-git', url: "${git_url}/${repo}.git"

// Mark build 'stage' stage 'Build'

sh ('./gradlew clean dockerBuild final') }

//next steps

//checkout and definition stage node('build') { // Mark the code checkout 'stage' stage 'Checkout' checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [

[$class: 'UserExclusion', excludedUsers: 'jenkins'], [$class: 'CleanBeforeCheckout'], [$class: 'LocalBranch', localBranch: 'master']

], userRemoteConfigs: [[ credentialsId: 'jenkins-git', url: "${git_url}/${artifact_name}.git", refspec: '+refs/heads/master:refs/remotes/origin/master' ]] ]) }

Blueocean plugin

Пока в стадии alpha

Красивая визуализация процесса на современных технологиях

Lessons Learned

1. Линейный Pipeline

2. Автогенерация джобов

Job DSL plugin

Декларативное описание создания джобов (Groovy DSL)

Очень просто сконфигурировать, легко смасштабировать

Унификация разработки как бонус

def jobs = "${JOBS_LIST}".split( '\n' )

jobs.each { job -> pipelineJob("${basePath}/${job}") { //define SCM

definition { cps { script(readFileFromWorkspace('some_script.groovy')) sandbox() } } } }

def jobs = "${JOBS_LIST}".split( '\n' )

jobs.each { job -> pipelineJob("${basePath}/${job}") { //define SCM

definition { cps { script(readFileFromWorkspace('some_script.groovy')) sandbox() } } } }

scm { git { remote { url "${some_url}.git" credentials 'jenkins-git' }

branch '*/master' createTag false } }

logRotator { numToKeep(3) }

concurrentBuild(false)

Lessons Learned

1. Линейный Pipeline

2. Автогенерация джобов

3. Даём управление человеку

А зачем нам человек?

Недостаточный уровень автоматизации

Невозможность принять решение go-nogo в автоматическом режиме

Формальные процедуры и процессы

Pipeline inputs

Дают возможность приостановить работу до принятия решения человеком

Есть REST API

Можно параметризовать

http://developerblog.info/2016/05/31/poluchaiem-upravlieniie-obratno-v-jenkins-pipeline/

input id: 'TestsArePassed'

http://host:port/job/name/number/input/TestsArePassed/proceedEmpty

http://host:port/job/name/number/input/TestsArePassed/abort

Jira Integration

Учётная система

Возможность назначать на определённые этапы ответственных лиц

Jira Plugin (есть интеграция с Pipeline Plugin)

jiraIssueUpdate( jqlSearch: jql, workflowActionName: 'Testing', comment: "Deploy to test environment is completed" )

jiraComment ( issueKey: jira_id, body: "Auto tests have been started» )

Lessons Learned

1. Линейный Pipeline

2. Автогенерация джобов

3. Даём управление человеку

4. Борьба с ограничениями

Не хватает возможностей?

Это OpenSource, всегда можно написать свой плагин или доработать существующий

Пул-реквесты не всегда будут приняты

… или будут приняты через продолжительное время

//checkout and definition stage node('build') { // Mark the code checkout 'stage' stage 'Checkout' checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [

[$class: 'UserExclusion', excludedUsers: 'jenkins'], [$class: 'CleanBeforeCheckout'], [$class: 'LocalBranch', localBranch: 'master']

], userRemoteConfigs: [[ credentialsId: 'jenkins-git', url: "${git_url}/${artifact_name}.git", refspec: '+refs/heads/master:refs/remotes/origin/master' ]] ]) }

//checkout and definition stage node('build') { // Mark the code checkout 'stage' stage 'Checkout' git credentialsId: 'jenkins-git', url: "${git_url}/${repo}.git", excludedUsers: 'jenkins', cleanBeforeCheckout: true }

Удобно, но патч был отклонён

jiraIssueUpdate( jqlSearch: jql, workflowActionName: 'Testing', comment: 'Deploy to test environment is completed' )

jiraIssueUpdate( jqlSearch: jql, workflowActionName: 'Testing', comment: 'Deploy to test environment is completed' )

jiraIssueFieldUpdate( issueKey: jira_id, fieldName: 'Jenkins Info', fieldValue: 'some value'

)

Патч пока висит на рассмотрении

Не жди, используй Juseppe?

OpenSource UpdateCenter

Можно собирать свои версии плагинов раньше, чем они попадут в UpdateCenter

Решает проблемы с сетевым доступом (это когда у мастера нет доступа в интернет)

https://github.com/yandex-qatools/juseppe

Сетевые ограничения

Разные среды в разных DMZ

Сложно заказывать доступы между машинами

Решение в использовании slave-ов с разными лэйблами для разных сред/сетевых сегментов

Lessons Learned

1. Линейный Pipeline

2. Автогенерация джобов

3. Даём управление человеку

4. Борьба с ограничениями

5. Конфигурируй как код

Конфигурация как код

Не хочется делать Backup-ы

Команд много и есть желание быстро поднимать и конфигурировать новые экземпляры

Immutable-конфигурация

Блеск и нищета конфигурации

Легко конфигурировать джобы (см. JobDSL и Pipeline Plugin)

Добавлять мета-джобы можно через jenkins-cli

Сложно конфигурировать сам Jenkins: credentials, tools, plugins (шаблонизация xml, init groovy scripts, API etc.)

Lessons Learned

1. Линейный Pipeline

2. Автогенерация джобов

3. Даём управление человеку

4. Борьба с ограничениями

5. Конфигурируй как код

Plugins & tools List

JobDSL

Pipeline Plugin

Blueocean Plugin

Jira Plugin

Juseppe

/aatarasoff

/aatarasoff

habrahabr.ru/aatarasoff

developerblog.info

Вопросы и ответы

Architect @

Recommended