[AWS] Jenkins를 활용한 Docker x SpringBoot CI/CD 구축

haeny-dev·2021년 7월 20일
20

AWS

목록 보기
6/6

📌 참고

  • AWS EC2 인스턴스 2개 활용 예정
  • 구축용 서버 : Jenkins, Git, Gradle, Docker, DockerHub, Jdk8
  • 배포용 서버 : Docker, DockerHub
  • Git Repository : Github

📌 목표

그림과 같은 구조로 CI/CD 를 구축하여 자동배포가 가능하도록 할 예정입니다.

🤵🏻‍♂️ Jenkins

➕ Jenkins 설치

1. 패키지 업데이트

$ wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
echo deb http://pkg.jenkins.io/debian-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list
$ sudo apt update

1-1. 패키지 업데이트 간 GPG ERROR 발생 시

W: GPG error: https://pkg.jenkins.io/debian-stable binary/ Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY [16자리키]
E: The repository 'https://pkg.jenkins.io/debian-stable binary/ Release' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.

해결 방안은 위의 Error 로그에서 나타난 16자리키를 가지고 아래 명령어 실행

$ sudo apt-key adv --keyserver  keyserver.ubuntu.com --recv-keys [16자리키]

이후 업데이트 재시도 해주세요.

2. Jenkins 설치 및 실행 확인

$ sudo apt install jenkins
$ sudo systemctl status jenkins

Active 상태를 확인해주세요.

● jenkins.service - LSB: Start Jenkins at boot time
     Loaded: loaded (/etc/init.d/jenkins; generated)
     Active: active (exited) since Mon 2021-07-19 07:52:33 UTC; 1min 14s ago
       Docs: man:systemd-sysv-generator(8)
      Tasks: 0 (limit: 1160)
     Memory: 0B
     CGroup: /system.slice/jenkins.service

Jul 19 07:52:32 ip-172-31-14-198 systemd[1]: Starting LSB: Start Jenkins at boot time...
Jul 19 07:52:32 ip-172-31-14-198 jenkins[7146]: Correct java version found
Jul 19 07:52:32 ip-172-31-14-198 jenkins[7146]:  * Starting Jenkins Automation Server jenkins
Jul 19 07:52:32 ip-172-31-14-198 su[7189]: (to jenkins) root on none
Jul 19 07:52:32 ip-172-31-14-198 su[7189]: pam_unix(su-l:session): session opened for user jenkins by (uid=0)
Jul 19 07:52:32 ip-172-31-14-198 su[7189]: pam_unix(su-l:session): session closed for user jenkins
Jul 19 07:52:33 ip-172-31-14-198 jenkins[7146]:    ...done.
Jul 19 07:52:33 ip-172-31-14-198 systemd[1]: Started LSB: Start Jenkins at boot time.

3. Jenkins 접속

젠킨스의 포트 번호는 따로 설정해 주지 않았다면, 8080포트로 실행이 됩니다. 그러므로 [EC2 인스턴스 URL]:8080 으로 접속하면 다음과 같은 화면이 나옵니다.

문구를 자세히 읽어보면 빨간색으로 표시된 경로로 이동하여 암호를 확인하여 입력하라는 내용의 문구이니, 당황하지 않고 해당 경로로 가서 암호를 얻어옵니다.

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

다음과 같은 화면이 나타나면 Install suggested plugins 선택하여 플러그인 설치해주시고, 계정 생성화면이 나타나면 젠킨스에서 사용할 계정을 생성해주세요.

계정 생성까지 마치면 젠킨스 메인 대시보드 페이지가 나타납니다.

➕ Jenkins x Github 연동

1. SSH 키 생성

젠킨스에서 깃헙 프로젝트로 접근하기 위해서 SSH키를 생성합니다.

$ sudo mkdir /var/lib/jenkins/.ssh
$ sudo ssh-keygen -t -rsa -f /var/lib/jenkis/.ssh/[키명칭]

2. Github Deploy Key 등록

위에서 생성해준 키 중 퍼블릭키를 깃헙에 등록해주겠습니다. 사용할 깃헙 프로젝트에서 Settings > Deploy Keys > Add deploy key 를 눌러주세요.

Title 은 구분할 수 있는 명칭으로 하고, Key 값에는 퍼블릭키 값이 들어가야 합니다. 해당 명령어를 사용하여 얻어온 퍼블릭키 값을 넣어주세요.

$ cat [키명칭].pub

