프로젝트 CD 적용기 2 - 젠킨스 파이프라인 작성

최지환·2023년 2월 13일
2

프로젝트-모각코

목록 보기
6/7
post-thumbnail

첫 배포를 하기 위해서 CD(지속적인 배포 Continous Delivery)까지 적용을 하려고 했다.

이전 글에서 배포용 ec2 와 RDS 관련 설정을 해주었다.

현재 내 프로젝트의 작업 순서를 보면 다음과 같다.

feature 브랜치에서 로드 작성 → pr 생성 → CI 작업 → 머지

자동화를 해둔 부분은 CI 밖에 없었기 때문에, 미루고 미뤘던 CD를 해보기로 하였다.

나는 젠킨스의 멀티브랜치파이프 라인 을 통해서 각 브랜치를 관리 했고, 해당 파이프라인 스크립트는 다음과 같다.

pipeline {
    agent any
    options {
        disableConcurrentBuilds()
    }

    stages {
      
         stage('CHECK-OUT') {
            steps {
                git branch: env.GIT_BRANCH,
                        credentialsId: 'test',
                        url: 'https://github.com/kodesalon/HamKke'
            }
        }
      
            stage('runsonarqube'){
            steps{
                sh '''
                    echo runsonarqube
                     ./gradlew sonar \
                      -Dsonar.projectKey=hamkke \
                      -Dsonar.host.url=http://3.37.62.142:9000 \
                      -Dsonar.login=sqp_8b88bdf437937b274ff1ef9e7b3aec8301a88b43
                '''
            }
        }
      
        stage('build'){
            steps{
                sh '''
                    echo build start
                     ./gradlew clean build -Pprofile=ci
                '''
            }
        }
	   }
	}
}

CI 에서는 브랜치를 체크아웃하고, build를 실행하고 소나큐브를 통해 정적 코드 분석을 하는 작업을 해주었다.

이후 배포 자동화 프로세스를 하기 위해서 파이프라인을 수정하였다.

우선 main 브랜치를 배포하는 것이아닌 devlop 브랜치를 배포하는 것으로 테스트를 해보았다.

pipeline {
    agent any
    options {
        disableConcurrentBuilds()
    }

    stages {
             stage('CHECK-OUT') {
            steps {
                git branch: env.GIT_BRANCH,
                        credentialsId: 'test',
                        url: 'https://github.com/kodesalon/HamKke'
            }
        }
      
            stage('runsonarqube'){
            steps{
                sh '''
                    echo runsonarqube
                     ./gradlew sonar \
                      -Dsonar.projectKey=hamkke \
                      -Dsonar.host.url=http://3.37.62.142:9000 \
                      -Dsonar.login=sqp_8b88bdf437937b274ff1ef9e7b3aec8301a88b43
                '''
            }
        }
      
        stage('build'){
            steps{
                sh '''
                    echo build start
                     ./gradlew clean build -Pprofile=ci
                '''
            }
        }
      
      stage('DEPLOY'){
        when{
          expression {env.GIT_BRANCH == 'develop'}
        }
             
        steps{ 
			   withCredentials([sshUserPrivateKey(credentialsId: "pemkey", keyFileVariable: 'key')]) {
          	sh '''echo develop!!!!!!!!!!!@#
		              echo build start
					  ssh -oStrictHostKeyChecking=no -T -i ${key} ubuntu@배포ec2-IP "
					  cd /home/ubuntu/HamKke
					  git checkout develop
					  git pull
					  ./gradlew clean bootjar
					  cd /home/ubuntu/HamKke/build/libs
					  nohup java -jar -Dspring.profiles.active=deploy board-0.0.1-SNAPSHOT.jar &
					  "
					  echo build end
					  '''
    	    	}
        	}
	    }
	}
}

정상적으로 작동하는 것을 확인하였고, 최종적으로 main 브랜치에서의 배포가 될 수 있도록 수정을 해주면

