본문 바로가기
반응형
DevOps/Jenkins

[Jenkins] pipeline script CI/CD

by brightGarden02 2024. 11. 4.

pipeline script를 적용하여 CI/CD를 구현한 캡쳐화면이다.

 

 

 

pipeline script를 단계별로 설명하려 한다.

pipeline {
    agent any
    tools {
        gradle '8.11'
    }
    ...
}

pipeline scipt의 시작 부분은 tools인 maven으로 할지, gradle로 할지 명시한다. 사용할 tool은 이미 설치가 되어 있어야 한다.

 

 

 

pipeline {
    ...
    environment {
        DOCKER_TAG = "latest"
        GITLAB_URL = "http://000.000.0.82:8081/test/test_cicd"
        REMOTE_SERVER = "garden@000.000.0.81"
        REMOTE_DIR = "/home/garden/test2"
        JAR = "management-0.0.1-SNAPSHOT.jar"
        NEXUS_DOCKER_URL = "000.000.0.83:9092"
        NEXUS_REPO = "user_management"
        NEXUS_URL = "000.000.0.83:9091"
        NEXUS_USERNAME = "admin"
        NEXUS_PASSWORD = "passwd"
        COMPOSE_FILE_PATH = "/home/garden"
    }
    ...
}

 

각 stage에 사용할 환경변수를 세팅한다. docker, nexus, remote_server, gitlab, docker-compose를 이용할 것이다.

(url에 있는 000 ip는 본인 ip를 적으면 된다.)

 

 

 

pipeline {
    ...
    stages {
        stage('Define Variables') {
            steps {
                script {
                    // 여러 이미지 이름을 배열로 관리
                    SERVICES = ['my-service1-image', 'my-service2-image']
                    
                    // 배포 서버 IP를 배열로 관리
                    DEPLOY_SERVERS = ['000.000.0.81', '000.000.0.83']
                }
            }
        }
    ...
    }
}

docker-compose를 이용하여 2개의 이미지를 배포할 예정이기에 SERVICES라는 배열에 2개의 이미지를 선언한다.

배포 서버는 81번, 83번에 배포할 예정이기에 DEPLOY_SERVERS 배열에 2개의 ip를 적는다.

 

 

 

pipeline {
    ...
    stages {
        ...
        stage('Git clone') {
            steps {
                git branch: 'feature/garden', credentialsId: 'abcdefg', url: "${GITLAB_URL}"
            }
            post {
                failure {
                    echo 'Repository clone failure!'
                }
                success {
                    echo 'Repository clone success!'
                }
            }
        }
        ...
    }
}

Git clone을 하기 위해 해당 branch, credentialId, url을 적는다.

credentialsId는 jenkins 관리에서 세팅 가능하다. 성공, 실패에 따라 echo로 출력하게 하였다.

 

 

 

pipeline {
    ...
    stages {
        ...
        stage('Gradle Build') {
            steps {
                dir("./") {
                    sh 'chmod +x ./gradlew'
                    sh './gradlew clean build'
                }
            }
            post {
                failure {
                    echo 'Gradle build failed!'
                }
                success {
                    echo 'Gradle build succeeded!'
                }
            }
        }
        ...
    }
}

gradlew에 대한 실행 권한을 부여하고 gradlew을 실행시킨다.

 

 

 

pipeline {
    ...
    stages {
        ...
        stage('Copy JAR and Dockerfile to Server') {
            steps {
                sshagent(credentials: ['abcdef']) {
                    sh """
                    scp build/libs/${JAR} ${REMOTE_SERVER}:${REMOTE_DIR}
                    scp Dockerfile ${REMOTE_SERVER}:${REMOTE_DIR}
                    """
                }
            }
            post {
                failure {
                    echo 'Failed to copy JAR and Dockerfile to server!'
                }
                success {
                    echo 'JAR and Dockerfile copied to server successfully!'
                }
            }
        }
        ...
    }
}

jenkins에서 build를 통해 만들어진 jar파일과, 프로젝트에 있던 Dockerfile을 원격서버로 가져온다.

 

 

 

pipeline {
	...
    stages {
        ...
        stage('Docker Build & Push for Services') {
            steps {
                script {
                    for (service in SERVICES) {
                        echo "Building and pushing ${service}..."
                        sh """
                        ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} 'cd ${REMOTE_DIR} && docker build -t ${service}:${DOCKER_TAG} .'
                        ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} 'docker tag ${service}:${DOCKER_TAG} ${NEXUS_DOCKER_URL}/repository/${NEXUS_REPO}/${service}:${DOCKER_TAG}'
                        ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} 'docker push ${NEXUS_DOCKER_URL}/repository/${NEXUS_REPO}/${service}:${DOCKER_TAG}'
                        """
                    }
                }
            }
            post {
                failure {
                    echo 'Docker build or push for services failed!'
                }
                success {
                    echo 'Docker build and push for services succeeded!'
                }
            }
        }
    	...
    }
}

원격서버에서 각각의 image이름으로 docker image를 만들고 tag로 버전 이름을 붙인다.

해당 image를 nexus에 저장한다.

 

 

 

pipeline {
    ...
    stages {
        ...
        stage('Docker Login to Nexus') {
            steps {
                sh """
                ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} 'echo ${NEXUS_PASSWORD} | docker login ${NEXUS_DOCKER_URL} --username ${NEXUS_USERNAME} --password-stdin'
                """
            }
            post {
                failure {
                    echo 'Docker login to Nexus failed!'
                }
                success {
                    echo 'Docker login to Nexus succeeded!'
                }
            }
        }
        ...
    }
}

 

