Назад к вопросам
Middle
67
questionbank

Как версионировать образы и интегрировать это с Jenkins?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Существуют различные стратегии версионирования образов:

  1. Семантическое версионирование: Используем MAJOR.MINOR.PATCH.

    • MAJOR: Значительные изменения (ломающие обратную совместимость).
    • MINOR: Новые возможности (обратно совместимые).
    • PATCH: Исправления ошибок (обратно совместимые).
  2. Версионирование по хэшу Git: Используем полный или сокращенный хэш последнего комита. Гарантирует уникальность.

  3. Версионирование по номеру сборки Jenkins: Используем автоинкрементный номер сборки Jenkins. Просто, но не привязано к исходному коду напрямую.

  4. Комбинированное версионирование: Сочетание, например, app_version-jenkins_build или app_version-git_commit.

Интеграция с Jenkins включает следующие шаги:

  1. Получение версии: В пайплайне Jenkins определяем версию образа. Это может быть:

    • Чтение версии из файла проекта (package.json, pom.xml и т.д.).
    • Получение хэша комита Git (git rev-parse HEAD).
    • Использование переменной окружения Jenkins ($BUILD_NUMBER).
  2. Сборка образа с тегом: Используем команду docker build с опцией -t для присвоения тега образу.

    # Dockerfile
    FROM ubuntu:latest
    COPY . /app
    # ...
    

    В Jenkinsfile:

    // Jenkinsfile
    pipeline {
        agent any
        stages {
            stage('Build Docker Image') {
                steps {
                    script {
                        def appVersion = sh(returnStdout: true, script: 'cat VERSION').trim() // Пример чтения из файла
                        def gitHash = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim() // Пример получения Git хэша
                        def imageTag = "${appVersion}-${gitHash}-${env.BUILD_NUMBER}" // Комбинированный тег
    
                        sh "docker build -t my-app:${imageTag} ."
                    }
                }
            }
        }
    }
    
  3. Разметка (tagging) для репозитория (опционально): Для удобства можно создать дополнительные теги, например latest или тег для окружения (dev, staging, prod).

    // В том же стейдже или новом
    steps {
        script {
            def imageTag = "${sh(returnStdout: true, script: 'cat VERSION').trim()}-${sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()}-${env.BUILD_NUMBER}"
            sh "docker build -t my-app:${imageTag} ."
            sh "docker tag my-app:${imageTag} my-registry/my-app:latest" // Добавление тега latest
        }
    }
    
  4. Push образа в репозиторий: Используем команду docker push с тегом.

    // В новом стейдже Push Docker Image
    stage('Push Docker Image') {
        steps {
            script {
                def imageTag = "${sh(returnStdout: true, script: 'cat VERSION').trim()}-${sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()}-${env.BUILD_NUMBER}"
                sh "docker push my-registry/my-app:${imageTag}"
                sh "docker push my-registry/my-app:latest" // Push тега latest
            }
        }
    }
    
  5. Применение в развертывании: В файлах манифеста (Kubernetes, Docker Compose) используем переменные окружения Jenkins или другие механизмы для указания нужной версии образа.

    # Kubernetes deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-app
    spec:
      replicas: 3
      template:
        spec:
          containers:
          - name: my-app
            image: my-registry/my-app:${IMAGE_TAG} # Использование переменной окружения
            ports:
            - containerPort: 8080
    

    В Jenkinsfile, при развертывании:

    // В стейдже Deployment
    stage('Deploy to Kubernetes') {
        environment {
            IMAGE_TAG = "${sh(returnStdout: true, script: 'cat VERSION').trim()}-${sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()}-${env.BUILD_NUMBER}"
        }
        steps {
            sh "kubectl apply -f deployment.yaml --namespace my-namespace"
        }
    }
    

Выбор конкретной стратегии версионирования зависит от требований проекта и команды. Комбинированный подход часто обеспечивает хорошую прослеживаемость от образа до исходного кода и номера сборки.