CD with Jenkins. Lessons Learned

Preview:

Citation preview

CD with Jenkins

Lessons Learned

@tolkv

2

@lavcraft

About me

Architect@

/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 stagenode('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 stagenode('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 stagenode('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 stagenode('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 stagenode('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 stagenode('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 stagenode('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 stagenode('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 stagenode('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

Интерфейс Jenkins

Интерфейс Jenkins

Blueocean plugin

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

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

Нет интерфейса – нет проблем

Lessons Learned

1. Линейный Pipeline

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

Job DSL plugin

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

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

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

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

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

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)

Что естьansible:

• установка jenkins master

Что естьansible:

• установка jenkins master• juseppe обязательно нужен

Что естьansible:

• установка jenkins master• juseppe обязательно нужен• преднастройка slave

Что естьansible:

• установка jenkins master• juseppe обязательно нужен• преднастройка slave

проекты:

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

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

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

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 stagenode('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 stagenode('build') { // Mark the code checkout 'stage' stage 'Checkout' {

git credentialsId: 'jenkins-git', url: "${git_url}/${repo}.git", excludedUsers: 'jenkins', cleanBeforeCheckout: true }}

//checkout and definition stagenode('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-ов с разными лэйблами для разных сред/сетевых сегментов

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

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

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

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

Lessons Learned

1. Линейный Pipeline

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

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

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

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

docker rm -f jenkins

docker rm -f jenkins

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

curl -XPOST 'jenkins/credentials/store/system/domain/_/createCredentials' --data-urlencode 'json={ "credentials": { "scope": "GLOBAL", "id": "jenkins-http", "username": "jenkins", "password": "sniknej123", "description": "", "$class": "...UsernamePasswordCredentialsImpl" }}'

Конфигурация как код говоришь?

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

Install Master

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

Install Master

template job xml

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

Install Master

template job xml

Job DSL

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

Install Master

template job xml

Job DSL Git

job dslpipeline groovy

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

Install Master

template job xml

Job DSL Git

job dslpipeline groovy

Generate jobs

Больше Прокси Джобов

Больше Прокси Джобов

Lessons Learned

1. Линейный Pipeline

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

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

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

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

Lessons Learned

1. Линейный Pipeline

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

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

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

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

Lessons Learned

1. Отдельные Master´а

Lessons Learned

1. Отдельные Master´а

2. Всё как код

Lessons Learned

1. Отдельные Master´а

2. Всё как код

3. Пайплайн всем

Lessons Learned

1. Отдельные Master´а

2. Всё как код

3. Пайплайн всем

4. Не смотреть в UI

Lessons Learned

1. Отдельные Master´а

2. Всё как код

3. Пайплайн всем

4. Не смотреть в UI

5. KISS и Контрибьють!

Plugins & toolsList

JobDSL

Pipeline Plugin

Blueocean Plugin

Jira Plugin

Juseppe

@aatarasoff

@aatarasoff

QA@tolkv

@lavcraft

Recommended