기타 개발 관련

[CI/CD] Jenkins 을 통한 CI/CD 파이프라인 구축 with AWS EC2, Java Spring, Docker

izongg 2025. 4. 9. 13:25
반응형

CI/CD란

CI , Continuous Integration (지속적 통합) : 각각의 개발자의 코드를 지속적으로 통합하고, 자동으로 빌드와 테스트를 실행하여 코드 품질을 유지하는 과정

CD, Continuous Deployment (지속적 배포) : 테스트를 통과한 코드를 자동으로 배포(또는 배포 준비)하여 신속하고 안정적으로 서비스에 반영하는 과정


이전에 Github액션을 통해 CI/CD 파이프라인을 구축해보았다.

https://izongg.tistory.com/32

 

[CI/CD] Github Action을 통한 CI/CD 파이프라인 구축 with AWS EC2, Java Spring, Docker

CI/CD란CI , Continuous Integration (지속적 통합) : 각각의 개발자의 코드를 지속적으로 통합하고, 자동으로 빌드와 테스트를 실행하여 코드 품질을 유지하는 과정CD, Continuous Deployment (지속적 배포) : 테

izongg.tistory.com

 

현재 aws ec2 프리티어를 사용중이라 메모리공간 이슈로 인해 jenkins가 아닌 Github Action을 사용하여 CI/CD를 구축했었다.

실제 이 프로젝트에서는 Github Action을 사용할거지만, jenkins로도 구축을 해보고싶어서 직접 구현해보았다.

 

아래 내용들은 미리 준비되어있다고 가정

1. 프로젝트 구현

2. aws ec2 환경 준비 with Docker설치

3. 프로젝트 Dockerfiles 작성

 

참고로 Docker을 사용하여 Java Spring 프로젝트를 AWS EC2서버에 배포하는 과정은 아래 글을 참고하자

https://izongg.tistory.com/31

 

[Docker] Docker을 사용하여 Java Spring 프로젝트를 AWS EC2서버에 배포하기

Docker을 사용하여 Java Spring 프로젝트를 AWS EC2서버에 배포하는 과정입니다. 아래 내용들은 미리 준비되어있다고 가정1. 프로젝트 구현2. aws ec2 인스턴스 생성3. ssh 접속 가능4. 로컬 Docker 설치 및 Do

izongg.tistory.com

자동화 할 프로세스  소개

우리가 CI/CD를 사용하지 않는다면 다음과 같은 과정을 손수 진행해야한다.

1. 수정된 프로젝트에서 Docker이미지 생성 후 Docker Hub로 Push

2. EC2 SSH 환경 접근 후, 수정된 Docker이미지를 Pull

3. 수정된 이미지 컨테이너 실행

 

이제 Github main브랜치에 push만 되면, 위 과정이 자동으로 진행되도록 구축해보겠다.


AWS EC2 프리티어 swap을 통한 메모리 확보

터미널에서 ssh를 통해 ec2 인스턴스에 접속 후 아래 명령어들을 입력한다.

 

1. Swap파일 생성

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

2. Swap 파일 권한 부여

sudo chmod 600 /swapfile

3. 리눅스 Swap 영역 설정

sudo mkswap /swapfile

4. Swap 공간에 Swap 파일 설정

sudo swapon /swapfile

5. 부팅 시 Swap 파일 활성화 설정 

sudo vi /etc/fstab

아래 텍스트를 젤 아래 줄에 추가하고 :wq 를 입력하여 저장한다.

/swapfile swap swap defaults 0 0

EC2 환경 세팅

jenkins 설치

https://www.jenkins.io/doc/book/installing/linux/

 

Linux

Jenkins – an open source automation server which enables developers around the world to reliably build, test, and deploy their software

www.jenkins.io

여기서 ec2 인스턴스 리눅스 배포판에 따라 LTS 버전을 설치한다.

wget이 없다면 

sudo yum install wget 
또는
sudo apt-get install wget

 

설치 후 

sudo systemctl start jenkins
sudo systemctl start jenkins

 

한 후 실행되었는지 확인

sudo systemctl status jenkins

 

Java 설치

sudo yum install java-17-openjdk-devel

본인 프로젝트에 맞는 버전을 설치한다.

which javac

 

설치 후 위 명령어를 입력하여 javac도 설치된지 확인 후, 없다면 포함된 버전으로 설치한다.


