인프라/CI-CD

Jenkins, GItLab을 활용한 자동빌드 구현

2023. 4. 25. 00:02
글 목차


728x90

ec2가 있다면 가능한 얘기다

0. 스프링부트 프로젝트 하나 만들어서 깃랩에 올리기
1. ec2의 메모리가 작다면 늘려준다(선택사항) aws프리티어는 꼭 해줘야 함
2. 도커를 설치한다.
3. 젠킨스 컨테이너 만들기
4. 젠킨스 플러그인 추가
5. 젠킨스 크레덴셜 만들기
6. 젠킨스 파이프라인 아이템 만들기
7. 젠킨스 파이프라인 깃 클론 및 빌드 스크립트 작성
8. 젠킨스 파이프라인에 웹훅 트리거 걸기
8. 깃랩에서 웹훅 만들기
9. 깃랩에 프로젝트폴더 안에 도커파일 생성
10. 젠킨스 파이프라인에 이전 이미지와 컨테이너를 삭제하고
    도커파일을 바탕으로 이미지파일 만드는 스크립트 작성
11. 젠킨스 파이프라인에 이미지파일로 컨테이너 만드는 스크립트 작성
12. 깃랩에서 푸쉬 해보기

 

0. 스프링부트 프로젝트 하나 만들어서 깃랩에 올리기

그냥 만들면 된다.

이렇게 index.html이 나오는 스프링부트 프로젝트를 깃랩에 그냥 만들어둔다. 포트번호는 9999로 했지만 별상관없다.

이 프로젝트를 깃랩에 올린다.

 

1. ec2를 만들어서 메모리를 늘려 준다.

메모리를 늘리는 법은 다음과 같다.

 

$ sudo dd if=/dev/zero of=/swapfile bs=128M count=16

1. 스왑 파일 생성

$ sudo chmod 600 /swapfile

2. 스왑 파일에 대한 읽기 및 쓰기 권한을 업데이트

$ sudo mkswap /swapfile

3. Linux 스왑 영역을 설정

$ sudo swapon /swapfile

4. 스왑 공간에 스왑 파일을 추가하여 스왑 파일을 즉시 사용할 수 있도록 만든다

$ sudo swapon -s

5. 절차가 성공했는지 확인

$ sudo vi /etc/fstab

6. 파일을 편집하여 부팅 시 스왑 파일을 활성화

/swapfile swap swap defaults 0 0

편집기에서 파일을 연 후 파일 끝에 다음 줄을 새로 추가하고 파일을 저장한 다음 종료한다.

 

free -h로 늘어난 메모리를 확인 2기가가 늘어났다.

 

2. 도커 설치

도커 설치는 그냥 공식 문서를 따라가자

https://docs.docker.com/engine/install/ubuntu/

 

Install Docker Engine on Ubuntu

 

docs.docker.com

 

sudo docker run hello-world

를 했을 때 정확히 설치 되었다는 안내가 나오면 성공이다.


3.젠킨스 컨테이너 만들기

sudo docker run -d --name jenkins -p 7777:8080 -v /jenkins:/var/jenkins_home -v /usr/bin/docker:/usr/bin/docker -v /var/run/docker.sock:/var/run/docker.sock -u root jenkins/jenkins:lts

를 치면 젠킨스 컨테이너를 만들 수 있다 옵션들은 그냥 검색하면된다.

이후

sudo usermod -aG docker root

이걸친다. 명령어 잘 인식된다면, 젠킨스와 ec2의 도커가 연결되었다는 의미(젠킨스에 도커 설치 안했는데도 젠킨스가 도커 명령어를 인식했으므로)

 

 

4. 젠킨스 플러그인 추가

젠킨스 플러그인은 자동으로 설치되는 플러그인과 내가 메뉴얼하게 설치하는 게 있다. 포트 번호 7777로 들어가자

이런 화면이 뜨는데 '젠킨스 컨테이너 안에서' cat으로 빨갛게 표시된 파일을 읽으면 비밀번호가 나온다

suggested plugins을 설치한다

다 파란불이 떠야 정상이다

아무거나 입력하자

 

이제 젠킨스를 시작할 수 있는데

젠킨스 관리 -> 플러그인 관리 -> available plugins 에서  gitlab을 검색해서 webhook triger와 gitlab플러그인을 설치한다

install without restart를 하면 된다.

 

(추가) SSH Agent Plugin 도 설치하자 이는 jenkins 컨테이너에서 직접적으로 ec2의 도커에 접근하지 못할경우 pem 키를 가지고 ec2에 접속하여 쉘명령을 하기 위해서다

 

5.젠킨스 크레덴셜 만들기

젠킨스 관리 -> Manage Credential -> System -> Global Credential -> add Credential을 통해 Credential을 만든다.

