Сквозной jenkins ci cd конвейер: что мы собираем
Цель - один Jenkinsfile, который проводит коммит через весь путь: вытащить код, собрать приложение и Docker-образ, прогнать тесты, проверить качество в SonarQube с quality gate, запушить образ в реестр, выкатить в Kubernetes, но на прод - только после ручного аппрува, и в конце пнуть Slack. Это и есть тот самый jenkins ci cd пример, который не стыдно показать на собеседовании.
Перед тем как смотреть на pipeline, договоримся про базу 2026 года. Jenkins живёт на LTS-линии 2.5xx; свежие выпуски (2.555.1 и новее) уже требуют Java 21, а Java 17 на них не поддерживается - последняя LTS-база, где ещё держался Java 17, ушла весной 2026. Поэтому контроллер и агенты гоняем на Java 21. Declarative pipeline - стандарт по умолчанию; scripted достаём только там, где нужна настоящая динамика (циклы по списку сервисов, генерация stage на лету). Blue Ocean - наследие, его развитие давно заморожено, новый UI на нём не строим, смотрим в сторону обычного Pipeline-вида и логов.
Логику переиспользования выносим в shared library. В реальном проекте ты не пишешь sh-команды деплоя в каждом репозитории - ты вызываешь deployToK8s() из общей библиотеки, и сотня команд получает одинаковый, проверенный код.