Jenkins 접속

따로 아이피를 설정하지 않았으면 현재 

[EC2 인스턴스 URL]:8080 로 접속하면 아래 화면이 나온다.

 

비밀번호는 ssh 에서 

sudo cat /var/lib/jenkins/secrets/initialAdminPassword

하면 비밀번호가 나온다. 붙여넣는다.

 

그리고 Install suggested plugins 로 자동으로 필요한 플러그인을 다운받는다.

 

본인이 젠킨스 접속할 때 로그인 할 정보를 입력한다.

이제 대시보드에 접속 되었을 것 이다.


Github - Jenkins 연동

github 와 Jenkins를 연결시켜주기 위한 키를 생성한다.

sudo mkdir /var/lib/jenkins/.ssh
sudo ssh-keygen -t rsa -f /var/lib/jenkins/.ssh/jenkins

 

생성된 public키를 

sudo cat /var/lib/jenkins/.ssh/jenkins.pub

 

Github 프로젝트 레포지토리 -> Settings -> Deploy keys -> Add deploy key 
에 추가해준다

 

이번엔 Jenkins에 아까 만든 키의 private 키를 넣어준다.

sudo cat /var/lib/jenkins/.ssh/jenkins

해서 

 

-----BEGIN OPENSSH PRIVATE KEY-----
..
..
..
..
-----END OPENSSH PRIVATE KEY-----

아래 위 영어를 포함한 키를 복사한다.

 

Jenkins 관리 -> Credentials -> Domain에 (global) 클릭 -> Add Credentials

 

아래처럼 입력 후 생성

 


SSH EC2 - Jenkins 연동

ssh ec2와 jenkins를 연동할 키를 생성한다. (izongg 부분에는 본인 아무거나 넣어도 된다.)

sudo chown -R ec2-user:ec2-user /var/lib/jenkins/.ssh
sudo chmod 700 /var/lib/jenkins/.ssh
ssh-keygen -t rsa -C izongg -m PEM -P "" -f /var/lib/jenkins/.ssh/izongg

 

여기서 생성한 키의 public 키를 ec2에 넣는다

sudo cat /var/lib/jenkins/.ssh/izongg.pub

여기서 나온 키를

vi .ssh/authorized_keys

여기 제일 아래줄에 추가한다. ( i로 입력하고, esc 후 :wq로 저장)

 

Jenkins에서 

Jenkins 관리 -> Plugins -> Available Plugins

에서 Publish Over SSH 설치 후 jenkins 재실행

 

 

이후 jenkins 관리 -> System 에 들어가면 제일 아래에 Publish over SSH 부분이 있다.

 

Key 에는 금방 위에서 생성한 키의 Private키를 넣는다.

sudo cat /var/lib/jenkins/.ssh/izongg.pub

 

그리고 아래 SSH Servers 추가를 누른다.

 

Name : jenkins 접속 할 유저이름 정하기

Hostname : ec2 호스트 (퍼블릭 IPv4 주소)

Username : ec2 유저 네임 (프리티어면 대부분 ec2-user)

 

우측하단에 Test Configuration 을 누르면 왼쪽에 Success 가 나온다. 

Save 누른다.


Docker - Jenkins 연동

ec2에 Docker 설치

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

 

Install

Learn how to choose the best method for you to install Docker Engine. This client-server application is available on Linux, Mac, Windows, and as a static binary.

docs.docker.com

본인에게 맞는 플랫폼으로 설치

 

Jenkins가 sudo 명령어를 비밀번호 없이 실행할 수 있게 해주는 설정 (자동화 목적)

sudo visudo

에서 

jenkins ALL=(ALL) NOPASSWD: ALL

를 아무곳에 추가해준 후 :wq 저장 (이 부분은 보안을 위해 추후 보완 필요)

 

 

jenkins 계정을 docker그룹에 추가

sudo usermod -aG docker jenkins

이후

sudo -u jenkins -s

 

docker login

Jenkins Item 설정

먼저 ec2 인스턴스에 git을 설치한다.

sudo yum install git

 

 

그리고 jenkins에서 Item을 생성한다.

좌측 새로운Item 클릭

 

Item name 프로젝트 이름으로 입력 후 Freestyle project 선택 후 OK

 

그리고 구성->General 으로가면 소스코드 관리에서 Github project를 체크한다.

 