유저네임은 이메일에서 아이디 부분이다. 패스워드는 패스워드다.

ID는 크레덴셜의 이름이다. 이크레덴셜로 깃 로그인을 대신한다. 로그인을 하면 권한이 있는 리포지토리의 클론을 할 수 있다.

 

(추가) -ec2_ssh_key : 서버에 접근하기 위한 권한

kind 에서 SSH Username with private key 선택후 ID(임으로 설정), Username(키를 받은 우분투 유저 이름 , 보통 Ubuntu), Description (설명)을 입력한 후

받은 서버 키를 입력해준다. ----BEGIN RSA PRIVATE KEY---—랑 ----END RSA PRIVATE KEY---—까지 포함해서 다 복붙해서 넣어준다.

kind 에서 SSH Username with private key 선택후 ID(임으로 설정), Username(키를 받은 우분투 유저 이름 , 보통 Ubuntu), Description (설명)을 입력한 후

받은 서버 키를 입력해준다. ----BEGIN RSA PRIVATE KEY---—랑 ----END RSA PRIVATE KEY---—까지 포함해서 다 복붙해서 넣어준다.

 

6. 젠킨스 파이프라인 아이템 만들기

jenkins홈에서 새로운 아이템 만들기를 클릭해서 파이프라인으로 아이템을 만든다.

파이프라인 스크립트에 헬로우 월드를 쓰고

빌드를 해보자

 

7. 깃 클론 및 빌드 스크립트 작성

여기까지 왔다면 이제 깃 클론을 시도 할 수 있다.

Pipeline Syntax로 들어가자

Sample stap을 Git:git으로 바꾸고

옵션을 다 채웠을 때 이렇게 빨간불이 들어오면 실패다 안들어 오게 Credential을 만들면서 수정해 보자 나같은 경우에는 Gitlab username이 이메일의 앞부분 password가 이메일 이었는데 다른사람은 패스워드가 그냥 패스워드였다.

 

성공한 크레덴셔을 가지고 스크립트를 이렇게 수정한다.

pipeline {
    agent any

    stages {
        stage('gitlab clone') {
            steps {
                echo '클론을 시작할게요!'
                git branch: 'master', credentialsId: 'gitlab4', url: 'https://lab.ssafy.com/sogo.git'
                echo '클론을 완료했어요!'
            }
        }
    }
}

성공 지금 빌드를 눌러 성공했는지 파악한다. 성공하지 못했다면 빨간불이 뜨는 크레덴셜을 사용한 가능성이 높다.

이제 빌드를 해보자

스크립트에 몇줄 더 추가 해보자

pipeline {
    agent any

    stages {
        stage('gitlab clone') {
            steps {
                echo '클론을 시작할게요!'
                git branch: 'master', credentialsId: 'gitlab4', url: 'https://lab.ssafy.com/siganshoyou/jenkinsgogo.git'
                echo '클론을 완료했어요!'
            }
        }
        stage('build') {
            steps {
                echo '빌드를 시작할게요!'
                sh '''
                chmod +x /var/jenkins_home/workspace/jenkinsgogo/gradlew
          		// cd gradlew가 있는 디렉터리(프로젝트의 루트 디렉터리) //는 주석이 아니다 오류가 뜨니까 필요없으면 지워야 된다.
                /var/jenkins_home/workspace/jenkinsgogo/gradlew clean bootJar
                '''
                echo '빌드를 완료했어요!'
            }
        }
    }
}

성공하면 아래와 같이 된다.

 

8.젠킨스 파이프라인에 웹훅 트리거 걸기

그리고 고급버튼을 눌러가면서 어떻게든 Secret Token이라는 것을 찾는다. 어떤 버튼 안에 숨겨져있을 수도 있고 그렇다. Generate라는 버튼으로 생성해야 나올 수도 있다. 어쨌든 유아이는 계속 바뀌니 찾아야 된다.

 

8. 깃랩에서 웹훅 만들기

푸시를 걸고 싶은 리포지토리에서 웹훅이라는 메뉴를 찾는다 지금은 세팅스에 있었지만 후에는 어떻게 될지도 모르고 깃헙에서도 찾아야될 일이다.

 

 

채워야할건 url과 secret token인데 url은 체크하는 곳 옆에 적혀 있는데 찾아서 잘 적어주면되고 secret토큰은 앞에서 복사한걸 붙여넣으면 된다.

 

 

그후 add webhook이란 버튼을 찾고 테스트를 해보면 된다.

만약 테스트를 했을 때 젠킨스 웹페이지에서 새로운 빌드 흔적이 생기면 성공이다.

 

9. 깃랩에 프로젝트폴더 안에 도커파일 생성

도커파일은 프로젝트의 루트폴더에 만들면된다. 확장자 없이 파일이름이 Dockerfile이면 된다.

