Как стать автором
Обновить

Автоматизация деплоя: из Bitbucket через Jenkins в MicroK8s — опыт финтех-разработчика

Уровень сложностиСредний
Время на прочтение9 мин
Количество просмотров715
Автоматизация — как дорога в облаках: красиво, но требует точной навигации.
Автоматизация — как дорога в облаках: красиво, но требует точной навигации.

Всем привет! Я — 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

Перед установкой убедитесь, что у вас установлены:

  1. Java (OpenJDK) — Bitbucket требует Java 8 или 11.

  2. Git — для работы с репозиториями.

  3. База данных (например, 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

  1. Перейдите на официальный сайт Atlassian и найдите последнюю версию Bitbucket Server (например, 8.9.0 на момент написания). Скачайте бинарный файл для Linux:

wget https://www.atlassian.com/software/stash/downloads/binary/atlassian-bitbucket-8.9.0-x64.bin
  1. Примечание: Замените 8.9.0 на актуальную версию.

  2. Сделайте файл исполняемым:

chmod +x atlassian-bitbucket-8.9.0-x64.bin

Шаг 4: Установка Bitbucket

  1. Запустите установщик

sudo ./atlassian-bitbucket-8.9.0-x64.bin 
  1. Следуйте инструкциям в терминале:

    • Нажмите 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 для начала установки.

  2. После завершения установщик предложит запустить Bitbucket. Выберите n (настроим вручную позже).

Шаг 5: Настройка базы данных (PostgreSQL)

  1. Создайте пользователя и базу данных для 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

  1. Назначьте права на директории:

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

  1. Откройте http://<IP>:7990

  2. Создайте администратора и настройте базу данных (по умолчанию используется встроенная H2).

  3. Создайте проект SPRIN и репозиторий spring-app.

  4. Загрузите исходный код

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

  1. Откройте http://<IP>:8080 и используйте начальный пароль из /var/lib/jenkins/secrets/initialAdminPassword.

  2. Создайте администратора.

  3. Установите плагины:

    • 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. Вот пошаговая инструкция:

  1. Установите необходимые плагины:

    • Зайдите в Manage Jenkins → Manage Plugins.

    • Установите плагины:

      • Git Plugin — для работы с Bitbucket.

      • Maven Integration Plugin — для сборки проекта.

      • Docker Pipeline — для работы с Docker.

      • Pipeline — для поддержки Jenkinsfile.

    • Перезапустите Jenkins после установки: http://<ваш_IP>:8080/restart.

  2. Настройте инструменты:

    • Перейдите в Manage Jenkins → Global Tool Configuration.

    • JDK: Добавьте установку JDK (например, JDK11), укажите имя JDK.

    • Maven: Добавьте Maven (например, Maven), выберите версию (например, 3.8.6).

  3. Добавьте учетные данные для Bitbucket:

    • В Manage Jenkins → Manage Credentials → System → Global credentials нажмите Add Credentials.

    • Тип: Username with password.

    • Username: username (ваш логин Bitbucket).

    • Password: ваш App Password (токен).

    • ID: bitbucket-credentials.

    • Сохраните.

  4. Создайте новую джобу:

    • На главной странице Jenkins выберите New Item.

    • Введите имя (например, spring-app-deploy).

    • Выберите тип Pipeline и нажмите OK.

  5. Настройте джобу:

  6. Запустите сборку:

    • Нажмите 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!".

Анализ проблем и лучшие практики

Проблемы:

  1. Аутентификация: Пароли ненадежны, токены решают проблему.

  2. Порты: Статические значения приводят к сбоям.

  3. Отладка: Без логов сложно найти ошибки.

Решения:

  • Перешел на токены.

  • Использовал динамические порты.

  • Добавил вывод HTTP-кодов.

Лучшие практики:

  • Токены: Безопаснее паролей

Заключение

Автоматизация деплоя из Bitbucket через Jenkins в MicroK8s — это не только экономия времени, но и вызовы, которые учат внимательности. Мой опыт показал, что с правильными инструментами и подходом можно построить надежный пайплайн. Настройте свой CI/CD и забудьте про ручной деплой!

Какой у вас был самый сложный баг в CI/CD? Делитесь в комментариях — обсудим!

P.S. Если нужна помощь с настройкой, пишите — разберемся вместе.

Готово! Ваши идеи — в комментариях!

Теги:
Хабы:
+5
Комментарии4

Публикации

Истории

Работа

Ближайшие события

25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань
20 – 22 июня
Летняя айти-тусовка Summer Merge
Ульяновская область