그리고 아래에 Git을 체크하면 아래에 입력창이 나온다.

Repository URL: 깃허브 클론할 때 사용하는 url , ex) https://github.com/izongg0/[project_name].git 

 

Credentials은 이미 하나가 있을텐데, 이거는 선택하면 Failed to connect to repository 에러가 나온다.

 

다음 과정을 거쳐서 Github 개인 엑세스 토큰을 만들고 등록시켜준다.

  1. GitHub 계정에 로그인
  2. 우측 상단의 프로필 사진을 클릭하고, Settings 선택.
  3. 좌측 사이드바 가장 아래에서 Developer settings 를 클릭
  4. 좌측 사이드바에서  Personal access tokens > Tokens (classic)로 이동
  5. Generate new token (classic) 버튼 클릭
  6. 토큰의 설명을 입력하고, 만료 기간을 설정. (필요에 따라 'No expiration'을 선택할 수 있지만, 보안을 위해 적절한 만료 기간을 설정하는 것이 좋다.)
  7. 토큰에 부여할 권한 선택. Jenkins에서 저장소에 접근하려면 repo 범위 선택
  8. Generate token 버튼을 클릭하여 토큰을생성
  9.  이 토큰은 이후에 다시 확인할 수 없으므로 보관

jenkins에 credential 등록

  1. Jenkins 대시보드에서Jenkins 관리 클릭
  2. Credentials> System > Global credentials (unrestricted)로 클릭
  3. Add Credentials 클릭
  4. 다음과 같이 입력
    • Kind: "Username with password"
    • Username: GitHub 사용자 이름
    • Password: 앞서 생성한 개인 액세스 토큰(PAT)
    • ID: (선택 사항) 이 자격 증명의 식별자
    • Description: (선택 사항) 자격 증명에 대한 설명
  5. OK 클릭

그리고 다시 여기로 돌아오면 Credentials 에 Git닉네임/***** 이 추가되어있고, 선택하면 에러가 사라진다.

 

그리고 아래에 Branch Specifier은 빌드할 브랜치를 입력한다.


이제 실행할 명령어를 입력한다.

 

아래에 Build Steps가 있다.

Add build step -> Execute shell 하면 Command창이 나온다.

여기선 프로젝트 이미지를 만들고, docker hub로 푸쉬하는 명령어를 작성하였다.

 

여기가 CI/CD 중 CI 부분이라고 할 수 있다.

docker build --build-arg DEPENDENCY=build/dependency --platform linux/amd64 -t izongg/odin_stamp .
docker push izongg/odin_stamp

 

다음,

Add build step -> Send files or execute commands over SSH after the build runs 

여기는 ssh ec2환경에서 docker hub의 최신 image를 pull받고, 컨테이너를 실행한다.

나머지는 빈칸으로 두고, Exec command만 입력하면 된다.

sudo systemctl start docker
sudo docker pull izongg/odin_stamp
docker stop $(docker ps -aq) # 기존 컨테이너 중지
sudo docker run -d -p 8080:8080 --platform linux/amd64 izongg/odin_stamp

여기가 CD 부분이라고 할 수 있다.

각각 CI, CD에서의 명령어는 각자의 프로젝트 환경에 맞게 적절히 수정하여 사용한다.

 

이제 jenkins의 '지금 빌드'를 통해 수동으로 배포를 할 수 있는 상태가 되었다.

 

빌드 후

permission denied while trying to connect to the Docker daemon socket

에러가 나온다면 ec2 인스턴스에서 아래 명령어를 입력하여 권한을 풀어준다.

sudo chmod 666 /var/run/docker.sock

 

Github Push-Merge 를 통한 자동 배포

Dashboard -> Jenkins 관리 -> Plugins -> Available plugins에서 Github Integration 를 설치한다.

 

 

itrem -> Configuration -> Triggers -> GitHub hook trigger for GITScm polling 체크

 

 

Github 프로젝트 Repository에서 Settings -> Webhooks -> add Webhook

Payload URL: [퍼블릭 IPv4 주소]:[젠킨스 PORT - 8080]/github-webhook/

Content type : application/json

 

 

이제 github main 브랜치에 수정사항을 push 한 후, jenkins에서 자동으로 배포가 되고 업데이트가 되는 것을  확인한다.

반응형