AWS Cloud School 8기/Jenkins

90일차) 2025-05-09(Jenkins를 통한 CI/CD)

eitherwho 2025. 5. 9. 16:44

 깃허브 액션같은 경우, webhook을 하는데 큰 문제가 없었다.

# 하지만 오픈소스 CI 도구인 젠킨스의 경우, 로컬 환경(private network)에 설치하면 내가 네트워크 관리자여서 포트포워딩을 제어할 수 있는 상황이 아니라면 webhook이 불가능하다. 따라서 우리는 클라우드에 인스턴스를 생성하여 jenkins를 구성할 예정이다.

EKS가 설치된 VPC의 퍼블릭 서브넷에 Jenkins를 설치

- 인스턴스 유형은 최소 small 이상으로 해야한다.

# 젠킨스가 어떤 포트를 쓰는지에 대한 정보가 없기때문에 일단 모두 허용

root@ip-10-50-10-213:~# apt update -y
  • 레포등록을 위한 키 추가
wget -O /usr/share/keyrings/jenkins-keyring.asc \
https://pkg.jenkins.io/debian/jenkins.io-2023.key
  • 젠킨스 레포 추가
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc]" \
 https://pkg.jenkins.io/debian binary/ | sudo tee \
 /etc/apt/sources.list.d/jenkins.list > /dev/null
  • 젠킨스는 자바로 만든 앱이기 때문에 자바 설치
apt install -y fontconfig openjdk-17-jre
  • 레포 업뎃
apt-get update
  • 젠킨스 설치
apt-get install jenkins -y
root@ip-10-50-10-213:~# systemctl restart jenkins
root@ip-10-50-10-213:~# systemctl enable jenkins
  • 인스턴스의 8080포트로 접속

젠킨스는 플러그인을 통해 원하는 환경을 구성할 수 있다.

ex) 내가 만든 앱은 gradle로 빌드하고 aws에 배포할꺼니까 gradle, aws 플러그인을 설치하는식

 

# 인증관련된 정보(docker 계정정보, 깃허브계정정보, 필수한 플러그인이나 툴들 설치)

# 주로 볼곳들

 


 




 



 

# 메이븐이라는 도구를 정의

 

 

 

----

 

혹시 나중에 젠킨스 빌드를 많이 하면, 디스크 용량이 부족한 경우가 생긴다. 그럴 땐 EBS를 늘리면 된다.

 

 도커로그인 정보 등록

 

 

 

# 젠킨스홈

 

 



https://github.com/oolralra/simple_sb.git

# 이걸 fork하세요!! 간단 스프링부트앱 mvn으로 빌드. 8085번이 타겟포트

 



# 웹훅.

 

# 깃에 CI/CD스크립트를 저장.


 

 

 

# 소스코드의 브랜치과 같게.

 

 

 

 

 

 

-----------

앞으로 이 Jenkinsfile이라는 스크립트에서 우리가 해야할것들.

 

1. 소스코드에 변경사항이 생겼을때 git clone.

2. 앱빌드(maven) => target 폴더에 springbootApp.jar 파일 생성

3. target/springbootApp.jar 을 넣어서 도커 빌드.

4. 컨테이너레지스트리(도커허브)에 push

5. 깃허브레포를 소스레포에서 deploy레포로 변경후 git clone

6. deployment.yml 파일의 이미지 태그를 수정 후 push

 

------------------------

github 웹훅 환경을 구성.

 

 

 

 

# http://<본인인스턴스주소>:8080/github-webhook/

 



 

pipeline {
    agent any
   
    stages {
        stage('start') {
            steps {
                sh "echo hello jenkins!!!"
            }
            post {
                failure {
                    sh "echo failed"
                }
                success {
                    sh "echo success"
                }
            }
        }
    }
}

 

# 스테이지들-스테이지-스텝스...

# post 스텝스를 수행후 성공/실패 여부에 따라서 분기점.

 

# 레포에서 아무파일이나 생성해서 소스코드에 변화를 줬을때

 

# 새로운 젠킨스 빌드가 자동으로 수행되는지 확인한다 = webhook 성공

 

위에서 정리한 절차대로 스크립트를 짜면된다!!

 

https://vscode.dev/

 

 

 

 

 





pipeline {
    agent any

    tools {
        maven 'my_maven'
    }
    environment {
        GITNAME = 'oolralra'           
        GITEMAIL = 'oolralra@gmail.com'
        GITWEBADD = 'https://github.com/<본인>/simple_sb.git'
        GITSSHADD = 'git@github.com:<본인>/simple_sb.git'
        GITCREDENTIAL = 'git_cre'
       
        DOCKERHUB = '<본인허브>/spring'
        DOCKERHUBCREDENTIAL = 'docker_cre'
    }

    stages {
        stage('start') {
            steps {
                sh "echo hello jenkins!!!"
            }
            post {
                failure {
                    sh "echo failed"
                }
                success {
                    sh "echo success"
                }
            }
        }
    }
}

