사이드 프로젝트를 작업을 진행하며, 백과 프론트 서버를 분리해서 운영을 하기로 결정을 하였고,
OAuth2 구현을 위해 먼저 작업을 한 파일을 배포를 해야하는 상황이 되었다.
나는 백엔드를 담당하고있었고, 내가 최종적으로 기획하고 싶은 백엔드의 인프라는 다음과 같았다.
개발환경
- 서버 : EC2 (ubuntu 22.04 LTS , SpringBoot 2.7.11)
- DB : AWS RDS(MySQL 8.0.28)
- 언어 : Java 11
- JDBC : Spring data JPA , QueryDsl
- Build : Gradle
인프라
- EC2 인스턴스를 총 3개를 사용하여 Jenkins, NginX, 운영서버로 두고,
- Github에 Push를 하게되면 Jenkins가 자동으로 Gradle로 빌드를 하여 jar file을 생성하여 dockerHub에 이미지를 등록한다.
- 빌드가 끝나면 dockerhub에서 운영서버와 Nginx서버의 docker로 이미지를 pull하여 도커 컨테이너를 실행시킨다.
로드밸런싱 로직
- Nginx는 사용자가 들어오면 로드밸런싱을하여 사용자에게 포트를 지정하여 해당 컨테이너의 서버로 요청을 전달한다.
- 사실, 로드밸런싱을 하며 EC2내에 도커 컨테이너를 분리하여 저렇게 포트만 바꿔두는건 의미가 없지만(저 서버가 죽으면 다 뻗으니까..)
- 사이드 프로젝트이니 도커 컨테이너를 각각 개별 서버로 가정하고 대용량 트래픽을 위해 로드밸런싱 하는 로직을 사용 했다고 가정을 했다.
현 상황
- 우선 현재 상황은 개발을 마치지 않았고, 프론트 서버와 같이 작업을 하기 위해 배포를 하는것이기 때문에 간단히 구성을 하였다.
- 배포 서버와 운영 서버 둘 다 도커를 사용하지 않고 EC2컨테이너 2개로 Jenkins 서버와 배포 서버를 분리하였다.
- 최초에는 EC2 프리티어가 인스턴스를 1개만 지원을 하기 때문에 Docker위에 컨테이너를 활용하여 Jenkins와 배포 서버를 구현하여 로직만 구현하려고 하였으나, EC2 프리티어는 용량이 매우 적어 Jenkins 하나를 돌리는데도 먹통이되었고, swap 메모리를 이용하여 Jenkins를 겨우 돌릴 수 있었기 때문에, EC2를 분리하여 1개는 Jenkins용, 1개는 운영서버용으로 사용하였다
- Github push를 하면 Jenkins 파이프라인에 의해 Build를 자동적으로 진행하고, 배포까지 진행하는 프로세스를 계획하고 진행하였다.
환경 설정
- 호스트명 변경 : 나는 개인적으로 블로그를 따라하다보니 지금 하고있는 작업이 어느 서버에서 해야하는 작업인지 헷갈렸기 때문에 호스트명을 먼저 변경하였다.
Jenkins용 인스턴스에 ssh 접속을 하여 jenkins라고 호스트명을 변경시켜주었고,
$ sudo hostnamectl set-hostname jenkins
SpringBoot 서버용 인스턴스에 ssh 접속을 하여 respal(사이드프로젝트명)-live 라고 호스트명을 변경시켜주었다.
$ sudo hostnamectl set-hostname respal-live
Swap 메모리 설정 : 이후 두 인스턴스 모두 프리티어 인스턴스이므로, 앞서 말했듯 메모리가 부족해지기 때문에 두 인스턴스 모두 swap 메모리를 설정하였다.
1. Swap 파일 생성
$ sudo dd if=/dev/zero of=/swapfile bs=128M count=16
- 명령에서 bs는 블록 크기이고 count는 블록 수이다.
- dd 명령을 사용하여 root 파일 시스템에 swap file을 생성한다.
- 일반적으로 2GB를 증설시키며, 이 명령어도 동일하게 작동한다 (128MB x 16 = 2048MB)
2. 생성된 Swap 파일 권한 부여
$ sudo chmod 600 /swapfile
3. Linux 스왑 영역 설정
sudo mkswap /swapfile
4. 스왑 공간에 스왑 파일을 추가하여 사용할 수 있도록 한다.
sudo swapon /swapfile
5. 작업 성공 확인
sudo swapon -s
6. 부팅 시 Swap 파일 활성화
$ sudo vi /etc/fstab
마지막 줄에 아래 내용을 추가한다.
/swapfile swap swap defaults 0 0
JDK 설치
우선 Jenkins Java 기반 툴이고, 배포 서버 또한 Spring 서버이기 때문에 두 인스턴스 모두 JDK를 설치해준다.
$ sudo apt-get update
$ sudo apt-get upgrade
# JAVA11 설치
$ sudo apt-get install openjdk-11-jdk
위 명령어들을 순서대로 입력해주고
$ java -version
자바 버전을 확인해준다.
이후 설치가 잘 되었다면, Java 환경 변수를 설정해준다.
$ sudo vi /etc/environment
vi 편집기로 environment를 열어 i를 눌러 수정 모드로 진입을 해주고
$JAVA_HOME="/usr/lib/jvm/java-11-openjdk-arm64"
맨 아래에 다음과같이 작성을 해주고 esc 버튼을 눌러 수정모드 종료 후 :wq!를 하여 저장을 하고 나간다.
Jenkins 설치
우선 GPG라는 GNU에서 쓰이는 암호화 key를 받아 준다.
$ wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
이후 Jenkins 레포지토리를 시스템에 추가하고,
$ sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
Jenkins 레포지토리를 사용하여 Jenkins의 최신 버전을 설치한다.
$ sudo apt update
$ sudo apt install jenkins
이렇게하면 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 9B7D32F2D50582E6"
해당 키값을 복사하여 키서버에서 가져와 실행시킨다.
$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9B7D32F2D50582E6
이러면 자동으로 Jenkins가 실행이 되는데, 젠킨스는 사용자가 포트 지정을 따로 하지 않을경우 자동적으로 8080 포트를 잡기 때문에
인스턴스의 보안그룹에서 8080포트를 열어주도록 한다.
Jenkins 세팅
이제 젠킨스가 실행되었다면, 브라우저 주소창에 인스턴스의 Public 주소 :8080 혹은 할당한 탄력적 IP 주소 :8080을 입력하여 Jenkins에 접속하도록 한다.
(ex : ec2.asdfasdf.amazonaws.com:8080) << 인스턴스 public주소:8080
해당 화면은 나는 이미 설치가 진행되었기 때문에 다른 블로그의 사진을 가져왔다.
해당 password창에 암호를 입력해야하는데, jenkins용 서버에서
$ sudo cat /var/lib/jenkins/secrets/initialAdminPassword
위 명령어를 입력하여 암호를 가져와서 붙여넣기를 한다.
이후 플러그인 설치를 제안해주는 플러그인 셋으로 클릭해주면
위와같이 자동으로 플러그인이 설치가 된다. (좀 오래걸렸던것 같다.)
플러그인 설치가 완료되면 어드민 설정 페이지가 나오는데
위 어드민 설정은 젠킨스 페이지를 재접속 할 때 로그인 정보로 쓰이기 때문에 설정값을 기억해 두도록 하자
이후, Jenkins 인스턴스 URL을 설정하라는 메세지가 나오는데, 해당 필드는 자동으로 채워지니 채워진 값으로 저장하고 설정을 끝내자.
설정을 완료하면 Jenkins 설치가 완료되었다.
다음글에선 설치한 Jenkins와 배포 서버와 설정을 하고, Github와의 연동으로 프로젝트를 Push하는 경우, Jenkins가 프로젝트를 가져와서 빌드 후 파이프라인을 통해 자동 배포까지 진행되는 작업을 작성하도록 하겠다!
java 설정 참고 블로그 : https://davelogs.tistory.com/71
jenkins 설정 참고 블로그 : https://jjeongil.tistory.com/2018
'💻Spring' 카테고리의 다른 글
OAuth, 일반 이메일 회원가입시 중복관련 Trouble Shooting (0) | 2023.06.05 |
---|---|
Jenkins 파이프라인을 이용한 SpringBoot 자동배포 2 (젠킨스 파이프라인 생성 및 깃허브 액션 연결) (0) | 2023.05.20 |
Github에 프로젝트 민감정보 숨기기 (application.yml) (0) | 2023.04.26 |
@ModelAttribute , @RequestParam 정리 (0) | 2023.04.26 |
Spring Security Jwt - 예외처리 커스터마이징 (0) | 2023.04.03 |