Jenkins pipeline целиком: один Jenkinsfile
Вот скелет сквозного конвейера. Агент - эфемерный pod в Kubernetes (про это была отдельная глава), образы и шаги - настоящие.
Код: Выделить всё
@Library('platform-shared@v3') _
pipeline {
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: build
image: maven:3.9-eclipse-temurin-21
command: ["sleep"]
args: ["infinity"]
- name: kaniko
image: gcr.io/kaniko-project/executor:debug
command: ["sleep"]
args: ["infinity"]
'''
}
}
options {
timeout(time: 30, unit: 'MINUTES')
disableConcurrentBuilds()
}
environment {
IMAGE = "registry.cyberlake.ru/shop/api"
TAG = "${env.GIT_COMMIT.take(8)}"
}
stages {
stage('Checkout') {
steps { checkout scm }
}
stage('Build & Test') {
steps {
container('build') {
sh 'mvn -B clean verify'
}
}
post {
always { junit 'target/surefire-reports/*.xml' }
}
}
stage('Quality Gate') {
steps {
container('build') {
withSonarQubeEnv('sonar-prod') {
sh 'mvn -B sonar:sonar'
}
}
timeout(time: 10, unit: 'MINUTES') {
waitForQualityGate abortPipeline: true
}
}
}
stage('Build & Push Image') {
steps {
container('kaniko') {
sh """
/kaniko/executor \
--dockerfile=Dockerfile \
--context=`pwd` \
--destination=${IMAGE}:${TAG} \
--destination=${IMAGE}:latest
"""
}
}
}
stage('Deploy: staging') {
steps {
deployToK8s(cluster: 'staging', image: "${IMAGE}:${TAG}")
}
}
stage('Approve: prod') {
steps {
timeout(time: 1, unit: 'HOURS') {
input message: "Катим ${TAG} в прод?", ok: 'Деплой',
submitter: 'release-team'
}
}
}
stage('Deploy: prod') {
steps {
deployToK8s(cluster: 'prod', image: "${IMAGE}:${TAG}")
}
}
}
post {
success { slackSend channel: '#deploys', color: 'good',
message: "OK ${IMAGE}:${TAG} -> prod" }
failure { slackSend channel: '#deploys', color: 'danger',
message: "FAIL ${env.JOB_NAME} #${env.BUILD_NUMBER}" }
}
}
Функция deployToK8s живёт в shared library. Минимальный вид файла vars/deployToK8s.groovy:
Код: Выделить всё
def call(Map cfg) {
withKubeConfig(credentialsId: "kubeconfig-${cfg.cluster}") {
container('build') {
sh """
kubectl set image deployment/api \
api=${cfg.image} -n shop
kubectl rollout status deployment/api -n shop --timeout=180s
"""
}
}
}
Код: Выделить всё
jenkins:
systemMessage: "Cyberlake CI - managed by JCasC"
numExecutors: 0
clouds:
- kubernetes:
name: "k8s"
namespace: "jenkins-agents"
jenkinsUrl: "http://jenkins.jenkins.svc:8080"
containerCapStr: "30"
unclassified:
slackNotifier:
teamDomain: "cyberlake"
tokenCredentialId: "slack-token"
Jenkins vs GitLab, GitHub Actions и Argo: честно в 2026
Главный вопрос практика - стоит ли вообще брать Jenkins сегодня. Отвечаю без религии. Связка jenkins vs gitlab и jenkins против GitHub Actions в 2026 - это не про то, кто круче, а про то, что у тебя за парк и команда.
Где Jenkins силён. Максимальная гибкость - тысячи плагинов, любой экзотический шаг, интеграция с легаси, которого нет в коробке у облачных систем. Полный self-hosted контроль - данные и сборка не уходят наружу, что критично для банков и госсектора. Огромный установленный парк: если у компании уже сотни Jenkins-пайплайнов и инженеры их знают, миграция стоит дороже, чем поддержка.
Где проигрывает. GitLab CI даёт всё в одной платформе - репозиторий, CI, реестр, безопасность, самая глубокая нативная интеграция с Kubernetes через pull-based агента. Берут, когда хотят единый продукт вместо зоопарка. GitHub Actions выигрывает скоростью старта и экосистемой готовых actions - если код уже на GitHub, это путь наименьшего сопротивления, но он же и привязка: репозиторий не на GitHub - и преимущество испаряется. Jenkins за это платит обслуживанием: обновления контроллера, совместимость плагинов, ёмкость агентов - всё на твоих плечах.
И отдельно про деплой. В 2026 типовая архитектура cloud-native команд - это CI-инструмент (любой из трёх) плюс Argo CD на доставке. Argo по факту выиграл слой CD на Kubernetes: drift detection, автоматический откат, мультикластер, паттерн App-of-Apps. Jenkins тут не конкурент Argo, а партнёр - он собирает образ и обновляет манифест в git, а Argo подтягивает изменение в кластер по pull-модели. Если строишь GitOps - не заставляй Jenkins делать kubectl apply на прод напрямую, отдай это Argo, а Jenkins оставь на сборке и тестах.
Как выбирать коротко. Нужен максимальный контроль, есть легаси и DevOps-команда - Jenkins. Хочешь единую платформу с безопасностью из коробки - GitLab CI. Код на GitHub и важна скорость - GitHub Actions. Деплоишь в Kubernetes всерьёз - сверху Argo CD, независимо от выбора CI.
Типичные грабли финального конвейера
- Quality Gate без waitForQualityGate. Запустить sonar:sonar и забыть про ожидание - сборка зелёная даже при провале порогов. Гейт работает только с waitForQualityGate abortPipeline: true.
- input внутри агента. Шаг аппрува держит занятым executor и pod всё время ожидания. Выноси input в stage без тяжёлого agent или ставь agent none на pipeline и agent на отдельные stage.
- Секреты в Jenkinsfile открытым текстом. Токены реестра и kubeconfig - только через credentials и withKubeConfig, никогда не хардкодь и не печатай в echo.
- Прод-деплой без таймаута на input. Зависший аппрув блокирует пайплайн навечно. Всегда оборачивай в timeout.
- docker build на docker.sock в кластере. Монтировать сокет демона - дыра в безопасности. В Kubernetes собирай образ kaniko или buildkit без привилегий.
- Возьми любой свой проект и собери Jenkinsfile со стадиями Checkout, Build & Test, Build & Push Image, Deploy staging, Approve prod, Deploy prod.
- Вынеси деплой в shared library как vars/deployToK8s.groovy и вызови из двух стадий с разными кластерами.
- Добавь stage Quality Gate с waitForQualityGate (поднимешь SonarQube локально через docker run).
- Опиши контроллер и kubernetes-облако в jenkins.yaml через JCasC и подними Jenkins из этого файла с нуля.
- Добавь slackSend в post-блок на success и failure, проверь оба пути - зелёный и красный.
- Почему input на проде надо оборачивать в timeout и выносить за пределы тяжёлого агента?
- Чем waitForQualityGate отличается от простого запуска sonar:sonar и зачем abortPipeline: true?
- В каких трёх ситуациях ты осознанно выберешь Jenkins, а не GitLab CI или GitHub Actions?
- Почему в GitOps-связке деплой в кластер лучше отдать Argo CD, а Jenkins оставить на CI?
Ты собрал полноценный jenkins pipeline: код проходит сборку, тесты, гейт качества, упаковку в образ, выкатку в staging, человеческий аппрув и прод, а Slack держит команду в курсе - и всё это описано как код через Jenkinsfile, shared library и JCasC. Это рабочий каркас, который масштабируется на десятки сервисов. Jenkins в 2026 - не модный, но честный инструмент: он даёт контроль и гибкость ценой обслуживания, и для большого парка с легаси это всё ещё сильный выбор. Дальше расти стоит в трёх направлениях: GitOps с Argo CD как слой доставки, DevSecOps - сканеры образов и SBOM прямо в гейтах, и платформенная инженерия - превращение твоего конвейера в самообслуживаемый продукт для других команд. Конвейер ты уже строить умеешь. Теперь строй платформу.