# 환경변수를 본인에 맞게 수정.

 

    stages {
        stage('Checkout Github') {
            steps {
                checkout([$class: 'GitSCM', branches: [[name: '*/main']], extensions: [],
                userRemoteConfigs: [[credentialsId: GITCREDENTIAL, url: GITWEBADD]]])

            }
            post {
                failure {
                    sh "echo clone failed"
                }
                success {
                    sh "echo clone success"
                }
            }
        }

        stage('springboot app build') {
            steps {
                sh "mvn clean package"
            }

            post {
                failure {
                    sh "echo mvn packaging fail"
                }
                success {
                    sh "echo mvn packaging success"
                }
            }
        }
        stage('docker image build') {
            steps {
                sh "docker build -t ${DOCKERHUB}:${currentBuild.number} ."
                sh "docker build -t ${DOCKERHUB}:latest ."
                // currentBuild.number 젠킨스가 제공하는 빌드넘버 변수
                // oolralra/fast:<빌드넘버> 와 같은 이미지가 만들어질 예정.
             
            }
            post {
                failure {
                    sh "echo image build failed"
                }
                success {
                    sh "echo image build success"
                }
            }
        }
        stage('docker image push') {
            steps {
                withDockerRegistry(credentialsId: DOCKERHUBCREDENTIAL, url: '') {
                    sh "docker push ${DOCKERHUB}:${currentBuild.number}"
                    sh "docker push ${DOCKERHUB}:latest"
                }
            }
            post {
                failure {
                    sh "docker image rm -f ${DOCKERHUB}:${currentBuild.number}"
                    sh "docker image rm -f ${DOCKERHUB}:latest"
                    sh "echo push failed"
                    // 성공하든 실패하든 로컬에 있는 도커이미지는 삭제
                }
                success {
                    sh "docker image rm -f ${DOCKERHUB}:${currentBuild.number}"
                    sh "docker image rm -f ${DOCKERHUB}:latest"
                    sh "echo push success"
                    // 성공하든 실패하든 로컬에 있는 도커이미지는 삭제
                }
            }
        }
        stage('EKS manifest file update') {
            steps {
                git credentialsId: GITCREDENTIAL, url: GITSSHADD, branch: 'main'
                sh "git config --global user.email ${GITEMAIL}"
                sh "git config --global user.name ${GITNAME}"
                sh "sed -i 's@${DOCKERHUB}:.*@${DOCKERHUB}:${currentBuild.number}@g' fast.yml"

                sh "git add ."
                sh "git branch -M main"
                sh "git commit -m 'fixed tag ${currentBuild.number}'"
                sh "git remote remove origin"
                sh "git remote add origin ${GITSSHADD}"
                sh "git push origin main"
            }
            post {
                failure {
                    sh "echo manifest update failed"
                }
                success {
                    sh "echo manifest update success"
                }
            }
        }
     

    }

# 기존 stages 제거후 복붙.

 

# 혹시모르니 기존이 빌드되어 나온 jar파일은 삭제.

 

# 여기까지 성공했는지 확인.


# 인스턴스에 docker가 설치 안되어있음.

 

인스턴스에서 

 

curl -fsSL https://get.docker.com -o get-docker.sh

sh get-docker.sh

 

# jenkins는 명령을 치는 주체가 jenkins 라는 리눅스 사용자.

# 따라서 jenkins라는 리눅스 사용자에게 권한을 부여.

 

root@ip-10-50-10-213:~# usermod -aG docker jenkins

# jenkins라는 사용자를 docker라는 그룹에 add해주는 명령.

 

root@ip-10-50-10-213:~# systemctl restart jenkins

# 젠킨스 재시작후 다시 빌드.

 

 

# 우리는 github와 ssh 통신이 실패했다.

# Jenkinsfile을 수정

ssh 통신을 위한 인증

  1. id/pass 방식
  2. public key 방식(키페어)
  • 클라이언트 = private key = 젠킨스
  • 서버 = public key = 깃허브

인스턴스에서 키페어 생성

  • 관리자 권한을 취득 후 jenkins라는 사용자로 변경

  • 기본값으로 키페어 생성
ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa -N '' -q

 

- 깃허브에 퍼블릭키 등록



 

jenkins@ip-10-50-10-213:~$ cat ~/.ssh/id_rsa.pub

# 꼭 처음부터 끝까지

 

- 젠킨스에 프라이빗키 credential 생성

  • 프라이빗키
jenkins@ip-10-50-10-213:~$ cat ~/.ssh/id_rsa

# 프라이빗키값 전체

 

  • 내 known_hosts에 등록시키기 위해 깃허브서버에 ssh 접속을 1회 실시
jenkins@ip-10-50-10-213:~$ ssh git@github.com

# 중간에 fail이 떠도 좋다.

 

# 수정 확인 가능

실습)

여러분들이 argoCD 설치해서 앱배포가 잘 되게끔 해보세요!!

딸깍 해서 스프링부트앱에 "프로젝트 조 알려주세요!"라는 내용이 뜨는 사이트주소를 저한테 알려주시면 됩니다!"