pipeline {
    agent any
    options {
        disableConcurrentBuilds()
    }

    stages {
             stage('CHECK-OUT') {
            steps {
                git branch: env.GIT_BRANCH,
                        credentialsId: 'test',
                        url: 'https://github.com/kodesalon/HamKke'
            }
        }
      
            stage('runsonarqube'){
            steps{
                sh '''
                    echo runsonarqube
                     ./gradlew sonar \
                      -Dsonar.projectKey=hamkke \
                      -Dsonar.host.url=http://3.37.62.142:9000 \
                      -Dsonar.login=sqp_8b88bdf437937b274ff1ef9e7b3aec8301a88b43
                '''
            }
        }
      
        stage('build'){
            steps{
                sh '''
                    echo build start
                     ./gradlew clean build -Pprofile=ci
                '''
            }
        }
      
      stage('DEPLOY'){
        when{
          expression {env.GIT_BRANCH == 'main'}
        }
             
        steps{ 
			   withCredentials([sshUserPrivateKey(credentialsId: "pemkey", keyFileVariable: 'key')]) {
          		sh '''echo develop!!!!!!!!!!!@#
		              echo build start
					  ssh -oStrictHostKeyChecking=no -T -i ${key} ubuntu@43.201.95.31  "
					  cd /home/ubuntu/HamKke
					  git checkout main
					  git pull
					  ./gradlew clean bootjar
					  cd /home/ubuntu/HamKke/build/libs
					  nohup java -jar -Dspring.profiles.active=deploy board-0.0.1-SNAPSHOT.jar &
					  "
					  echo build end
					  '''
    	    	}
        	}
	    }
	}
}

완성.

CD 적용 하면서 알게 된점

키 등록 하기

배포 서버에 ssh 접속을 하기 위해서는 key 가 필요했다. 그래서 젠킨스가 설치된 리눅스에 key 값을 넣어주었고 실행을 했는데, jenkuns 가 리눅스의 키에 접근을 하지 못하는 문제가 발생했다. 따라서 젠킨스 내부에 Credentials 관리에 들어가 사용할 키 값을 입력해주어야 했다.

  1. Dashboard → jenkins 관리 → Credentials → (global) 에서 Add credentials 클릭

  1. SSH Username with private key 선택 후 필요한 값을 입력해줘야한다.

ID - 키 이름 설정

Username - 키를 사용하는 user의 이름이다. 나는 ubuntu로 했다.

Description - key를 넣어주면된다. 여기서 말하는 Key 는 암호화된 key의 원문이다.
아래와 같은 형태로 키가 있는데, 이 텍스트를 모두 복사해서 넣어주면 된다.

이렇게 젠킨스에서 사용할 키를 등록해줄 수 있다.

나는 키 이름을 pemkey 라는 이름으로 만들어 두었다.

이를 파이프라인에서 사용해보자.

파이프 라인에서 jenkins에 만들어둔 credentials를 사용하기 위해서는 특정 문법이 필요하다.

withCredentials( ) 를 이용해 파이프라인에서 키를 사용 할 수 있다. 이때 파라미터로 sshUserPrivateKey 로 만들어 credentials를 사용한다고 명시하고, credentialsId에 사용하려는 credentials를 명시하고, keyFileVariable으로 받아온 키 값의 변수를 지정할 수 있다.

받아온 변수는 ${ } 를 이용해 사용한다.

정리하자면 다음과 같은 형태로 사용한다.

withCredentials([sshUserPrivateKey(credentialsId: "젠킨스에 등록한 key ID", keyFileVariable: '파이프라인에서 사용하는 키의 이름 명')]){
ssh ${파이프라인에서 사용하는 키의 이름 명} ubuntu@주소
}

scp 실패 후, 다른 방법 적용

scp는 리눅스에서 원격지로 파일을 전송 할 수 있도록 해주는 명령어 이다.

$ scp test1.txt root@192.168.000.000:/test

위의 예시는 test1.txt 파일을 root@192.168.000.000 의 test 폴더에 전송화는 명령이다.

처음에는 나는 jenkins 서버에서 ci 작업을 하고, 빌드 후 jar 파일을 배포 서버에 전송을 하려고 했다.

하지만 문제가 발생하였다. 전송 까지는 잘 되었지만, 전송 후 배포 서버에 ssh 접근이 잘 되지 않았다.

여러가지로 테스트를 더 해보았는데 젠킨스에서 파이프라인 실행으로 ssh 와 scp를 연속으로 할 수 없었다. 순서를 바꿔 해봐도 안되었다.

원인을 찾으려 했으나. 찾을 수 없었다. 그래서 다른 방법으로 ssh 접속 1회 후, git을 통해서 파일을 내려받고 배포를 할 수 있도록 변경하였다.

리눅스는 아직 어렵다…

ssh 접속 후 다중 명령어 입력

젠킨스에서 배포 서버로 ssh 접속 후, 한번의 명령어 입력후 연결이 끊어지는 문제가 발생하였다.
찾아보니 ssh 접속하는 명령어 입력 시, “ “ 를 이용해 실행 시킬 명령어를 한번에 입력 할 수 있었다.

따라서 다음과 같이 작성하였다.

  ssh -oStrictHostKeyChecking=no -T -i ${key} ubuntu@ 배포 서버 IP 주소 "
					  명령어1,
						명령어2,
						명령어3
					  "

그 외에도 삽질을 정말 많이 했는데, 하고 나니가 진짜 속이 후련하다..!

0개의 댓글