
Всем привет! Я — Java-разработчик с пятилетним опытом в финтехе, и сегодня я расскажу, как настроить CI/CD для деплоя Spring Boot приложения из Bitbucket через Jenkins в MicroK8s. Это не просто теория — я поделюсь реальным кейсом, разберу ошибки, с которыми столкнулся, и дам рабочий код. Если вы хотите автоматизировать деплой и не наступать на грабли — поехали!
Представьте: у вас есть микросервис на Spring Boot, который нужно быстро и без ошибок доставить в продакшен. Ручной деплой отнимает время, а команда требует стабильности. Я решил эту задачу с помощью Bitbucket, Jenkins и MicroK8s, но путь оказался не таким гладким, как хотелось бы. Проблемы с аутентификацией, конфликты портов и настройка окружения заставили меня попотеть. Как я справился? Об этом — в статье.
CI/CD (Continuous Integration/Continuous Deployment) — это must-have для современных разработчиков. Автоматизация сборки, тестирования и деплоя приложений экономит время, снижает вероятность ошибок и ускоряет доставку кода до продакшена. В этой статье мы разберем, как настроить полноценный CI/CD-пайплайн для Spring Boot приложения, используя связку Bitbucket, Jenkins и MicroK8s.
Зачем именно эти инструменты?
Bitbucket — удобный сервис для управления Git-репозиториями с поддержкой приватных проектов.
Jenkins — мощный и гибкий инструмент для автоматизации CI/CD с огромным количеством плагинов.
MicroK8s — легковесный Kubernetes для локальных и небольших серверов, идеальный для разработки и тестирования.
Мы развернем инфраструктуру на одном сервере, настроим пайплайн для сборки Spring Boot приложения, его деплоя в Docker-реестр MicroK8s и запуска в кластере. В конце вы получите работающее приложение, доступное через браузер.
Подготовим сервер
Установка ОС
Для примера возьмем Ubuntu 24.04 LTS — стабильную и популярную систему для серверов.
Далее обновим пакеты:
# Обновляем пакеты
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl net-tools
Развернем Bitbucket
Установка Bitbucket
Перед установкой убедитесь, что у вас установлены:
Java (OpenJDK) — Bitbucket требует Java 8 или 11.
Git — для работы с репозиториями.
База данных (например, PostgreSQL) — для хранения данных Bitbucket.
Шаг 1: Установите OpenJDK 11
sudo apt install -y openjdk-11-jdk
Проверьте версию Java:
java -version
Установите Git:
sudo apt install -y git
Проверьте версию Git:
git --version
Установите PostgreSQL (опционально, если используете внешнюю БД):
sudo apt install -y postgresql postgresql-contrib
Запустите и включите PostgreSQL:
sudo systemctl start postgresql
sudo systemctl enable postgresql
Шаг 2: Создание пользователя для Bitbucket
Bitbucket рекомендуется запускать от имени непривилегированного пользователя:
sudo useradd -m -s /bin/bash bitbucket
sudo passwd bitbucket # Установите пароль (опционально)
Шаг 3: Скачивание Bitbucket
Перейдите на официальный сайт Atlassian и найдите последнюю версию Bitbucket Server (например, 8.9.0 на момент написания). Скачайте бинарный файл для Linux:
wget https://www.atlassian.com/software/stash/downloads/binary/atlassian-bitbucket-8.9.0-x64.bin
Примечание: Замените 8.9.0 на актуальную версию.
Сделайте файл исполняемым:
chmod +x atlassian-bitbucket-8.9.0-x64.bin
Шаг 4: Установка Bitbucket
Запустите установщик
sudo ./atlassian-bitbucket-8.9.0-x64.bin
Следуйте инструкциям в терминале:
Нажмите Enter для продолжения.
Выберите тип установки: 1 (стандартная установка) или 2 (Data Center).
Укажите директорию установки (по умолчанию /opt/atlassian/bitbucket/8.9.0): нажмите Enter или введите свой путь.
Укажите домашнюю директорию данных (по умолчанию /var/atlassian/application-data/bitbucket): нажмите Enter.
Выберите порты: HTTP (7990) и Control (8005) — оставьте по умолчанию или измените.
Установите Bitbucket как службу: выберите y и нажмите Enter.
Нажмите Enter для начала установки.
После завершения установщик предложит запустить Bitbucket. Выберите n (настроим вручную позже).
Шаг 5: Настройка базы данных (PostgreSQL)
Создайте пользователя и базу данных для Bitbucket
sudo -u postgres psql
Внутри psql выполните:
CREATE USER bitbucketuser WITH PASSWORD 'yourpassword';
CREATE DATABASE bitbucketdb OWNER bitbucketuser ENCODING 'UTF8';
\q
Отредактируйте файл конфигурации Bitbucket:
sudo nano /var/atlassian/application-data/bitbucket/shared/bitbucket.properties
Добавьте настройки базы данных:
jdbc.driver=org.postgresql.Driver
jdbc.url=jdbc:postgresql://localhost:5432/bitbucketdb
jdbc.user=bitbucketuser
jdbc.password=yourpassword
Шаг 6: Запуск Bitbucket
Назначьте права на директории:
sudo chown -R bitbucket:bitbucket /opt/atlassian/bitbucket/8.9.0
sudo chown -R bitbucket:bitbucket /var/atlassian/application-data/bitbucket
Запустите Bitbucket как службу:
sudo /opt/atlassian/bitbucket/8.9.0/bin/start-bitbucket.sh
Проверьте статус:
ps aux | grep bitbucket
Откройте порты в фаерволе:
sudo ufw allow 7990, 8005, 5432
Шаг 7: Доступ к Bitbucket
Откройте браузер и перейдите по адресу:
http://<ваш_IP>:7990
Следуйте инструкциям веб-мастера установки:
Введите лицензионный ключ (получите пробный на сайте Atlassian).
Настройте администраторский аккаунт.
Дополнительно: Остановка Bitbucket
Если нужно остановить:
sudo /opt/atlassian/bitbucket/8.9.0/bin/stop-bitbucket.sh
Конфигурация Bitbucket
Откройте http://<IP>:7990
Создайте администратора и настройте базу данных (по умолчанию используется встроенная H2).
Создайте проект SPRIN и репозиторий spring-app.
Загрузите исходный код
SSH-ключи для Jenkins
Сгенерируйте SSH-ключ для Jenkins:
ssh-keygen -t rsa -b 4096 -C "jenkins@server" -f ~/.ssh/jenkins_bitbucket
Добавьте публичный ключ (~/.ssh/jenkins_bitbucket.pub) в настройки Bitbucket (Settings → SSH Keys).
Развернем Jenkins
Шаг 1: Установка Jenkins на хост
Для упрощения интеграции с MicroK8s и управления правами рекомендуем установить Jenkins непосредственно на хост:
sudo apt update
wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt install -y openjdk-17-jre jenkins
sudo systemctl start jenkins
sudo systemctl enable jenkins
Jenkins будет доступен на http://<IP>:8080.
Шаг 2: Настройка Jenkins
Откройте http://<IP>:8080 и используйте начальный пароль из /var/lib/jenkins/secrets/initialAdminPassword.
Создайте администратора.
Установите плагины:
Git Plugin — для Bitbucket.
Docker Pipeline — для работы с Docker.
Kubernetes CLI Plugin — для MicroK8s.
Шаг 3: Интеграция с Bitbucket
Добавьте учетные данные в Manage Jenkins → Manage Credentials:
Тип: Username with password.
ID: bitbucket-credentials.
Логин/пароль от Bitbucket.
Шаг 4: Права для MicroK8s
Добавьте пользователя jenkins в группу microk8s:
sudo usermod -a -G microk8s jenkins
sudo systemctl restart jenkins
Развернем MicroK8s
Шаг 1: Установка MicroK8s на хост
MicroK8s лучше ставить на хост для упрощения доступа к локальному реестру и kubectl:
sudo snap install microk8s --classic
sudo usermod -a -G microk8s $USER
newgrp microk8s
Шаг 2: Активация компонентов
Включите аддоны:
microk8s enable dns storage registry
registry создает локальный реестр на localhost:32000.
Пример сервиса для развертывания
Исходный код
Пример Spring Boot приложения:
DemoApplication.java
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class DemoApplication {
@GetMapping("/")
public String home() {
return "Spring is here!";
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>springApp</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.3</version>
</parent>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Dockerfile
FROM openjdk:17-jdk-slim
WORKDIR /app
COPY target/demo-1.0.0.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
Загрузите код в Bitbucket.
Настройка Jenkins Pipeline
Jenkins забирает код, собирает JAR, строит Docker-образ и отправляет его в MicroK8s.
Jenkinsfile:
pipeline {
agent any
tools {
maven 'Maven'
jdk 'JDK'
}
environment {
REGISTRY = 'localhost:32000'
IMAGE_NAME = 'spring-app'
IMAGE_TAG = "${env.BUILD_NUMBER}"
}
stages {
stage('Checkout') {
steps {
git url: 'http://bitbucket.mydisk.keenetic.link:7990/scm/SPRIN/spring-app.git',
branch: 'master',
credentialsId: 'bitbucket-credentials'
}
}
stage('Build') {
steps {
withEnv(["JAVA_HOME=${tool 'JDK'}", "PATH+MAVEN=${tool 'Maven'}/bin"]) {
sh 'mvn clean package'
}
}
}
stage('Test') {
steps {
withEnv(["JAVA_HOME=${tool 'JDK'}", "PATH+MAVEN=${tool 'Maven'}/bin"]) {
sh 'mvn test'
}
}
}
stage('Build Docker Image') {
steps {
sh 'ls -la target/'
sh "docker build --no-cache -t ${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} ."
sh "docker push ${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}"
}
}
stage('Deploy to MicroK8s') {
steps {
script {
sh """
microk8s kubectl set image deployment/spring-app spring-app=${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} -n default
microk8s kubectl rollout status deployment/spring-app -n default
"""
}
}
}
}
post {
success {
echo 'Build completed successfully!'
}
failure {
echo 'Build failed!'
}
}
}
Настройка Jenkins
Шаги по созданию джобы в Jenkins
Чтобы запустить этот пайплайн, нужно настроить джобу в Jenkins. Вот пошаговая инструкция:
Установите необходимые плагины:
Зайдите в Manage Jenkins → Manage Plugins.
Установите плагины:
Git Plugin — для работы с Bitbucket.
Maven Integration Plugin — для сборки проекта.
Docker Pipeline — для работы с Docker.
Pipeline — для поддержки Jenkinsfile.
Перезапустите Jenkins после установки: http://<ваш_IP>:8080/restart.
Настройте инструменты:
Перейдите в Manage Jenkins → Global Tool Configuration.
JDK: Добавьте установку JDK (например, JDK11), укажите имя JDK.
Maven: Добавьте Maven (например, Maven), выберите версию (например, 3.8.6).
Добавьте учетные данные для Bitbucket:
В Manage Jenkins → Manage Credentials → System → Global credentials нажмите Add Credentials.
Тип: Username with password.
Username: username (ваш логин Bitbucket).
Password: ваш App Password (токен).
ID: bitbucket-credentials.
Сохраните.
Создайте новую джобу:
На главной странице Jenkins выберите New Item.
Введите имя (например, spring-app-deploy).
Выберите тип Pipeline и нажмите OK.
Настройте джобу:
В разделе General:
Поставьте галочку GitHub project (опционально) и укажите URL репозитория: http://bitbucket.example.com:8929/scm/SPRIN/spring-boot-starter-kafka-project.git.
В разделе Pipeline:
Выберите Pipeline script from SCM.
SCM: Git.
Repository URL: http://bitbucket.example.com:8929/scm/SPRIN/spring-boot-starter-kafka-project.git.
Credentials: выберите bitbucket-credentials.
Branch: master.
Script Path: Jenkinsfile.
Сохраните.
Запустите сборку:
Нажмите Build Now.
Следите за прогрессом в Console Output. Если все настроено верно, вы увидите выполнение этапов: Checkout, Build, Docker Build, Deploy.
Настройка Deployment в Microk8s
Разворачиваем приложение с помощью Deployment и Service, используя динамические порты.
Манифесты:
Deployment
# spring-app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-app
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: spring-app
template:
metadata:
labels:
app: spring-app
spec:
containers:
- name: spring-app
image: localhost:32000/spring-app:1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 7070
Service
# spring-app-service.yaml
apiVersion: v1
kind: Service
metadata:
name: spring-app-service
namespace: default
spec:
selector:
app: spring-app
ports:
- protocol: TCP
port: 7070
targetPort: 7070
nodePort: 30007
type: NodePort
Примените манифесты через командную строку:
microk8s kubectl apply -f spring-app-deployment.yaml
microk8s kubectl apply -f spring-app-service.yaml
Проверка и отладка CI CD конвейера
Логи Jenkins
sudo journalctl -u jenkins
Статус деплоя
microk8s kubectl get pods -n default
microk8s kubectl logs <pod-name> -n default
Доступ
Откройте http://<IP>:30007/ Увидите "Spring is here!".
Анализ проблем и лучшие практики
Проблемы:
Аутентификация: Пароли ненадежны, токены решают проблему.
Порты: Статические значения приводят к сбоям.
Отладка: Без логов сложно найти ошибки.
Решения:
Перешел на токены.
Использовал динамические порты.
Добавил вывод HTTP-кодов.
Лучшие практики:
Токены: Безопаснее паролей
Заключение
Автоматизация деплоя из Bitbucket через Jenkins в MicroK8s — это не только экономия времени, но и вызовы, которые учат внимательности. Мой опыт показал, что с правильными инструментами и подходом можно построить надежный пайплайн. Настройте свой CI/CD и забудьте про ручной деплой!
Какой у вас был самый сложный баг в CI/CD? Делитесь в комментариях — обсудим!
P.S. Если нужна помощь с настройкой, пишите — разберемся вместе.
Готово! Ваши идеи — в комментариях!