3. Jenkins Credential 등록

젠킨스에서는 생성해준 키의 프라이빗 키를 크레덴셜로 등록해주어야 합니다.
Jenkins관리 > Manage Credentials > Credentials 아래 Domain이 (global) 인 화살표를 눌러 add credentials 을 눌러 크레덴셜을 추가합니다.

종류는 SSH Username with private key 로 선택해 주세요. ID 에는 해당 크레덴셜의 ID라고 생각하고 구분할 수 있도록 지어주세요. 그리고, Private Key 부분에 Enter directly를 체크해주면 프라이빗키를 입력할 수 있는 창이 나타납니다.

인스턴스로 가서 프라이빗 키를 얻어와서 입력해주도록 합니다.

$ cat [키명칭]
-----BEGIN OPENSSH PRIVATE KEY-----
...
... 이와 같은 형태의 key가 private key 입니다 ...
...
-----END OPENSSH PRIVATE KEY-----

키까지 모두 입력하고 OK를 하면 다음과 같이 등록된 것을 확인할 수 있습니다.

➕ Jenkins x 배포서버 SSH연결

1. SSH 키 생성

배포서버인 AWS EC2 인스턴스에 접근하기 위해서, PEM 형식의 키를 생성합니다.

ssh-keygen -t rsa -C "키명칭" -m PEM -P "" -f /var/lib/jenkins/.ssh/[키명칭]

2. 배포서버 PublicKey 등록

위에서 생성한 키페어 중 퍼블릭 키를 배포서버인 인스턴스의 .ssh/authorized_keys 파일에 추가해주세요.

// 구축서버
$ sudo cat /var/lib/jenkins/.ssh/[키명칭].pub

// 배포서버
$ vi .ssh/authorized_keys

3. Publish Over SSH 플러그인 설정

  • Jenkins 관리 > 플러그인 관리 > 설치가능 탭 에서 Publish Over SSH 플러그인을 검색하여 설치하고 젠킨스를 재실행하여 플러그인이 적용 될 수 있도록 해주세요.

  • Jenkins 관리 > 시스템 관리 아래 Publish Over SSH 영역의 고급 버튼을 눌러 확장하여 설정하겠습니다.

    • Path to Key 는 위에서 생성해준 private key 경로를 넣어주세요.
    • Key 는 Private key 파일안의 내용을 복사 붙여넣기 해주세요.
    • Name 는 접속할 ssh 서버의 이름을 지어주세요.
    • Hostname 는 접속할 인스턴스의 주소를 넣어주세요.
    • Username 는 접속할 유저명을 넣어주세요.

    입력을 마친 후 Test Configuration 버튼을 눌러 정상적으로 연결이 되는지 확인까지 해주세요.

🐳 Docker

➕ Docker 설치

[AWS]EC2 X Docker 를 참고해주세요.

➕ Docker Hub 설정

1. 회원가입

https://hub.docker.com 에서 회원가입 진행해주세요. 해당 절차는 도커허브 계정이 없는 분만 진행해주세요.

2. Repository 생성

Repositories 메뉴로 이동하여 Create Repository 를 눌러 구축서버에서 만들게 될 도커이미지를 저장해 놓을 저장소를 생성해주세요.

➕ Jenkins x Docker 설정

1. Docker 그룹에 젠킨스 추가

// 추가
$ sudo usermod -aG docker jenkins
$ su - jenkins

// 확인
$ id -nG
jenkins docker

2. docker.sock 권한 변경

$ sudo chmod 666 /var/run/docker.sock

3. Jenkins에서 Docker login

젠킨스에서 도커허브에 빌드 된 이미지를 푸쉬할 수 있도록 젠킨스 유저로 들어가서 도커 로그인을 해주도록 합니다. 여기서 로그인시 입력하는 아이디와 암호는 위에서 가입한 도커허브의 아이디와 암호를 입력하면 됩니다.

$ sudo su - jenkins
$ docker login

🚀 Jenkins Item

➕ Item 생성

젠킨스 메인 대시보드 화면에서 새로운 Item 버튼을 눌러 아이템을 생성해주세요. 그리고 나타나는 Item 종류 중 Freestyle project 를 선택해서 생성해주세요.

➕ Github 정보 입력

General 탭에서 가장 먼저 GitHub project 체크박스를 체크 해주세요.

