
Всем привет! Я — 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. Если нужна помощь с настройкой, пишите — разберемся вместе.
Готово! Ваши идеи — в комментариях!