Docker Login을 통해 Nexus에 로그인한다.

 

 

 

pipeline {
    ...
    stages {
        ...
        stage('Deploy with Docker Compose') {
            steps {
                script {
                    echo 'Deploying with Docker Compose...'
                    for (server in DEPLOY_SERVERS) {
                        echo "Deploying to ${server}..."
                        
                        sh """
                        ssh -o StrictHostKeyChecking=no -i /var/jenkins_home/.ssh/id_rsa garden@${server} << EOF
                        
                            cd ${COMPOSE_FILE_PATH}
                            docker-compose down
                            docker-compose up -d
EOF
                        """
                    }
                }
            }
            post {
                failure {
                    echo 'Deployment to server failed!'
                }
                success {
                    echo 'Deployment to server succeeded!'
                }
            }
        }
    }
}

Docker-compose를 통한 배포하는 단계이다.

jenkins에서 rsa키를 가지고 garden 계정으로 DEPLOY_SERVERS 배열에 있는 각 서버에 접근한다.

docker-compose 파일 경로로 이동하여 docker-compose를 내리고 다시 올린다.

 

 

 

전체 pipeline script

pipeline {
    agent any
    tools {
        gradle '8.11'
    }
    environment {
        DOCKER_TAG = "latest"
        GITLAB_URL = "http://000.000.0.82:8081/test/test_cicd"
        REMOTE_SERVER = "garden@000.000.0.81"
        REMOTE_DIR = "/home/garden/test2"
        JAR = "management-0.0.1-SNAPSHOT.jar"
        NEXUS_DOCKER_URL = "000.000.0.83:9092"
        NEXUS_REPO = "user_management"
        NEXUS_URL = "000.000.0.83:9091"
        NEXUS_USERNAME = "admin"
        NEXUS_PASSWORD = "passwd"
        COMPOSE_FILE_PATH = "/home/garden"
    }
    stages {
        stage('Define Variables') {
            steps {
                script {
                    // 여러 이미지 이름을 배열로 관리
                    SERVICES = ['my-service1-image', 'my-service2-image']
                    
                    // 배포 서버 IP를 배열로 관리
                    DEPLOY_SERVERS = ['000.000.0.81', '000.000.0.83']
                }
            }
        }
        stage('Git clone') {
            steps {
                git branch: 'feature/garden', credentialsId: 'abcdef', url: "${GITLAB_URL}"
            }
            post {
                failure {
                    echo 'Repository clone failure!'
                }
                success {
                    echo 'Repository clone success!'
                }
            }
        }
        stage('Gradle Build') {
            steps {
                dir("./") {
                    sh 'chmod +x ./gradlew'
                    sh './gradlew clean build'
                }
            }
            post {
                failure {
                    echo 'Gradle build failed!'
                }
                success {
                    echo 'Gradle build succeeded!'
                }
            }
        }
        stage('Copy JAR and Dockerfile to Server') {
            steps {
                sshagent(credentials: ['abcdef']) {
                    sh """
                    scp build/libs/${JAR} ${REMOTE_SERVER}:${REMOTE_DIR}
                    scp Dockerfile ${REMOTE_SERVER}:${REMOTE_DIR}
                    """
                }
            }
            post {
                failure {
                    echo 'Failed to copy JAR and Dockerfile to server!'
                }
                success {
                    echo 'JAR and Dockerfile copied to server successfully!'
                }
            }
        }
        stage('Docker Build & Push for Services') {
            steps {
                script {
                    for (service in SERVICES) {
                        echo "Building and pushing ${service}..."
                        sh """
                        ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} 'cd ${REMOTE_DIR} && docker build -t ${service}:${DOCKER_TAG} .'
                        ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} 'docker tag ${service}:${DOCKER_TAG} ${NEXUS_DOCKER_URL}/repository/${NEXUS_REPO}/${service}:${DOCKER_TAG}'
                        ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} 'docker push ${NEXUS_DOCKER_URL}/repository/${NEXUS_REPO}/${service}:${DOCKER_TAG}'
                        """
                    }
                }
            }
            post {
                failure {
                    echo 'Docker build or push for services failed!'
                }
                success {
                    echo 'Docker build and push for services succeeded!'
                }
            }
        }
        stage('Docker Login to Nexus') {
            steps {
                sh """
                ssh -o StrictHostKeyChecking=no ${REMOTE_SERVER} 'echo ${NEXUS_PASSWORD} | docker login ${NEXUS_DOCKER_URL} --username ${NEXUS_USERNAME} --password-stdin'
                """
            }
            post {
                failure {
                    echo 'Docker login to Nexus failed!'
                }
                success {
                    echo 'Docker login to Nexus succeeded!'
                }
            }
        }
        stage('Deploy with Docker Compose') {
            steps {
                script {
                    echo 'Deploying with Docker Compose...'
                    for (server in DEPLOY_SERVERS) {
                        echo "Deploying to ${server}..."
                        
                        sh """
                        ssh -o StrictHostKeyChecking=no -i /var/jenkins_home/.ssh/id_rsa garden@${server} << EOF
                        
                            cd ${COMPOSE_FILE_PATH}
                            docker-compose down
                            docker-compose up -d
EOF
                        """
                    }
                }
            }
            post {
                failure {
                    echo 'Deployment to server failed!'
                }
                success {
                    echo 'Deployment to server succeeded!'
                }
            }
        }
    }
}

'DevOps > Jenkins' 카테고리의 다른 글

[Jenkins] 시간 설정 방법(Time zone)  (0) 2024.10.25

댓글


반응형
반응형