FROM openjdk:11-jdk
EXPOSE 9999
COPY build/libs/*.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

from은 만들고자 하는 컨테이너의 이미지이다. 이 컨테이너는 jar파일을 돌릴 예정이니 jdk이미지를 커스텀한 이미지여야 한다.

expose는 열어야 하는 컨테이너의 포트 번호다 이 경우는 properties에 열어놓은 해당 프로젝트의 포트번호면 된다.

copy 다음 첫번째는 복사하고자하는 대상이다. 현재위치(pwd)는 dockerfile이 존재하는 프로젝트 최상위폴더이다 ls를 하면 build폴더가 있다는 것을 알 수 있다. 이전 파이프라인 스크립트에서 빌드를 한 jar파일이 바로 build/libs에 들어있다. 이 jar를 app.jar라고 해서 복사해둔다.

entrypoint는 해당 컨테이너가 실행될때 처음 실행되는 명령어를 뜻한다 이경우는 복사된 app.jar을 실행하게 된다. 만약 jar파일이 런타임오류가 있다면 컨테이너는 실행되지 않는다.

 

10. 젠킨스 파이프라인에 이전 이미지와 컨테이너를 삭제하고
    도커파일을 바탕으로 이미지파일 만드는 스크립트 작성

파이프라인 스크립트를 또 추가한다

pipeline {
    agent any

    stages {
		stage('gitlab clone') {
            steps {
                echo '클론을 시작할게요!'
                git branch: 'master', credentialsId: 'gitlab4', url: 'https://lab.ssafy.com/siganshoyou/jenkinsgogo.git'
                echo '클론을 완료했어요!'
            }
        }
        stage('build') {
            steps {
                echo '빌드를 시작할게요!'
                sh '''
                chmod +x /var/jenkins_home/workspace/jenkinsgogo/gradlew
                /var/jenkins_home/workspace/jenkinsgogo/gradlew clean bootJar
                '''
                echo '빌드를 완료했어요!'
            }
        }
        stage('make image') {
            steps {
            	echo '이미지를 만들게요!'
                sh '''
                docker stop backend || true # 먼저 컨테이너를 지우지 않으면 <none>이라는 이미지가 남는다 이는 해당 이미지를 레퍼런스하고 있는 컨테이너가 아직 존재함에도 이미지를 먼저 지웠기 때문이다.
                docker rm backend || true
                docker rmi backend || true
                docker build -t backend . #여기서 . 은 pwd를 의미한다. 이 디렉터리에는 꼭 Dockerfile이 존재하여야 한다. 따라서 예를들어 pwd를 출력했을 때 그 디렉터이 안의 a 폴더안에 Dockerfile이 있다면 ./a 라고 해주면 된다.
                '''
                echo '이미지를 만들었어요!'
            }
        }
    }
}

jenkins 컨테이너에서 docker를 사용하지 못한다면 make image stage가 작동하지 않을 수 있다 이경우 ssh인증을 통해 직접 ec2에 접속한다.

 

sshagent(credentials: ['ec2_ssh_key']) {
    sh '''
        ssh -o StrictHostKeyChecking=no ubuntu@j8d103.p.ssafy.io "sudo docker stop $(docker ps -aq --filter ancestor=backdb)"
        ssh -o StrictHostKeyChecking=no ubuntu@j8d103.p.ssafy.io "sudo docker rm -f $(docker ps -aq --filter ancestor=backdb)"
        ssh -o StrictHostKeyChecking=no ubuntu@j8d103.p.ssafy.io "sudo docker rmi backdb"
        ssh -o StrictHostKeyChecking=no ubuntu@j8d103.p.ssafy.io "sudo docker build -t ."
    '''
                    
    
}

근데 마지막라인은 확실하지 않은게 도커파일이 있는 위치와 프로젝트의 루트주소를 확실하게 해줘야 할듯

아마 깃클론한 폴더를 ec2에서 볼륨으로 복사한뒤에 그걸 ssh를 이용해서 ec2의 도커를 통해 새 컨테이너를 dockerbuild를 통해 만들면 될듯 위코드는 완전 참고만 한고 새로 만들어야될것같다.

 

11. 젠킨스 파이프라인에 이미지파일로 컨테이너 만드는 스크립트 작성

stage('run container') {
    steps {
        sh '''
        docker run -d --name backend -p 8080:8081 backend
        '''
        echo '컨테이너를 가동시켜요!'
    }
}

이후 만들어진 이미지를 바탕으로 이걸 해준다. 만약 jenkins 컨테이너에서 docker run이 안된다면 이 코드말고 위의 ssh sh을 사용하는 방법으로 docker run을 가동시켜 주자

728x90
Jenkins, GItLab을 활용한 자동빌드 구현