YOU ARE DOWNLOADING DOCUMENT

Please tick the box to continue:

Transcript
Page 1: CD with Jenkins. Lessons Learned

CD with Jenkins

Lessons Learned

Page 2: CD with Jenkins. Lessons Learned

@tolkv

2

@lavcraft

Page 3: CD with Jenkins. Lessons Learned

About me

Architect@

/aatarasoff

/aatarasoff

habrahabr.ru/aatarasoff

developerblog.info

Page 4: CD with Jenkins. Lessons Learned

Что такое Jenkins?

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

Page 5: CD with Jenkins. Lessons Learned

Continuous Integration

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

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

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

Page 6: CD with Jenkins. Lessons Learned

Monolith Microservices

Page 7: CD with Jenkins. Lessons Learned

Continuous Integration Delivery

Page 8: CD with Jenkins. Lessons Learned

Continuous Delivery

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

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

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

Page 9: CD with Jenkins. Lessons Learned

Три часа и в продакшен

Page 10: CD with Jenkins. Lessons Learned

Continuous Delivery Tools

Jenkins

GoCD

Team City

CircleCI

etc.

Page 11: CD with Jenkins. Lessons Learned

Почему Jenkins?

OpenSource

Экспертиза

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

Pipeline Plugin

Page 12: CD with Jenkins. Lessons Learned

Lessons Learned

1. Линейный Pipeline

Page 13: CD with Jenkins. Lessons Learned

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

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

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

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

Feature Toggle

Page 14: CD with Jenkins. Lessons Learned

Pipeline plugin

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

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

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

Page 15: CD with Jenkins. Lessons Learned
Page 16: CD with Jenkins. Lessons Learned

//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

Page 17: CD with Jenkins. Lessons Learned

//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

Page 18: CD with Jenkins. Lessons Learned

//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

Page 19: CD with Jenkins. Lessons Learned

//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

Page 20: CD with Jenkins. Lessons Learned

//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

Page 21: CD with Jenkins. Lessons Learned

//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

Page 22: CD with Jenkins. Lessons Learned

//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' ]] ])}

Page 23: CD with Jenkins. Lessons Learned

//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' ]] ])}

Page 24: CD with Jenkins. Lessons Learned

//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

Page 25: CD with Jenkins. Lessons Learned

Интерфейс Jenkins

Page 26: CD with Jenkins. Lessons Learned

Интерфейс Jenkins

Page 27: CD with Jenkins. Lessons Learned

Blueocean plugin

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

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

Page 28: CD with Jenkins. Lessons Learned
Page 29: CD with Jenkins. Lessons Learned
Page 30: CD with Jenkins. Lessons Learned
Page 31: CD with Jenkins. Lessons Learned
Page 32: CD with Jenkins. Lessons Learned

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

Page 33: CD with Jenkins. Lessons Learned

Lessons Learned

1. Линейный Pipeline

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

Page 34: CD with Jenkins. Lessons Learned

Job DSL plugin

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

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

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

Page 35: CD with Jenkins. Lessons Learned
Page 36: CD with Jenkins. Lessons Learned

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

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

Page 37: CD with Jenkins. Lessons Learned

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

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

Page 38: CD with Jenkins. Lessons Learned

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

branch '*/master' createTag false }}

logRotator { numToKeep(3)}

concurrentBuild(false)

Page 39: CD with Jenkins. Lessons Learned

Что естьansible:

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

Page 40: CD with Jenkins. Lessons Learned

Что естьansible:

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

Page 41: CD with Jenkins. Lessons Learned

Что естьansible:

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

Page 42: CD with Jenkins. Lessons Learned

Что естьansible:

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

проекты:

Page 43: CD with Jenkins. Lessons Learned

Lessons Learned

1. Линейный Pipeline

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

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

Page 44: CD with Jenkins. Lessons Learned

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

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

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

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

Page 45: CD with Jenkins. Lessons Learned

Pipeline inputs

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

Есть REST API

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

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

Page 46: CD with Jenkins. Lessons Learned

input id: 'TestsArePassed'

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

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

Page 47: CD with Jenkins. Lessons Learned

Jira Integration

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

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

Page 48: CD with Jenkins. Lessons Learned

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

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

Page 49: CD with Jenkins. Lessons Learned
Page 50: CD with Jenkins. Lessons Learned

<——— Интеграционные тесты

<——— Сборка завершена

<——— Деплой в тест

Page 51: CD with Jenkins. Lessons Learned

Lessons Learned

1. Линейный Pipeline

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

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

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

Page 52: CD with Jenkins. Lessons Learned

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

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

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

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

Page 53: CD with Jenkins. Lessons Learned

//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' ]] ])}

Page 54: CD with Jenkins. Lessons Learned

//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 }}

Page 55: CD with Jenkins. Lessons Learned

//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 }}

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

Page 56: CD with Jenkins. Lessons Learned

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

Page 57: CD with Jenkins. Lessons Learned

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

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

)

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

Page 58: CD with Jenkins. Lessons Learned

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

OpenSource UpdateCenter

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

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

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

Page 59: CD with Jenkins. Lessons Learned

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

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

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

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

Page 60: CD with Jenkins. Lessons Learned

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

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

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

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

Page 61: CD with Jenkins. Lessons Learned

Lessons Learned

1. Линейный Pipeline

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

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

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

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

Page 62: CD with Jenkins. Lessons Learned

docker rm -f jenkins

Page 63: CD with Jenkins. Lessons Learned

docker rm -f jenkins

Page 64: CD with Jenkins. Lessons Learned

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

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

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

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

Page 65: CD with Jenkins. Lessons Learned

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

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

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

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

Page 66: CD with Jenkins. Lessons Learned

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

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

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

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

Page 67: CD with Jenkins. Lessons Learned

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

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

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

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

Page 68: CD with Jenkins. Lessons Learned

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

Page 69: CD with Jenkins. Lessons Learned

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

Page 70: CD with Jenkins. Lessons Learned

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

Install Master

Page 71: CD with Jenkins. Lessons Learned

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

Install Master

template job xml

Page 72: CD with Jenkins. Lessons Learned

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

Install Master

template job xml

Job DSL

Page 73: CD with Jenkins. Lessons Learned

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

Install Master

template job xml

Job DSL Git

job dslpipeline groovy

Page 74: CD with Jenkins. Lessons Learned

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

Install Master

template job xml

Job DSL Git

job dslpipeline groovy

Generate jobs

Page 75: CD with Jenkins. Lessons Learned

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

Page 76: CD with Jenkins. Lessons Learned

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

Page 77: CD with Jenkins. Lessons Learned

Lessons Learned

1. Линейный Pipeline

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

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

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

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

Page 78: CD with Jenkins. Lessons Learned

Lessons Learned

1. Линейный Pipeline

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

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

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

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

Page 79: CD with Jenkins. Lessons Learned

Lessons Learned

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

Page 80: CD with Jenkins. Lessons Learned

Lessons Learned

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

2. Всё как код

Page 81: CD with Jenkins. Lessons Learned

Lessons Learned

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

2. Всё как код

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

Page 82: CD with Jenkins. Lessons Learned

Lessons Learned

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

2. Всё как код

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

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

Page 83: CD with Jenkins. Lessons Learned

Lessons Learned

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

2. Всё как код

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

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

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

Page 84: CD with Jenkins. Lessons Learned

Plugins & toolsList

JobDSL

Pipeline Plugin

Blueocean Plugin

Jira Plugin

Juseppe

Page 85: CD with Jenkins. Lessons Learned

@aatarasoff

@aatarasoff

QA@tolkv

@lavcraft