그 다음, 소스 코드 관리 탭에서 Git 으로 선택해준 후 나타나는 입력 창에서,
Repository URL 은 깃헙에서 해당 레퍼지토리의 URL을 입력해주세요.
Credentials 는 위의 젠킨스 설정에서 해주었던 깃헙 관련 Credential을 선택해주세요.

➕ 빌드 정보 입력

1. Gradle build

Build 탭에서 Add build step > Execute shell 선택하여 명령어를 입력해주세요.

./gradlew clean build

2. Docker build & push

Add build step > Execute shell 선택하여 이번에는 도커 이미지를 빌드하고 도커허브에 배포하는 명령어를 입력해주세요.

docker build -t [dockerHub UserName]/[dockerHub Repository]:[version]
docker push [dockerHub UserName]/[dockerHub Repository]:[version]

3. Docker pull & run

빌드 환경 탭에서 Send files or execute commands over SSH after the build runs 를 체크해주세요.

아래 나타난 Transfers 영역에서 다 비워둔 채 Exec command 에만 배포서버에서 어떤 행동을 할지 명령어를 입력해 줍니다.

  • 도커허브에서 구축서버에서 올려놓은 도커이미지를 pull 합니다.
    docker pull [dockerHub UserName]/[dockerHub Repository]:[version]
  • 배포서버에서 도커컨테이너 이름으로 검색하여 있으면 해당 컨테이너를 정지하고 삭제합니다.
    docker ps -q --filter name=[containerName] | grep -q . && docker rm -f $(docker ps -aq --filter name=[containerName])
  • 새로 받아온 이미지를 실행해줍니다.
    docker run -d --name [containerName] -p 8085:8080 [dockerHub UserName]/[dockerHub Repository]:[version]

4. 스프링부트 프로젝트 확인

위에서 저는 스프링부트의 도커이미지를 실행할 때 도커컨테이너의 8080포트를 EC2 인스턴스의 8085포트에 연결해주었으므로, [EC2인스턴스URL]:8085 로 접근하면 확인이 가능합니다.

해당 과정까지 모두 마치면 젠킨스에서 Build Now 버튼을 통해 수동으로 배포를 할 수 있는 상태까지 되었습니다.

🖥 자동배포화

➕ Github Webhook 연동

1. 플러그인 설치

Jenkins 관리 > 플러그인 관리 > 설치 가능 탭 에서 Github Integration 검색하여 설치 후 젠킨스를 재시작해주세요.

2. Jenkins Webhook 설정

해당 Item > 구성 > 빌드 유발 탭 에서 GitHub hook trigger for GITScm polling 체크해주세요.

3. Github Webhook 추가

해당 Github Repository에서 Settings > Webhooks > add Webhook 을 눌러 웹훅을 추가해주세요.

Payload URL
아래 경로 형태로 입력해주세요.

[구축서버 인스턴스 URL]:[젠킨스 PORT]/github-webhook/

Content Type 은 application/json 으로 해주세요.

여기까지 설정하였다면, 개인 로컬 IDEA 에서 소스를 수정 후 push 까지 시행 후 젠킨스 대시보드에서 자동으로 빌드가 생성되는지 확인해주세요.

📖 REFERENCE

jenkins 설치하기 (ubuntu 20.04)
[Jenkins] Docker를 활용한 Spring boot 프로젝트 CI & CD
Docker/Jenkins를 활용한 웹서버 자동배포 & DockerImage 자동 배포
[Docker & Jenkins] 도커와 젠킨스를 활용한 Spring Boot CI/CD🥸

3개의 댓글

comment-user-thumbnail
2024년 4월 17일

유익한 글 감사합니다.
궁금한 점 여쭤보겠습니다.
docker hub는 제가 알고 있는 docker hub 가 맞나요? github 처럼 docker 로 빌드된 이미지를 공유하는 그사이트 ? https://hub.docker.com/
그렇다면 public & private 가 공존할것인데
image 들을 외부에 놓는게 기업입장에서는 괜찮은가요? github 보안때문 보통 gitlab enterprise 버전을 많이 쓰긴한데... 그렇다면
dockerhub 를 별도로 aws 환경에 내려받아서 내부 repository 를 구축해야 되는가요?

1개의 답글
comment-user-thumbnail
2024년 7월 31일

구축서버에서 만든 public key를 배포 서버에 authorized_keys 파일에 등록할 때
기존에 서버 접속 시 사용하는 키페어(pem파일) 내용 밑에 추가해주면 되나요?

답글 달기